1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
99 ;; Other random patterns
108 UNSPEC_LD_MPIC ; load_macho_picbase
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_CALL_NEEDS_VZEROUPPER
114 ;; For SSE/MMX support:
132 UNSPEC_MS_TO_SYSV_CALL
134 ;; Generic math support
136 UNSPEC_IEEE_MIN ; not commutative
137 UNSPEC_IEEE_MAX ; not commutative
139 ;; x87 Floating point
155 UNSPEC_FRNDINT_MASK_PM
159 ;; x87 Double output FP
191 ;; For SSE4.1 support
201 ;; For SSE4.2 support
208 UNSPEC_XOP_UNSIGNED_CMP
219 UNSPEC_AESKEYGENASSIST
221 ;; For PCLMUL support
237 ;; For RDRAND support
241 (define_c_enum "unspecv" [
244 UNSPECV_PROBE_STACK_RANGE
264 UNSPECV_LLWP_INTRINSIC
265 UNSPECV_SLWP_INTRINSIC
266 UNSPECV_LWPVAL_INTRINSIC
267 UNSPECV_LWPINS_INTRINSIC
272 UNSPECV_SPLIT_STACK_RETURN
275 ;; Constants to represent rounding modes in the ROUND instruction
284 ;; Constants to represent pcomtrue/pcomfalse variants
294 ;; Constants used in the XOP pperm instruction
296 [(PPERM_SRC 0x00) /* copy source */
297 (PPERM_INVERT 0x20) /* invert source */
298 (PPERM_REVERSE 0x40) /* bit reverse source */
299 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
300 (PPERM_ZERO 0x80) /* all 0's */
301 (PPERM_ONES 0xa0) /* all 1's */
302 (PPERM_SIGN 0xc0) /* propagate sign bit */
303 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
304 (PPERM_SRC1 0x00) /* use first source byte */
305 (PPERM_SRC2 0x10) /* use second source byte */
308 ;; Registers by name.
361 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
364 ;; In C guard expressions, put expressions which may be compile-time
365 ;; constants first. This allows for better optimization. For
366 ;; example, write "TARGET_64BIT && reload_completed", not
367 ;; "reload_completed && TARGET_64BIT".
371 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
372 atom,generic64,amdfam10,bdver1,bdver2,btver1"
373 (const (symbol_ref "ix86_schedule")))
375 ;; A basic instruction type. Refinements due to arguments to be
376 ;; provided in other attributes.
379 alu,alu1,negnot,imov,imovx,lea,
380 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
381 icmp,test,ibr,setcc,icmov,
382 push,pop,call,callv,leave,
384 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
385 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
387 ssemuladd,sse4arg,lwp,
388 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
389 (const_string "other"))
391 ;; Main data type used by the insn
393 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
394 (const_string "unknown"))
396 ;; The CPU unit operations uses.
397 (define_attr "unit" "integer,i387,sse,mmx,unknown"
398 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
399 (const_string "i387")
400 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
401 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
402 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
404 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
406 (eq_attr "type" "other")
407 (const_string "unknown")]
408 (const_string "integer")))
410 ;; The (bounding maximum) length of an instruction immediate.
411 (define_attr "length_immediate" ""
412 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
415 (eq_attr "unit" "i387,sse,mmx")
417 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
419 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
420 (eq_attr "type" "imov,test")
421 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
422 (eq_attr "type" "call")
423 (if_then_else (match_operand 0 "constant_call_address_operand" "")
426 (eq_attr "type" "callv")
427 (if_then_else (match_operand 1 "constant_call_address_operand" "")
430 ;; We don't know the size before shorten_branches. Expect
431 ;; the instruction to fit for better scheduling.
432 (eq_attr "type" "ibr")
435 (symbol_ref "/* Update immediate_length and other attributes! */
436 gcc_unreachable (),1")))
438 ;; The (bounding maximum) length of an instruction address.
439 (define_attr "length_address" ""
440 (cond [(eq_attr "type" "str,other,multi,fxch")
442 (and (eq_attr "type" "call")
443 (match_operand 0 "constant_call_address_operand" ""))
445 (and (eq_attr "type" "callv")
446 (match_operand 1 "constant_call_address_operand" ""))
449 (symbol_ref "ix86_attr_length_address_default (insn)")))
451 ;; Set when length prefix is used.
452 (define_attr "prefix_data16" ""
453 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
455 (eq_attr "mode" "HI")
457 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
462 ;; Set when string REP prefix is used.
463 (define_attr "prefix_rep" ""
464 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
466 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
471 ;; Set when 0f opcode prefix is used.
472 (define_attr "prefix_0f" ""
474 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
475 (eq_attr "unit" "sse,mmx"))
479 ;; Set when REX opcode prefix is used.
480 (define_attr "prefix_rex" ""
481 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
483 (and (eq_attr "mode" "DI")
484 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
485 (eq_attr "unit" "!mmx")))
487 (and (eq_attr "mode" "QI")
488 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
491 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
494 (and (eq_attr "type" "imovx")
495 (match_operand:QI 1 "ext_QIreg_operand" ""))
500 ;; There are also additional prefixes in 3DNOW, SSSE3.
501 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
502 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
503 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
504 (define_attr "prefix_extra" ""
505 (cond [(eq_attr "type" "ssemuladd,sse4arg")
507 (eq_attr "type" "sseiadd1,ssecvt1")
512 ;; Prefix used: original, VEX or maybe VEX.
513 (define_attr "prefix" "orig,vex,maybe_vex"
514 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
516 (const_string "orig")))
518 ;; VEX W bit is used.
519 (define_attr "prefix_vex_w" "" (const_int 0))
521 ;; The length of VEX prefix
522 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
523 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
524 ;; still prefix_0f 1, with prefix_extra 1.
525 (define_attr "length_vex" ""
526 (if_then_else (and (eq_attr "prefix_0f" "1")
527 (eq_attr "prefix_extra" "0"))
528 (if_then_else (eq_attr "prefix_vex_w" "1")
529 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
530 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
531 (if_then_else (eq_attr "prefix_vex_w" "1")
532 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
533 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
535 ;; Set when modrm byte is used.
536 (define_attr "modrm" ""
537 (cond [(eq_attr "type" "str,leave")
539 (eq_attr "unit" "i387")
541 (and (eq_attr "type" "incdec")
542 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
543 (ior (match_operand:SI 1 "register_operand" "")
544 (match_operand:HI 1 "register_operand" ""))))
546 (and (eq_attr "type" "push")
547 (not (match_operand 1 "memory_operand" "")))
549 (and (eq_attr "type" "pop")
550 (not (match_operand 0 "memory_operand" "")))
552 (and (eq_attr "type" "imov")
553 (and (not (eq_attr "mode" "DI"))
554 (ior (and (match_operand 0 "register_operand" "")
555 (match_operand 1 "immediate_operand" ""))
556 (ior (and (match_operand 0 "ax_reg_operand" "")
557 (match_operand 1 "memory_displacement_only_operand" ""))
558 (and (match_operand 0 "memory_displacement_only_operand" "")
559 (match_operand 1 "ax_reg_operand" ""))))))
561 (and (eq_attr "type" "call")
562 (match_operand 0 "constant_call_address_operand" ""))
564 (and (eq_attr "type" "callv")
565 (match_operand 1 "constant_call_address_operand" ""))
567 (and (eq_attr "type" "alu,alu1,icmp,test")
568 (match_operand 0 "ax_reg_operand" ""))
569 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
573 ;; The (bounding maximum) length of an instruction in bytes.
574 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
575 ;; Later we may want to split them and compute proper length as for
577 (define_attr "length" ""
578 (cond [(eq_attr "type" "other,multi,fistp,frndint")
580 (eq_attr "type" "fcmp")
582 (eq_attr "unit" "i387")
584 (plus (attr "prefix_data16")
585 (attr "length_address")))
586 (ior (eq_attr "prefix" "vex")
587 (and (eq_attr "prefix" "maybe_vex")
588 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
589 (plus (attr "length_vex")
590 (plus (attr "length_immediate")
592 (attr "length_address"))))]
593 (plus (plus (attr "modrm")
594 (plus (attr "prefix_0f")
595 (plus (attr "prefix_rex")
596 (plus (attr "prefix_extra")
598 (plus (attr "prefix_rep")
599 (plus (attr "prefix_data16")
600 (plus (attr "length_immediate")
601 (attr "length_address")))))))
603 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
604 ;; `store' if there is a simple memory reference therein, or `unknown'
605 ;; if the instruction is complex.
607 (define_attr "memory" "none,load,store,both,unknown"
608 (cond [(eq_attr "type" "other,multi,str,lwp")
609 (const_string "unknown")
610 (eq_attr "type" "lea,fcmov,fpspc")
611 (const_string "none")
612 (eq_attr "type" "fistp,leave")
613 (const_string "both")
614 (eq_attr "type" "frndint")
615 (const_string "load")
616 (eq_attr "type" "push")
617 (if_then_else (match_operand 1 "memory_operand" "")
618 (const_string "both")
619 (const_string "store"))
620 (eq_attr "type" "pop")
621 (if_then_else (match_operand 0 "memory_operand" "")
622 (const_string "both")
623 (const_string "load"))
624 (eq_attr "type" "setcc")
625 (if_then_else (match_operand 0 "memory_operand" "")
626 (const_string "store")
627 (const_string "none"))
628 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
629 (if_then_else (ior (match_operand 0 "memory_operand" "")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "load")
632 (const_string "none"))
633 (eq_attr "type" "ibr")
634 (if_then_else (match_operand 0 "memory_operand" "")
635 (const_string "load")
636 (const_string "none"))
637 (eq_attr "type" "call")
638 (if_then_else (match_operand 0 "constant_call_address_operand" "")
639 (const_string "none")
640 (const_string "load"))
641 (eq_attr "type" "callv")
642 (if_then_else (match_operand 1 "constant_call_address_operand" "")
643 (const_string "none")
644 (const_string "load"))
645 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
646 (match_operand 1 "memory_operand" ""))
647 (const_string "both")
648 (and (match_operand 0 "memory_operand" "")
649 (match_operand 1 "memory_operand" ""))
650 (const_string "both")
651 (match_operand 0 "memory_operand" "")
652 (const_string "store")
653 (match_operand 1 "memory_operand" "")
654 (const_string "load")
656 "!alu1,negnot,ishift1,
657 imov,imovx,icmp,test,bitmanip,
659 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
660 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
661 (match_operand 2 "memory_operand" ""))
662 (const_string "load")
663 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
664 (match_operand 3 "memory_operand" ""))
665 (const_string "load")
667 (const_string "none")))
669 ;; Indicates if an instruction has both an immediate and a displacement.
671 (define_attr "imm_disp" "false,true,unknown"
672 (cond [(eq_attr "type" "other,multi")
673 (const_string "unknown")
674 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
675 (and (match_operand 0 "memory_displacement_operand" "")
676 (match_operand 1 "immediate_operand" "")))
677 (const_string "true")
678 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
679 (and (match_operand 0 "memory_displacement_operand" "")
680 (match_operand 2 "immediate_operand" "")))
681 (const_string "true")
683 (const_string "false")))
685 ;; Indicates if an FP operation has an integer source.
687 (define_attr "fp_int_src" "false,true"
688 (const_string "false"))
690 ;; Defines rounding mode of an FP operation.
692 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
693 (const_string "any"))
695 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
696 (define_attr "use_carry" "0,1" (const_string "0"))
698 ;; Define attribute to indicate unaligned ssemov insns
699 (define_attr "movu" "0,1" (const_string "0"))
701 ;; Used to control the "enabled" attribute on a per-instruction basis.
702 (define_attr "isa" "base,noavx,avx"
703 (const_string "base"))
705 (define_attr "enabled" ""
706 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
707 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
711 ;; Describe a user's asm statement.
712 (define_asm_attributes
713 [(set_attr "length" "128")
714 (set_attr "type" "multi")])
716 (define_code_iterator plusminus [plus minus])
718 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
720 ;; Base name for define_insn
721 (define_code_attr plusminus_insn
722 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
723 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
725 ;; Base name for insn mnemonic.
726 (define_code_attr plusminus_mnemonic
727 [(plus "add") (ss_plus "adds") (us_plus "addus")
728 (minus "sub") (ss_minus "subs") (us_minus "subus")])
729 (define_code_attr plusminus_carry_mnemonic
730 [(plus "adc") (minus "sbb")])
732 ;; Mark commutative operators as such in constraints.
733 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
734 (minus "") (ss_minus "") (us_minus "")])
736 ;; Mapping of signed max and min
737 (define_code_iterator smaxmin [smax smin])
739 ;; Mapping of unsigned max and min
740 (define_code_iterator umaxmin [umax umin])
742 ;; Base name for integer and FP insn mnemonic
743 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
744 (umax "maxu") (umin "minu")])
745 (define_code_attr maxmin_float [(smax "max") (smin "min")])
747 ;; Mapping of logic operators
748 (define_code_iterator any_logic [and ior xor])
749 (define_code_iterator any_or [ior xor])
751 ;; Base name for insn mnemonic.
752 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
754 ;; Mapping of shift-right operators
755 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
757 ;; Base name for define_insn
758 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
760 ;; Base name for insn mnemonic.
761 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
763 ;; Mapping of rotate operators
764 (define_code_iterator any_rotate [rotate rotatert])
766 ;; Base name for define_insn
767 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
769 ;; Base name for insn mnemonic.
770 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
772 ;; Mapping of abs neg operators
773 (define_code_iterator absneg [abs neg])
775 ;; Base name for x87 insn mnemonic.
776 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
778 ;; Used in signed and unsigned widening multiplications.
779 (define_code_iterator any_extend [sign_extend zero_extend])
781 ;; Various insn prefixes for signed and unsigned operations.
782 (define_code_attr u [(sign_extend "") (zero_extend "u")
783 (div "") (udiv "u")])
784 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
786 ;; Used in signed and unsigned divisions.
787 (define_code_iterator any_div [div udiv])
789 ;; Instruction prefix for signed and unsigned operations.
790 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
791 (div "i") (udiv "")])
793 ;; All integer modes.
794 (define_mode_iterator SWI1248x [QI HI SI DI])
796 ;; All integer modes without QImode.
797 (define_mode_iterator SWI248x [HI SI DI])
799 ;; All integer modes without QImode and HImode.
800 (define_mode_iterator SWI48x [SI DI])
802 ;; All integer modes without SImode and DImode.
803 (define_mode_iterator SWI12 [QI HI])
805 ;; All integer modes without DImode.
806 (define_mode_iterator SWI124 [QI HI SI])
808 ;; All integer modes without QImode and DImode.
809 (define_mode_iterator SWI24 [HI SI])
811 ;; Single word integer modes.
812 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
814 ;; Single word integer modes without QImode.
815 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
817 ;; Single word integer modes without QImode and HImode.
818 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
820 ;; All math-dependant single and double word integer modes.
821 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
822 (HI "TARGET_HIMODE_MATH")
823 SI DI (TI "TARGET_64BIT")])
825 ;; Math-dependant single word integer modes.
826 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
827 (HI "TARGET_HIMODE_MATH")
828 SI (DI "TARGET_64BIT")])
830 ;; Math-dependant integer modes without DImode.
831 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
832 (HI "TARGET_HIMODE_MATH")
835 ;; Math-dependant single word integer modes without QImode.
836 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
837 SI (DI "TARGET_64BIT")])
839 ;; Double word integer modes.
840 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
841 (TI "TARGET_64BIT")])
843 ;; Double word integer modes as mode attribute.
844 (define_mode_attr DWI [(SI "DI") (DI "TI")])
845 (define_mode_attr dwi [(SI "di") (DI "ti")])
847 ;; Half mode for double word integer modes.
848 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
849 (DI "TARGET_64BIT")])
851 ;; Instruction suffix for integer modes.
852 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
854 ;; Pointer size prefix for integer modes (Intel asm dialect)
855 (define_mode_attr iptrsize [(QI "BYTE")
860 ;; Register class for integer modes.
861 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
863 ;; Immediate operand constraint for integer modes.
864 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "nF") (DI "e")])
872 ;; Immediate operand constraint for shifts.
873 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
875 ;; General operand predicate for integer modes.
876 (define_mode_attr general_operand
877 [(QI "general_operand")
878 (HI "general_operand")
879 (SI "x86_64_general_operand")
880 (DI "x86_64_general_operand")
881 (TI "x86_64_general_operand")])
883 ;; General sign/zero extend operand predicate for integer modes.
884 (define_mode_attr general_szext_operand
885 [(QI "general_operand")
886 (HI "general_operand")
887 (SI "x86_64_szext_general_operand")
888 (DI "x86_64_szext_general_operand")])
890 ;; Immediate operand predicate for integer modes.
891 (define_mode_attr immediate_operand
892 [(QI "immediate_operand")
893 (HI "immediate_operand")
894 (SI "x86_64_immediate_operand")
895 (DI "x86_64_immediate_operand")])
897 ;; Nonmemory operand predicate for integer modes.
898 (define_mode_attr nonmemory_operand
899 [(QI "nonmemory_operand")
900 (HI "nonmemory_operand")
901 (SI "x86_64_nonmemory_operand")
902 (DI "x86_64_nonmemory_operand")])
904 ;; Operand predicate for shifts.
905 (define_mode_attr shift_operand
906 [(QI "nonimmediate_operand")
907 (HI "nonimmediate_operand")
908 (SI "nonimmediate_operand")
909 (DI "shiftdi_operand")
910 (TI "register_operand")])
912 ;; Operand predicate for shift argument.
913 (define_mode_attr shift_immediate_operand
914 [(QI "const_1_to_31_operand")
915 (HI "const_1_to_31_operand")
916 (SI "const_1_to_31_operand")
917 (DI "const_1_to_63_operand")])
919 ;; Input operand predicate for arithmetic left shifts.
920 (define_mode_attr ashl_input_operand
921 [(QI "nonimmediate_operand")
922 (HI "nonimmediate_operand")
923 (SI "nonimmediate_operand")
924 (DI "ashldi_input_operand")
925 (TI "reg_or_pm1_operand")])
927 ;; SSE and x87 SFmode and DFmode floating point modes
928 (define_mode_iterator MODEF [SF DF])
930 ;; All x87 floating point modes
931 (define_mode_iterator X87MODEF [SF DF XF])
933 ;; SSE instruction suffix for various modes
934 (define_mode_attr ssemodesuffix
936 (V8SF "ps") (V4DF "pd")
937 (V4SF "ps") (V2DF "pd")
938 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
941 ;; SSE vector suffix for floating point modes
942 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
944 ;; SSE vector mode corresponding to a scalar mode
945 (define_mode_attr ssevecmode
946 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
948 ;; Instruction suffix for REX 64bit operators.
949 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
951 ;; This mode iterator allows :P to be used for patterns that operate on
952 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
953 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
955 ;; Scheduling descriptions
957 (include "pentium.md")
960 (include "athlon.md")
961 (include "bdver1.md")
967 ;; Operand and operator predicates and constraints
969 (include "predicates.md")
970 (include "constraints.md")
973 ;; Compare and branch/compare and store instructions.
975 (define_expand "cbranch<mode>4"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
978 (match_operand:SDWIM 2 "<general_operand>" "")))
979 (set (pc) (if_then_else
980 (match_operator 0 "ordered_comparison_operator"
981 [(reg:CC FLAGS_REG) (const_int 0)])
982 (label_ref (match_operand 3 "" ""))
986 if (MEM_P (operands[1]) && MEM_P (operands[2]))
987 operands[1] = force_reg (<MODE>mode, operands[1]);
988 ix86_expand_branch (GET_CODE (operands[0]),
989 operands[1], operands[2], operands[3]);
993 (define_expand "cstore<mode>4"
994 [(set (reg:CC FLAGS_REG)
995 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
996 (match_operand:SWIM 3 "<general_operand>" "")))
997 (set (match_operand:QI 0 "register_operand" "")
998 (match_operator 1 "ordered_comparison_operator"
999 [(reg:CC FLAGS_REG) (const_int 0)]))]
1002 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1003 operands[2] = force_reg (<MODE>mode, operands[2]);
1004 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1005 operands[2], operands[3]);
1009 (define_expand "cmp<mode>_1"
1010 [(set (reg:CC FLAGS_REG)
1011 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1012 (match_operand:SWI48 1 "<general_operand>" "")))])
1014 (define_insn "*cmp<mode>_ccno_1"
1015 [(set (reg FLAGS_REG)
1016 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1017 (match_operand:SWI 1 "const0_operand" "")))]
1018 "ix86_match_ccmode (insn, CCNOmode)"
1020 test{<imodesuffix>}\t%0, %0
1021 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1022 [(set_attr "type" "test,icmp")
1023 (set_attr "length_immediate" "0,1")
1024 (set_attr "mode" "<MODE>")])
1026 (define_insn "*cmp<mode>_1"
1027 [(set (reg FLAGS_REG)
1028 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1029 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1030 "ix86_match_ccmode (insn, CCmode)"
1031 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1032 [(set_attr "type" "icmp")
1033 (set_attr "mode" "<MODE>")])
1035 (define_insn "*cmp<mode>_minus_1"
1036 [(set (reg FLAGS_REG)
1038 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1039 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1041 "ix86_match_ccmode (insn, CCGOCmode)"
1042 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1043 [(set_attr "type" "icmp")
1044 (set_attr "mode" "<MODE>")])
1046 (define_insn "*cmpqi_ext_1"
1047 [(set (reg FLAGS_REG)
1049 (match_operand:QI 0 "general_operand" "Qm")
1052 (match_operand 1 "ext_register_operand" "Q")
1054 (const_int 8)) 0)))]
1055 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056 "cmp{b}\t{%h1, %0|%0, %h1}"
1057 [(set_attr "type" "icmp")
1058 (set_attr "mode" "QI")])
1060 (define_insn "*cmpqi_ext_1_rex64"
1061 [(set (reg FLAGS_REG)
1063 (match_operand:QI 0 "register_operand" "Q")
1066 (match_operand 1 "ext_register_operand" "Q")
1068 (const_int 8)) 0)))]
1069 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1070 "cmp{b}\t{%h1, %0|%0, %h1}"
1071 [(set_attr "type" "icmp")
1072 (set_attr "mode" "QI")])
1074 (define_insn "*cmpqi_ext_2"
1075 [(set (reg FLAGS_REG)
1079 (match_operand 0 "ext_register_operand" "Q")
1082 (match_operand:QI 1 "const0_operand" "")))]
1083 "ix86_match_ccmode (insn, CCNOmode)"
1085 [(set_attr "type" "test")
1086 (set_attr "length_immediate" "0")
1087 (set_attr "mode" "QI")])
1089 (define_expand "cmpqi_ext_3"
1090 [(set (reg:CC FLAGS_REG)
1094 (match_operand 0 "ext_register_operand" "")
1097 (match_operand:QI 1 "immediate_operand" "")))])
1099 (define_insn "*cmpqi_ext_3_insn"
1100 [(set (reg FLAGS_REG)
1104 (match_operand 0 "ext_register_operand" "Q")
1107 (match_operand:QI 1 "general_operand" "Qmn")))]
1108 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1109 "cmp{b}\t{%1, %h0|%h0, %1}"
1110 [(set_attr "type" "icmp")
1111 (set_attr "modrm" "1")
1112 (set_attr "mode" "QI")])
1114 (define_insn "*cmpqi_ext_3_insn_rex64"
1115 [(set (reg FLAGS_REG)
1119 (match_operand 0 "ext_register_operand" "Q")
1122 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1123 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1124 "cmp{b}\t{%1, %h0|%h0, %1}"
1125 [(set_attr "type" "icmp")
1126 (set_attr "modrm" "1")
1127 (set_attr "mode" "QI")])
1129 (define_insn "*cmpqi_ext_4"
1130 [(set (reg FLAGS_REG)
1134 (match_operand 0 "ext_register_operand" "Q")
1139 (match_operand 1 "ext_register_operand" "Q")
1141 (const_int 8)) 0)))]
1142 "ix86_match_ccmode (insn, CCmode)"
1143 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1144 [(set_attr "type" "icmp")
1145 (set_attr "mode" "QI")])
1147 ;; These implement float point compares.
1148 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1149 ;; which would allow mix and match FP modes on the compares. Which is what
1150 ;; the old patterns did, but with many more of them.
1152 (define_expand "cbranchxf4"
1153 [(set (reg:CC FLAGS_REG)
1154 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1155 (match_operand:XF 2 "nonmemory_operand" "")))
1156 (set (pc) (if_then_else
1157 (match_operator 0 "ix86_fp_comparison_operator"
1160 (label_ref (match_operand 3 "" ""))
1164 ix86_expand_branch (GET_CODE (operands[0]),
1165 operands[1], operands[2], operands[3]);
1169 (define_expand "cstorexf4"
1170 [(set (reg:CC FLAGS_REG)
1171 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1172 (match_operand:XF 3 "nonmemory_operand" "")))
1173 (set (match_operand:QI 0 "register_operand" "")
1174 (match_operator 1 "ix86_fp_comparison_operator"
1179 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1180 operands[2], operands[3]);
1184 (define_expand "cbranch<mode>4"
1185 [(set (reg:CC FLAGS_REG)
1186 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1187 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1188 (set (pc) (if_then_else
1189 (match_operator 0 "ix86_fp_comparison_operator"
1192 (label_ref (match_operand 3 "" ""))
1194 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1196 ix86_expand_branch (GET_CODE (operands[0]),
1197 operands[1], operands[2], operands[3]);
1201 (define_expand "cstore<mode>4"
1202 [(set (reg:CC FLAGS_REG)
1203 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1204 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1205 (set (match_operand:QI 0 "register_operand" "")
1206 (match_operator 1 "ix86_fp_comparison_operator"
1209 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1211 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212 operands[2], operands[3]);
1216 (define_expand "cbranchcc4"
1217 [(set (pc) (if_then_else
1218 (match_operator 0 "comparison_operator"
1219 [(match_operand 1 "flags_reg_operand" "")
1220 (match_operand 2 "const0_operand" "")])
1221 (label_ref (match_operand 3 "" ""))
1225 ix86_expand_branch (GET_CODE (operands[0]),
1226 operands[1], operands[2], operands[3]);
1230 (define_expand "cstorecc4"
1231 [(set (match_operand:QI 0 "register_operand" "")
1232 (match_operator 1 "comparison_operator"
1233 [(match_operand 2 "flags_reg_operand" "")
1234 (match_operand 3 "const0_operand" "")]))]
1237 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238 operands[2], operands[3]);
1243 ;; FP compares, step 1:
1244 ;; Set the FP condition codes.
1246 ;; CCFPmode compare with exceptions
1247 ;; CCFPUmode compare with no exceptions
1249 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1250 ;; used to manage the reg stack popping would not be preserved.
1252 (define_insn "*cmpfp_0"
1253 [(set (match_operand:HI 0 "register_operand" "=a")
1256 (match_operand 1 "register_operand" "f")
1257 (match_operand 2 "const0_operand" ""))]
1259 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1260 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1261 "* return output_fp_compare (insn, operands, false, false);"
1262 [(set_attr "type" "multi")
1263 (set_attr "unit" "i387")
1265 (cond [(match_operand:SF 1 "" "")
1267 (match_operand:DF 1 "" "")
1270 (const_string "XF")))])
1272 (define_insn_and_split "*cmpfp_0_cc"
1273 [(set (reg:CCFP FLAGS_REG)
1275 (match_operand 1 "register_operand" "f")
1276 (match_operand 2 "const0_operand" "")))
1277 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1278 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1279 && TARGET_SAHF && !TARGET_CMOVE
1280 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1282 "&& reload_completed"
1285 [(compare:CCFP (match_dup 1)(match_dup 2))]
1287 (set (reg:CC FLAGS_REG)
1288 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290 [(set_attr "type" "multi")
1291 (set_attr "unit" "i387")
1293 (cond [(match_operand:SF 1 "" "")
1295 (match_operand:DF 1 "" "")
1298 (const_string "XF")))])
1300 (define_insn "*cmpfp_xf"
1301 [(set (match_operand:HI 0 "register_operand" "=a")
1304 (match_operand:XF 1 "register_operand" "f")
1305 (match_operand:XF 2 "register_operand" "f"))]
1308 "* return output_fp_compare (insn, operands, false, false);"
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "XF")])
1313 (define_insn_and_split "*cmpfp_xf_cc"
1314 [(set (reg:CCFP FLAGS_REG)
1316 (match_operand:XF 1 "register_operand" "f")
1317 (match_operand:XF 2 "register_operand" "f")))
1318 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1320 && TARGET_SAHF && !TARGET_CMOVE"
1322 "&& reload_completed"
1325 [(compare:CCFP (match_dup 1)(match_dup 2))]
1327 (set (reg:CC FLAGS_REG)
1328 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set_attr "mode" "XF")])
1334 (define_insn "*cmpfp_<mode>"
1335 [(set (match_operand:HI 0 "register_operand" "=a")
1338 (match_operand:MODEF 1 "register_operand" "f")
1339 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1342 "* return output_fp_compare (insn, operands, false, false);"
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1345 (set_attr "mode" "<MODE>")])
1347 (define_insn_and_split "*cmpfp_<mode>_cc"
1348 [(set (reg:CCFP FLAGS_REG)
1350 (match_operand:MODEF 1 "register_operand" "f")
1351 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1352 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1354 && TARGET_SAHF && !TARGET_CMOVE"
1356 "&& reload_completed"
1359 [(compare:CCFP (match_dup 1)(match_dup 2))]
1361 (set (reg:CC FLAGS_REG)
1362 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1364 [(set_attr "type" "multi")
1365 (set_attr "unit" "i387")
1366 (set_attr "mode" "<MODE>")])
1368 (define_insn "*cmpfp_u"
1369 [(set (match_operand:HI 0 "register_operand" "=a")
1372 (match_operand 1 "register_operand" "f")
1373 (match_operand 2 "register_operand" "f"))]
1375 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1377 "* return output_fp_compare (insn, operands, false, true);"
1378 [(set_attr "type" "multi")
1379 (set_attr "unit" "i387")
1381 (cond [(match_operand:SF 1 "" "")
1383 (match_operand:DF 1 "" "")
1386 (const_string "XF")))])
1388 (define_insn_and_split "*cmpfp_u_cc"
1389 [(set (reg:CCFPU FLAGS_REG)
1391 (match_operand 1 "register_operand" "f")
1392 (match_operand 2 "register_operand" "f")))
1393 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395 && TARGET_SAHF && !TARGET_CMOVE
1396 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1398 "&& reload_completed"
1401 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1403 (set (reg:CC FLAGS_REG)
1404 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1406 [(set_attr "type" "multi")
1407 (set_attr "unit" "i387")
1409 (cond [(match_operand:SF 1 "" "")
1411 (match_operand:DF 1 "" "")
1414 (const_string "XF")))])
1416 (define_insn "*cmpfp_<mode>"
1417 [(set (match_operand:HI 0 "register_operand" "=a")
1420 (match_operand 1 "register_operand" "f")
1421 (match_operator 3 "float_operator"
1422 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1424 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1425 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1426 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1427 "* return output_fp_compare (insn, operands, false, false);"
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set_attr "fp_int_src" "true")
1431 (set_attr "mode" "<MODE>")])
1433 (define_insn_and_split "*cmpfp_<mode>_cc"
1434 [(set (reg:CCFP FLAGS_REG)
1436 (match_operand 1 "register_operand" "f")
1437 (match_operator 3 "float_operator"
1438 [(match_operand:SWI24 2 "memory_operand" "m")])))
1439 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1440 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1441 && TARGET_SAHF && !TARGET_CMOVE
1442 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1443 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1445 "&& reload_completed"
1450 (match_op_dup 3 [(match_dup 2)]))]
1452 (set (reg:CC FLAGS_REG)
1453 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1455 [(set_attr "type" "multi")
1456 (set_attr "unit" "i387")
1457 (set_attr "fp_int_src" "true")
1458 (set_attr "mode" "<MODE>")])
1460 ;; FP compares, step 2
1461 ;; Move the fpsw to ax.
1463 (define_insn "x86_fnstsw_1"
1464 [(set (match_operand:HI 0 "register_operand" "=a")
1465 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1468 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1469 (set_attr "mode" "SI")
1470 (set_attr "unit" "i387")])
1472 ;; FP compares, step 3
1473 ;; Get ax into flags, general case.
1475 (define_insn "x86_sahf_1"
1476 [(set (reg:CC FLAGS_REG)
1477 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1481 #ifndef HAVE_AS_IX86_SAHF
1483 return ASM_BYTE "0x9e";
1488 [(set_attr "length" "1")
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "direct")
1491 (set_attr "bdver1_decode" "direct")
1492 (set_attr "mode" "SI")])
1494 ;; Pentium Pro can do steps 1 through 3 in one go.
1495 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1496 (define_insn "*cmpfp_i_mixed"
1497 [(set (reg:CCFP FLAGS_REG)
1498 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1499 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1500 "TARGET_MIX_SSE_I387
1501 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, true, false);"
1504 [(set_attr "type" "fcmp,ssecomi")
1505 (set_attr "prefix" "orig,maybe_vex")
1507 (if_then_else (match_operand:SF 1 "" "")
1509 (const_string "DF")))
1510 (set (attr "prefix_rep")
1511 (if_then_else (eq_attr "type" "ssecomi")
1513 (const_string "*")))
1514 (set (attr "prefix_data16")
1515 (cond [(eq_attr "type" "fcmp")
1517 (eq_attr "mode" "DF")
1520 (const_string "0")))
1521 (set_attr "athlon_decode" "vector")
1522 (set_attr "amdfam10_decode" "direct")
1523 (set_attr "bdver1_decode" "double")])
1525 (define_insn "*cmpfp_i_sse"
1526 [(set (reg:CCFP FLAGS_REG)
1527 (compare:CCFP (match_operand 0 "register_operand" "x")
1528 (match_operand 1 "nonimmediate_operand" "xm")))]
1530 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532 "* return output_fp_compare (insn, operands, true, false);"
1533 [(set_attr "type" "ssecomi")
1534 (set_attr "prefix" "maybe_vex")
1536 (if_then_else (match_operand:SF 1 "" "")
1538 (const_string "DF")))
1539 (set_attr "prefix_rep" "0")
1540 (set (attr "prefix_data16")
1541 (if_then_else (eq_attr "mode" "DF")
1543 (const_string "0")))
1544 (set_attr "athlon_decode" "vector")
1545 (set_attr "amdfam10_decode" "direct")
1546 (set_attr "bdver1_decode" "double")])
1548 (define_insn "*cmpfp_i_i387"
1549 [(set (reg:CCFP FLAGS_REG)
1550 (compare:CCFP (match_operand 0 "register_operand" "f")
1551 (match_operand 1 "register_operand" "f")))]
1552 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1554 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1555 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556 "* return output_fp_compare (insn, operands, true, false);"
1557 [(set_attr "type" "fcmp")
1559 (cond [(match_operand:SF 1 "" "")
1561 (match_operand:DF 1 "" "")
1564 (const_string "XF")))
1565 (set_attr "athlon_decode" "vector")
1566 (set_attr "amdfam10_decode" "direct")
1567 (set_attr "bdver1_decode" "double")])
1569 (define_insn "*cmpfp_iu_mixed"
1570 [(set (reg:CCFPU FLAGS_REG)
1571 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1572 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1573 "TARGET_MIX_SSE_I387
1574 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, true, true);"
1577 [(set_attr "type" "fcmp,ssecomi")
1578 (set_attr "prefix" "orig,maybe_vex")
1580 (if_then_else (match_operand:SF 1 "" "")
1582 (const_string "DF")))
1583 (set (attr "prefix_rep")
1584 (if_then_else (eq_attr "type" "ssecomi")
1586 (const_string "*")))
1587 (set (attr "prefix_data16")
1588 (cond [(eq_attr "type" "fcmp")
1590 (eq_attr "mode" "DF")
1593 (const_string "0")))
1594 (set_attr "athlon_decode" "vector")
1595 (set_attr "amdfam10_decode" "direct")
1596 (set_attr "bdver1_decode" "double")])
1598 (define_insn "*cmpfp_iu_sse"
1599 [(set (reg:CCFPU FLAGS_REG)
1600 (compare:CCFPU (match_operand 0 "register_operand" "x")
1601 (match_operand 1 "nonimmediate_operand" "xm")))]
1603 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1604 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1605 "* return output_fp_compare (insn, operands, true, true);"
1606 [(set_attr "type" "ssecomi")
1607 (set_attr "prefix" "maybe_vex")
1609 (if_then_else (match_operand:SF 1 "" "")
1611 (const_string "DF")))
1612 (set_attr "prefix_rep" "0")
1613 (set (attr "prefix_data16")
1614 (if_then_else (eq_attr "mode" "DF")
1616 (const_string "0")))
1617 (set_attr "athlon_decode" "vector")
1618 (set_attr "amdfam10_decode" "direct")
1619 (set_attr "bdver1_decode" "double")])
1621 (define_insn "*cmpfp_iu_387"
1622 [(set (reg:CCFPU FLAGS_REG)
1623 (compare:CCFPU (match_operand 0 "register_operand" "f")
1624 (match_operand 1 "register_operand" "f")))]
1625 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1627 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1628 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629 "* return output_fp_compare (insn, operands, true, true);"
1630 [(set_attr "type" "fcmp")
1632 (cond [(match_operand:SF 1 "" "")
1634 (match_operand:DF 1 "" "")
1637 (const_string "XF")))
1638 (set_attr "athlon_decode" "vector")
1639 (set_attr "amdfam10_decode" "direct")
1640 (set_attr "bdver1_decode" "direct")])
1642 ;; Push/pop instructions.
1644 (define_insn "*push<mode>2"
1645 [(set (match_operand:DWI 0 "push_operand" "=<")
1646 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1651 [(set (match_operand:TI 0 "push_operand" "")
1652 (match_operand:TI 1 "general_operand" ""))]
1653 "TARGET_64BIT && reload_completed
1654 && !SSE_REG_P (operands[1])"
1656 "ix86_split_long_move (operands); DONE;")
1658 (define_insn "*pushdi2_rex64"
1659 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1660 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1665 [(set_attr "type" "push,multi")
1666 (set_attr "mode" "DI")])
1668 ;; Convert impossible pushes of immediate to existing instructions.
1669 ;; First try to get scratch register and go through it. In case this
1670 ;; fails, push sign extended lower part first and then overwrite
1671 ;; upper part by 32bit move.
1673 [(match_scratch:DI 2 "r")
1674 (set (match_operand:DI 0 "push_operand" "")
1675 (match_operand:DI 1 "immediate_operand" ""))]
1676 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1677 && !x86_64_immediate_operand (operands[1], DImode)"
1678 [(set (match_dup 2) (match_dup 1))
1679 (set (match_dup 0) (match_dup 2))])
1681 ;; We need to define this as both peepholer and splitter for case
1682 ;; peephole2 pass is not run.
1683 ;; "&& 1" is needed to keep it from matching the previous pattern.
1685 [(set (match_operand:DI 0 "push_operand" "")
1686 (match_operand:DI 1 "immediate_operand" ""))]
1687 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1688 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1689 [(set (match_dup 0) (match_dup 1))
1690 (set (match_dup 2) (match_dup 3))]
1692 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1694 operands[1] = gen_lowpart (DImode, operands[2]);
1695 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1700 [(set (match_operand:DI 0 "push_operand" "")
1701 (match_operand:DI 1 "immediate_operand" ""))]
1702 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1703 ? epilogue_completed : reload_completed)
1704 && !symbolic_operand (operands[1], DImode)
1705 && !x86_64_immediate_operand (operands[1], DImode)"
1706 [(set (match_dup 0) (match_dup 1))
1707 (set (match_dup 2) (match_dup 3))]
1709 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1711 operands[1] = gen_lowpart (DImode, operands[2]);
1712 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1717 [(set (match_operand:DI 0 "push_operand" "")
1718 (match_operand:DI 1 "general_operand" ""))]
1719 "!TARGET_64BIT && reload_completed
1720 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1722 "ix86_split_long_move (operands); DONE;")
1724 (define_insn "*pushsi2"
1725 [(set (match_operand:SI 0 "push_operand" "=<")
1726 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "SI")])
1732 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1733 ;; "push a byte/word". But actually we use pushl, which has the effect
1734 ;; of rounding the amount pushed up to a word.
1736 ;; For TARGET_64BIT we always round up to 8 bytes.
1737 (define_insn "*push<mode>2_rex64"
1738 [(set (match_operand:SWI124 0 "push_operand" "=X")
1739 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "DI")])
1745 (define_insn "*push<mode>2"
1746 [(set (match_operand:SWI12 0 "push_operand" "=X")
1747 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1750 [(set_attr "type" "push")
1751 (set_attr "mode" "SI")])
1753 (define_insn "*push<mode>2_prologue"
1754 [(set (match_operand:P 0 "push_operand" "=<")
1755 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1756 (clobber (mem:BLK (scratch)))]
1758 "push{<imodesuffix>}\t%1"
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "<MODE>")])
1762 (define_insn "*pop<mode>1"
1763 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1764 (match_operand:P 1 "pop_operand" ">"))]
1766 "pop{<imodesuffix>}\t%0"
1767 [(set_attr "type" "pop")
1768 (set_attr "mode" "<MODE>")])
1770 (define_insn "*pop<mode>1_epilogue"
1771 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1772 (match_operand:P 1 "pop_operand" ">"))
1773 (clobber (mem:BLK (scratch)))]
1775 "pop{<imodesuffix>}\t%0"
1776 [(set_attr "type" "pop")
1777 (set_attr "mode" "<MODE>")])
1779 ;; Move instructions.
1781 (define_expand "movoi"
1782 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1783 (match_operand:OI 1 "general_operand" ""))]
1785 "ix86_expand_move (OImode, operands); DONE;")
1787 (define_expand "movti"
1788 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1789 (match_operand:TI 1 "nonimmediate_operand" ""))]
1790 "TARGET_64BIT || TARGET_SSE"
1793 ix86_expand_move (TImode, operands);
1794 else if (push_operand (operands[0], TImode))
1795 ix86_expand_push (TImode, operands[1]);
1797 ix86_expand_vector_move (TImode, operands);
1801 ;; This expands to what emit_move_complex would generate if we didn't
1802 ;; have a movti pattern. Having this avoids problems with reload on
1803 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1804 ;; to have around all the time.
1805 (define_expand "movcdi"
1806 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1807 (match_operand:CDI 1 "general_operand" ""))]
1810 if (push_operand (operands[0], CDImode))
1811 emit_move_complex_push (CDImode, operands[0], operands[1]);
1813 emit_move_complex_parts (operands[0], operands[1]);
1817 (define_expand "mov<mode>"
1818 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1819 (match_operand:SWI1248x 1 "general_operand" ""))]
1821 "ix86_expand_move (<MODE>mode, operands); DONE;")
1823 (define_insn "*mov<mode>_xor"
1824 [(set (match_operand:SWI48 0 "register_operand" "=r")
1825 (match_operand:SWI48 1 "const0_operand" ""))
1826 (clobber (reg:CC FLAGS_REG))]
1829 [(set_attr "type" "alu1")
1830 (set_attr "mode" "SI")
1831 (set_attr "length_immediate" "0")])
1833 (define_insn "*mov<mode>_or"
1834 [(set (match_operand:SWI48 0 "register_operand" "=r")
1835 (match_operand:SWI48 1 "const_int_operand" ""))
1836 (clobber (reg:CC FLAGS_REG))]
1838 && operands[1] == constm1_rtx"
1839 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1840 [(set_attr "type" "alu1")
1841 (set_attr "mode" "<MODE>")
1842 (set_attr "length_immediate" "1")])
1844 (define_insn "*movoi_internal_avx"
1845 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1846 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1847 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1849 switch (which_alternative)
1852 return standard_sse_constant_opcode (insn, operands[1]);
1855 if (misaligned_operand (operands[0], OImode)
1856 || misaligned_operand (operands[1], OImode))
1857 return "vmovdqu\t{%1, %0|%0, %1}";
1859 return "vmovdqa\t{%1, %0|%0, %1}";
1864 [(set_attr "type" "sselog1,ssemov,ssemov")
1865 (set_attr "prefix" "vex")
1866 (set_attr "mode" "OI")])
1868 (define_insn "*movti_internal_rex64"
1869 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1870 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1871 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1873 switch (which_alternative)
1879 return standard_sse_constant_opcode (insn, operands[1]);
1882 /* TDmode values are passed as TImode on the stack. Moving them
1883 to stack may result in unaligned memory access. */
1884 if (misaligned_operand (operands[0], TImode)
1885 || misaligned_operand (operands[1], TImode))
1887 if (get_attr_mode (insn) == MODE_V4SF)
1888 return "%vmovups\t{%1, %0|%0, %1}";
1890 return "%vmovdqu\t{%1, %0|%0, %1}";
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovaps\t{%1, %0|%0, %1}";
1897 return "%vmovdqa\t{%1, %0|%0, %1}";
1903 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1904 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1906 (cond [(eq_attr "alternative" "2,3")
1908 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1910 (const_string "V4SF")
1911 (const_string "TI"))
1912 (eq_attr "alternative" "4")
1914 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1916 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1918 (const_string "V4SF")
1919 (const_string "TI"))]
1920 (const_string "DI")))])
1923 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1924 (match_operand:TI 1 "general_operand" ""))]
1926 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1928 "ix86_split_long_move (operands); DONE;")
1930 (define_insn "*movti_internal_sse"
1931 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1932 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1933 "TARGET_SSE && !TARGET_64BIT
1934 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1936 switch (which_alternative)
1939 return standard_sse_constant_opcode (insn, operands[1]);
1942 /* TDmode values are passed as TImode on the stack. Moving them
1943 to stack may result in unaligned memory access. */
1944 if (misaligned_operand (operands[0], TImode)
1945 || misaligned_operand (operands[1], TImode))
1947 if (get_attr_mode (insn) == MODE_V4SF)
1948 return "%vmovups\t{%1, %0|%0, %1}";
1950 return "%vmovdqu\t{%1, %0|%0, %1}";
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovaps\t{%1, %0|%0, %1}";
1957 return "%vmovdqa\t{%1, %0|%0, %1}";
1963 [(set_attr "type" "sselog1,ssemov,ssemov")
1964 (set_attr "prefix" "maybe_vex")
1966 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1967 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1969 (const_string "V4SF")
1970 (and (eq_attr "alternative" "2")
1971 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1973 (const_string "V4SF")]
1974 (const_string "TI")))])
1976 (define_insn "*movdi_internal_rex64"
1977 [(set (match_operand:DI 0 "nonimmediate_operand"
1978 "=r,r ,r,m ,!m,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1979 (match_operand:DI 1 "general_operand"
1980 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1981 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983 switch (get_attr_type (insn))
1986 if (SSE_REG_P (operands[0]))
1987 return "movq2dq\t{%1, %0|%0, %1}";
1989 return "movdq2q\t{%1, %0|%0, %1}";
1992 if (get_attr_mode (insn) == MODE_TI)
1993 return "%vmovdqa\t{%1, %0|%0, %1}";
1994 /* Handle broken assemblers that require movd instead of movq. */
1995 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996 return "%vmovd\t{%1, %0|%0, %1}";
1998 return "%vmovq\t{%1, %0|%0, %1}";
2001 /* Handle broken assemblers that require movd instead of movq. */
2002 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2003 return "movd\t{%1, %0|%0, %1}";
2005 return "movq\t{%1, %0|%0, %1}";
2008 return standard_sse_constant_opcode (insn, operands[1]);
2011 return "pxor\t%0, %0";
2017 return "lea{q}\t{%a1, %0|%0, %a1}";
2020 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2021 if (get_attr_mode (insn) == MODE_SI)
2022 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2023 else if (which_alternative == 2)
2024 return "movabs{q}\t{%1, %0|%0, %1}";
2026 return "mov{q}\t{%1, %0|%0, %1}";
2030 (cond [(eq_attr "alternative" "4")
2031 (const_string "multi")
2032 (eq_attr "alternative" "5")
2033 (const_string "mmx")
2034 (eq_attr "alternative" "6,7,8,9")
2035 (const_string "mmxmov")
2036 (eq_attr "alternative" "10")
2037 (const_string "sselog1")
2038 (eq_attr "alternative" "11,12,13,14,15")
2039 (const_string "ssemov")
2040 (eq_attr "alternative" "16,17")
2041 (const_string "ssecvt")
2042 (match_operand 1 "pic_32bit_operand" "")
2043 (const_string "lea")
2045 (const_string "imov")))
2048 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2050 (const_string "*")))
2051 (set (attr "length_immediate")
2053 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2055 (const_string "*")))
2056 (set (attr "prefix_rex")
2057 (if_then_else (eq_attr "alternative" "8,9")
2059 (const_string "*")))
2060 (set (attr "prefix_data16")
2061 (if_then_else (eq_attr "alternative" "11")
2063 (const_string "*")))
2064 (set (attr "prefix")
2065 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2066 (const_string "maybe_vex")
2067 (const_string "orig")))
2068 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it. In case this
2072 ;; fails, move by 32bit parts.
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))])
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2086 [(set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090 [(set (match_dup 2) (match_dup 3))
2091 (set (match_dup 4) (match_dup 5))]
2092 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2095 [(set (match_operand:DI 0 "memory_operand" "")
2096 (match_operand:DI 1 "immediate_operand" ""))]
2097 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098 ? epilogue_completed : reload_completed)
2099 && !symbolic_operand (operands[1], DImode)
2100 && !x86_64_immediate_operand (operands[1], DImode)"
2101 [(set (match_dup 2) (match_dup 3))
2102 (set (match_dup 4) (match_dup 5))]
2103 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2105 (define_insn "*movdi_internal"
2106 [(set (match_operand:DI 0 "nonimmediate_operand"
2107 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2108 (match_operand:DI 1 "general_operand"
2109 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m ,*Ym ,*Y2"))]
2110 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2112 switch (get_attr_type (insn))
2115 if (SSE_REG_P (operands[0]))
2116 return "movq2dq\t{%1, %0|%0, %1}";
2118 return "movdq2q\t{%1, %0|%0, %1}";
2121 switch (get_attr_mode (insn))
2124 return "%vmovdqa\t{%1, %0|%0, %1}";
2126 return "%vmovq\t{%1, %0|%0, %1}";
2128 return "movaps\t{%1, %0|%0, %1}";
2130 return "movlps\t{%1, %0|%0, %1}";
2136 return "movq\t{%1, %0|%0, %1}";
2139 return standard_sse_constant_opcode (insn, operands[1]);
2142 return "pxor\t%0, %0";
2152 (if_then_else (eq_attr "alternative" "9,10,11,12")
2153 (const_string "noavx")
2154 (const_string "*")))
2156 (cond [(eq_attr "alternative" "0,1")
2157 (const_string "multi")
2158 (eq_attr "alternative" "2")
2159 (const_string "mmx")
2160 (eq_attr "alternative" "3,4")
2161 (const_string "mmxmov")
2162 (eq_attr "alternative" "5,9")
2163 (const_string "sselog1")
2164 (eq_attr "alternative" "13,14")
2165 (const_string "ssecvt")
2167 (const_string "ssemov")))
2168 (set (attr "prefix")
2169 (if_then_else (eq_attr "alternative" "5,6,7,8")
2170 (const_string "maybe_vex")
2171 (const_string "orig")))
2172 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2175 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2176 (match_operand:DI 1 "general_operand" ""))]
2177 "!TARGET_64BIT && reload_completed
2178 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2179 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2181 "ix86_split_long_move (operands); DONE;")
2183 (define_insn "*movsi_internal"
2184 [(set (match_operand:SI 0 "nonimmediate_operand"
2185 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2186 (match_operand:SI 1 "general_operand"
2187 "g ,re,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 1 "pic_32bit_operand" "")
2236 (const_string "lea")
2238 (const_string "imov")))
2239 (set (attr "prefix")
2240 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2241 (const_string "orig")
2242 (const_string "maybe_vex")))
2243 (set (attr "prefix_data16")
2244 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2246 (const_string "*")))
2248 (cond [(eq_attr "alternative" "2,3")
2250 (eq_attr "alternative" "6,7")
2252 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2253 (const_string "V4SF")
2254 (const_string "TI"))
2255 (and (eq_attr "alternative" "8,9,10,11")
2256 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2259 (const_string "SI")))])
2261 (define_insn "*movhi_internal"
2262 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2263 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2264 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2266 switch (get_attr_type (insn))
2269 /* movzwl is faster than movw on p2 due to partial word stalls,
2270 though not as fast as an aligned movl. */
2271 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2273 if (get_attr_mode (insn) == MODE_SI)
2274 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2276 return "mov{w}\t{%1, %0|%0, %1}";
2280 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2282 (const_string "imov")
2283 (and (eq_attr "alternative" "0")
2284 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2286 (eq (symbol_ref "TARGET_HIMODE_MATH")
2288 (const_string "imov")
2289 (and (eq_attr "alternative" "1,2")
2290 (match_operand:HI 1 "aligned_operand" ""))
2291 (const_string "imov")
2292 (and (ne (symbol_ref "TARGET_MOVX")
2294 (eq_attr "alternative" "0,2"))
2295 (const_string "imovx")
2297 (const_string "imov")))
2299 (cond [(eq_attr "type" "imovx")
2301 (and (eq_attr "alternative" "1,2")
2302 (match_operand:HI 1 "aligned_operand" ""))
2304 (and (eq_attr "alternative" "0")
2305 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2307 (eq (symbol_ref "TARGET_HIMODE_MATH")
2311 (const_string "HI")))])
2313 ;; Situation is quite tricky about when to choose full sized (SImode) move
2314 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2315 ;; partial register dependency machines (such as AMD Athlon), where QImode
2316 ;; moves issue extra dependency and for partial register stalls machines
2317 ;; that don't use QImode patterns (and QImode move cause stall on the next
2320 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2321 ;; register stall machines with, where we use QImode instructions, since
2322 ;; partial register stall can be caused there. Then we use movzx.
2323 (define_insn "*movqi_internal"
2324 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2325 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2326 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2328 switch (get_attr_type (insn))
2331 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2332 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2334 if (get_attr_mode (insn) == MODE_SI)
2335 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2337 return "mov{b}\t{%1, %0|%0, %1}";
2341 (cond [(and (eq_attr "alternative" "5")
2342 (not (match_operand:QI 1 "aligned_operand" "")))
2343 (const_string "imovx")
2344 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2346 (const_string "imov")
2347 (and (eq_attr "alternative" "3")
2348 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2350 (eq (symbol_ref "TARGET_QIMODE_MATH")
2352 (const_string "imov")
2353 (eq_attr "alternative" "3,5")
2354 (const_string "imovx")
2355 (and (ne (symbol_ref "TARGET_MOVX")
2357 (eq_attr "alternative" "2"))
2358 (const_string "imovx")
2360 (const_string "imov")))
2362 (cond [(eq_attr "alternative" "3,4,5")
2364 (eq_attr "alternative" "6")
2366 (eq_attr "type" "imovx")
2368 (and (eq_attr "type" "imov")
2369 (and (eq_attr "alternative" "0,1")
2370 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2372 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2374 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2377 ;; Avoid partial register stalls when not using QImode arithmetic
2378 (and (eq_attr "type" "imov")
2379 (and (eq_attr "alternative" "0,1")
2380 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2382 (eq (symbol_ref "TARGET_QIMODE_MATH")
2386 (const_string "QI")))])
2388 ;; Stores and loads of ax to arbitrary constant address.
2389 ;; We fake an second form of instruction to force reload to load address
2390 ;; into register when rax is not available
2391 (define_insn "*movabs<mode>_1"
2392 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2393 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2394 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2396 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2397 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2398 [(set_attr "type" "imov")
2399 (set_attr "modrm" "0,*")
2400 (set_attr "length_address" "8,0")
2401 (set_attr "length_immediate" "0,*")
2402 (set_attr "memory" "store")
2403 (set_attr "mode" "<MODE>")])
2405 (define_insn "*movabs<mode>_2"
2406 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2407 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2408 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2410 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2411 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2412 [(set_attr "type" "imov")
2413 (set_attr "modrm" "0,*")
2414 (set_attr "length_address" "8,0")
2415 (set_attr "length_immediate" "0")
2416 (set_attr "memory" "load")
2417 (set_attr "mode" "<MODE>")])
2419 (define_insn "*swap<mode>"
2420 [(set (match_operand:SWI48 0 "register_operand" "+r")
2421 (match_operand:SWI48 1 "register_operand" "+r"))
2425 "xchg{<imodesuffix>}\t%1, %0"
2426 [(set_attr "type" "imov")
2427 (set_attr "mode" "<MODE>")
2428 (set_attr "pent_pair" "np")
2429 (set_attr "athlon_decode" "vector")
2430 (set_attr "amdfam10_decode" "double")
2431 (set_attr "bdver1_decode" "double")])
2433 (define_insn "*swap<mode>_1"
2434 [(set (match_operand:SWI12 0 "register_operand" "+r")
2435 (match_operand:SWI12 1 "register_operand" "+r"))
2438 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2440 [(set_attr "type" "imov")
2441 (set_attr "mode" "SI")
2442 (set_attr "pent_pair" "np")
2443 (set_attr "athlon_decode" "vector")
2444 (set_attr "amdfam10_decode" "double")
2445 (set_attr "bdver1_decode" "double")])
2447 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2448 ;; is disabled for AMDFAM10
2449 (define_insn "*swap<mode>_2"
2450 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2451 (match_operand:SWI12 1 "register_operand" "+<r>"))
2454 "TARGET_PARTIAL_REG_STALL"
2455 "xchg{<imodesuffix>}\t%1, %0"
2456 [(set_attr "type" "imov")
2457 (set_attr "mode" "<MODE>")
2458 (set_attr "pent_pair" "np")
2459 (set_attr "athlon_decode" "vector")])
2461 (define_expand "movstrict<mode>"
2462 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2463 (match_operand:SWI12 1 "general_operand" ""))]
2466 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2468 if (GET_CODE (operands[0]) == SUBREG
2469 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2471 /* Don't generate memory->memory moves, go through a register */
2472 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2473 operands[1] = force_reg (<MODE>mode, operands[1]);
2476 (define_insn "*movstrict<mode>_1"
2477 [(set (strict_low_part
2478 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2479 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2480 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2481 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2483 [(set_attr "type" "imov")
2484 (set_attr "mode" "<MODE>")])
2486 (define_insn "*movstrict<mode>_xor"
2487 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2488 (match_operand:SWI12 1 "const0_operand" ""))
2489 (clobber (reg:CC FLAGS_REG))]
2491 "xor{<imodesuffix>}\t%0, %0"
2492 [(set_attr "type" "alu1")
2493 (set_attr "mode" "<MODE>")
2494 (set_attr "length_immediate" "0")])
2496 (define_insn "*mov<mode>_extv_1"
2497 [(set (match_operand:SWI24 0 "register_operand" "=R")
2498 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2502 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2503 [(set_attr "type" "imovx")
2504 (set_attr "mode" "SI")])
2506 (define_insn "*movqi_extv_1_rex64"
2507 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2508 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2513 switch (get_attr_type (insn))
2516 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2518 return "mov{b}\t{%h1, %0|%0, %h1}";
2522 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2523 (ne (symbol_ref "TARGET_MOVX")
2525 (const_string "imovx")
2526 (const_string "imov")))
2528 (if_then_else (eq_attr "type" "imovx")
2530 (const_string "QI")))])
2532 (define_insn "*movqi_extv_1"
2533 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2534 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2539 switch (get_attr_type (insn))
2542 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2544 return "mov{b}\t{%h1, %0|%0, %h1}";
2548 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2549 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2550 (ne (symbol_ref "TARGET_MOVX")
2552 (const_string "imovx")
2553 (const_string "imov")))
2555 (if_then_else (eq_attr "type" "imovx")
2557 (const_string "QI")))])
2559 (define_insn "*mov<mode>_extzv_1"
2560 [(set (match_operand:SWI48 0 "register_operand" "=R")
2561 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2565 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2566 [(set_attr "type" "imovx")
2567 (set_attr "mode" "SI")])
2569 (define_insn "*movqi_extzv_2_rex64"
2570 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2572 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2577 switch (get_attr_type (insn))
2580 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2582 return "mov{b}\t{%h1, %0|%0, %h1}";
2586 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2587 (ne (symbol_ref "TARGET_MOVX")
2589 (const_string "imovx")
2590 (const_string "imov")))
2592 (if_then_else (eq_attr "type" "imovx")
2594 (const_string "QI")))])
2596 (define_insn "*movqi_extzv_2"
2597 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2599 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2604 switch (get_attr_type (insn))
2607 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2609 return "mov{b}\t{%h1, %0|%0, %h1}";
2613 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2614 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2615 (ne (symbol_ref "TARGET_MOVX")
2617 (const_string "imovx")
2618 (const_string "imov")))
2620 (if_then_else (eq_attr "type" "imovx")
2622 (const_string "QI")))])
2624 (define_expand "mov<mode>_insv_1"
2625 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2628 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2630 (define_insn "*mov<mode>_insv_1_rex64"
2631 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2634 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2636 "mov{b}\t{%b1, %h0|%h0, %b1}"
2637 [(set_attr "type" "imov")
2638 (set_attr "mode" "QI")])
2640 (define_insn "*movsi_insv_1"
2641 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2644 (match_operand:SI 1 "general_operand" "Qmn"))]
2646 "mov{b}\t{%b1, %h0|%h0, %b1}"
2647 [(set_attr "type" "imov")
2648 (set_attr "mode" "QI")])
2650 (define_insn "*movqi_insv_2"
2651 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2654 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2657 "mov{b}\t{%h1, %h0|%h0, %h1}"
2658 [(set_attr "type" "imov")
2659 (set_attr "mode" "QI")])
2661 ;; Floating point push instructions.
2663 (define_insn "*pushtf"
2664 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2665 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2668 /* This insn should be already split before reg-stack. */
2671 [(set_attr "type" "multi")
2672 (set_attr "unit" "sse,*,*")
2673 (set_attr "mode" "TF,SI,SI")])
2675 ;; %%% Kill this when call knows how to work this out.
2677 [(set (match_operand:TF 0 "push_operand" "")
2678 (match_operand:TF 1 "sse_reg_operand" ""))]
2679 "TARGET_SSE2 && reload_completed"
2680 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2681 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2683 (define_insn "*pushxf"
2684 [(set (match_operand:XF 0 "push_operand" "=<,<")
2685 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2686 "optimize_function_for_speed_p (cfun)"
2688 /* This insn should be already split before reg-stack. */
2691 [(set_attr "type" "multi")
2692 (set_attr "unit" "i387,*")
2693 (set_attr "mode" "XF,SI")])
2695 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2696 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2697 ;; Pushing using integer instructions is longer except for constants
2698 ;; and direct memory references (assuming that any given constant is pushed
2699 ;; only once, but this ought to be handled elsewhere).
2701 (define_insn "*pushxf_nointeger"
2702 [(set (match_operand:XF 0 "push_operand" "=X,X")
2703 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2704 "optimize_function_for_size_p (cfun)"
2706 /* This insn should be already split before reg-stack. */
2709 [(set_attr "type" "multi")
2710 (set_attr "unit" "i387,*")
2711 (set_attr "mode" "XF,SI")])
2713 ;; %%% Kill this when call knows how to work this out.
2715 [(set (match_operand:XF 0 "push_operand" "")
2716 (match_operand:XF 1 "fp_register_operand" ""))]
2718 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2719 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2720 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2724 ;; On the average, pushdf using integers can be still shorter.
2726 (define_insn "*pushdf"
2727 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2728 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2731 /* This insn should be already split before reg-stack. */
2734 [(set_attr "type" "multi")
2735 (set_attr "unit" "i387,*,*")
2736 (set_attr "mode" "DF,SI,DF")])
2738 ;; %%% Kill this when call knows how to work this out.
2740 [(set (match_operand:DF 0 "push_operand" "")
2741 (match_operand:DF 1 "any_fp_register_operand" ""))]
2743 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2744 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2746 (define_insn "*pushsf_rex64"
2747 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2748 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2751 /* Anything else should be already split before reg-stack. */
2752 gcc_assert (which_alternative == 1);
2753 return "push{q}\t%q1";
2755 [(set_attr "type" "multi,push,multi")
2756 (set_attr "unit" "i387,*,*")
2757 (set_attr "mode" "SF,DI,SF")])
2759 (define_insn "*pushsf"
2760 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2761 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2764 /* Anything else should be already split before reg-stack. */
2765 gcc_assert (which_alternative == 1);
2766 return "push{l}\t%1";
2768 [(set_attr "type" "multi,push,multi")
2769 (set_attr "unit" "i387,*,*")
2770 (set_attr "mode" "SF,SI,SF")])
2772 ;; %%% Kill this when call knows how to work this out.
2774 [(set (match_operand:SF 0 "push_operand" "")
2775 (match_operand:SF 1 "any_fp_register_operand" ""))]
2777 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2782 [(set (match_operand:SF 0 "push_operand" "")
2783 (match_operand:SF 1 "memory_operand" ""))]
2785 && (operands[2] = find_constant_src (insn))"
2786 [(set (match_dup 0) (match_dup 2))])
2789 [(set (match_operand 0 "push_operand" "")
2790 (match_operand 1 "general_operand" ""))]
2792 && (GET_MODE (operands[0]) == TFmode
2793 || GET_MODE (operands[0]) == XFmode
2794 || GET_MODE (operands[0]) == DFmode)
2795 && !ANY_FP_REG_P (operands[1])"
2797 "ix86_split_long_move (operands); DONE;")
2799 ;; Floating point move instructions.
2801 (define_expand "movtf"
2802 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803 (match_operand:TF 1 "nonimmediate_operand" ""))]
2806 ix86_expand_move (TFmode, operands);
2810 (define_expand "mov<mode>"
2811 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2812 (match_operand:X87MODEF 1 "general_operand" ""))]
2814 "ix86_expand_move (<MODE>mode, operands); DONE;")
2816 (define_insn "*movtf_internal"
2817 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2818 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2821 && (!can_create_pseudo_p ()
2822 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2823 || GET_CODE (operands[1]) != CONST_DOUBLE
2824 || (optimize_function_for_size_p (cfun)
2825 && standard_sse_constant_p (operands[1])
2826 && !memory_operand (operands[0], TFmode))
2827 || (!TARGET_MEMORY_MISMATCH_STALL
2828 && memory_operand (operands[0], TFmode)))"
2830 switch (which_alternative)
2834 /* Handle misaligned load/store since we
2835 don't have movmisaligntf pattern. */
2836 if (misaligned_operand (operands[0], TFmode)
2837 || misaligned_operand (operands[1], TFmode))
2839 if (get_attr_mode (insn) == MODE_V4SF)
2840 return "%vmovups\t{%1, %0|%0, %1}";
2842 return "%vmovdqu\t{%1, %0|%0, %1}";
2846 if (get_attr_mode (insn) == MODE_V4SF)
2847 return "%vmovaps\t{%1, %0|%0, %1}";
2849 return "%vmovdqa\t{%1, %0|%0, %1}";
2853 return standard_sse_constant_opcode (insn, operands[1]);
2863 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2864 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2866 (cond [(eq_attr "alternative" "0,2")
2868 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2870 (const_string "V4SF")
2871 (const_string "TI"))
2872 (eq_attr "alternative" "1")
2874 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2876 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2878 (const_string "V4SF")
2879 (const_string "TI"))]
2880 (const_string "DI")))])
2882 ;; Possible store forwarding (partial memory) stall in alternative 4.
2883 (define_insn "*movxf_internal"
2884 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2885 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2886 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2887 && (!can_create_pseudo_p ()
2888 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889 || GET_CODE (operands[1]) != CONST_DOUBLE
2890 || (optimize_function_for_size_p (cfun)
2891 && standard_80387_constant_p (operands[1]) > 0
2892 && !memory_operand (operands[0], XFmode))
2893 || (!TARGET_MEMORY_MISMATCH_STALL
2894 && memory_operand (operands[0], XFmode)))"
2896 switch (which_alternative)
2900 return output_387_reg_move (insn, operands);
2903 return standard_80387_constant_opcode (operands[1]);
2913 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2914 (set_attr "mode" "XF,XF,XF,SI,SI")])
2916 (define_insn "*movdf_internal_rex64"
2917 [(set (match_operand:DF 0 "nonimmediate_operand"
2918 "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2919 (match_operand:DF 1 "general_operand"
2920 "fm,f,G,rm,r ,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2921 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922 && (!can_create_pseudo_p ()
2923 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2924 || GET_CODE (operands[1]) != CONST_DOUBLE
2925 || (optimize_function_for_size_p (cfun)
2926 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2927 && standard_80387_constant_p (operands[1]) > 0)
2928 || (TARGET_SSE2 && TARGET_SSE_MATH
2929 && standard_sse_constant_p (operands[1]))))
2930 || memory_operand (operands[0], DFmode))"
2932 switch (which_alternative)
2936 return output_387_reg_move (insn, operands);
2939 return standard_80387_constant_opcode (operands[1]);
2943 return "mov{q}\t{%1, %0|%0, %1}";
2946 return "movabs{q}\t{%1, %0|%0, %1}";
2952 return standard_sse_constant_opcode (insn, operands[1]);
2957 switch (get_attr_mode (insn))
2960 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2961 return "%vmovapd\t{%1, %0|%0, %1}";
2963 return "%vmovaps\t{%1, %0|%0, %1}";
2966 return "%vmovq\t{%1, %0|%0, %1}";
2968 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2969 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2970 return "%vmovsd\t{%1, %0|%0, %1}";
2972 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2974 return "%vmovlps\t{%1, %d0|%d0, %1}";
2981 /* Handle broken assemblers that require movd instead of movq. */
2982 return "%vmovd\t{%1, %0|%0, %1}";
2988 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2991 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2993 (const_string "*")))
2994 (set (attr "length_immediate")
2996 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2998 (const_string "*")))
2999 (set (attr "prefix")
3000 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3001 (const_string "orig")
3002 (const_string "maybe_vex")))
3003 (set (attr "prefix_data16")
3004 (if_then_else (eq_attr "mode" "V1DF")
3006 (const_string "*")))
3008 (cond [(eq_attr "alternative" "0,1,2")
3010 (eq_attr "alternative" "3,4,5,6,11,12")
3013 /* xorps is one byte shorter. */
3014 (eq_attr "alternative" "7")
3015 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3017 (const_string "V4SF")
3018 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3022 (const_string "V2DF"))
3024 /* For architectures resolving dependencies on
3025 whole SSE registers use APD move to break dependency
3026 chains, otherwise use short move to avoid extra work.
3028 movaps encodes one byte shorter. */
3029 (eq_attr "alternative" "8")
3031 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3033 (const_string "V4SF")
3034 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3036 (const_string "V2DF")
3038 (const_string "DF"))
3039 /* For architectures resolving dependencies on register
3040 parts we may avoid extra work to zero out upper part
3042 (eq_attr "alternative" "9")
3044 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3046 (const_string "V1DF")
3047 (const_string "DF"))
3049 (const_string "DF")))])
3051 ;; Possible store forwarding (partial memory) stall in alternative 4.
3052 (define_insn "*movdf_internal"
3053 [(set (match_operand:DF 0 "nonimmediate_operand"
3054 "=f,m,f,?Yd*r ,!o ,Y2*x,Y2*x,Y2*x,m ")
3055 (match_operand:DF 1 "general_operand"
3056 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3057 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3058 && (!can_create_pseudo_p ()
3059 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060 || GET_CODE (operands[1]) != CONST_DOUBLE
3061 || (optimize_function_for_size_p (cfun)
3062 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3063 && standard_80387_constant_p (operands[1]) > 0)
3064 || (TARGET_SSE2 && TARGET_SSE_MATH
3065 && standard_sse_constant_p (operands[1])))
3066 && !memory_operand (operands[0], DFmode))
3067 || (!TARGET_MEMORY_MISMATCH_STALL
3068 && memory_operand (operands[0], DFmode)))"
3070 switch (which_alternative)
3074 return output_387_reg_move (insn, operands);
3077 return standard_80387_constant_opcode (operands[1]);
3084 return standard_sse_constant_opcode (insn, operands[1]);
3089 switch (get_attr_mode (insn))
3092 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093 return "%vmovapd\t{%1, %0|%0, %1}";
3095 return "%vmovaps\t{%1, %0|%0, %1}";
3098 return "%vmovq\t{%1, %0|%0, %1}";
3100 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3101 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3102 return "%vmovsd\t{%1, %0|%0, %1}";
3104 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3106 return "%vmovlps\t{%1, %d0|%d0, %1}";
3115 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118 (const_string "orig")
3119 (const_string "maybe_vex")))
3120 (set (attr "prefix_data16")
3121 (if_then_else (eq_attr "mode" "V1DF")
3123 (const_string "*")))
3125 (cond [(eq_attr "alternative" "0,1,2")
3127 (eq_attr "alternative" "3,4")
3130 /* For SSE1, we have many fewer alternatives. */
3131 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3133 (eq_attr "alternative" "5,6")
3134 (const_string "V4SF")
3135 (const_string "V2SF"))
3137 /* xorps is one byte shorter. */
3138 (eq_attr "alternative" "5")
3139 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3141 (const_string "V4SF")
3142 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3146 (const_string "V2DF"))
3148 /* For architectures resolving dependencies on
3149 whole SSE registers use APD move to break dependency
3150 chains, otherwise use short move to avoid extra work.
3152 movaps encodes one byte shorter. */
3153 (eq_attr "alternative" "6")
3155 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3157 (const_string "V4SF")
3158 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3160 (const_string "V2DF")
3162 (const_string "DF"))
3163 /* For architectures resolving dependencies on register
3164 parts we may avoid extra work to zero out upper part
3166 (eq_attr "alternative" "7")
3168 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3170 (const_string "V1DF")
3171 (const_string "DF"))
3173 (const_string "DF")))])
3175 (define_insn "*movsf_internal"
3176 [(set (match_operand:SF 0 "nonimmediate_operand"
3177 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3178 (match_operand:SF 1 "general_operand"
3179 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3181 && (!can_create_pseudo_p ()
3182 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183 || GET_CODE (operands[1]) != CONST_DOUBLE
3184 || (optimize_function_for_size_p (cfun)
3185 && ((!TARGET_SSE_MATH
3186 && standard_80387_constant_p (operands[1]) > 0)
3188 && standard_sse_constant_p (operands[1]))))
3189 || memory_operand (operands[0], SFmode))"
3191 switch (which_alternative)
3195 return output_387_reg_move (insn, operands);
3198 return standard_80387_constant_opcode (operands[1]);
3202 return "mov{l}\t{%1, %0|%0, %1}";
3205 return standard_sse_constant_opcode (insn, operands[1]);
3208 if (get_attr_mode (insn) == MODE_V4SF)
3209 return "%vmovaps\t{%1, %0|%0, %1}";
3211 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3215 return "%vmovss\t{%1, %0|%0, %1}";
3221 return "movd\t{%1, %0|%0, %1}";
3224 return "movq\t{%1, %0|%0, %1}";
3228 return "%vmovd\t{%1, %0|%0, %1}";
3234 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3235 (set (attr "prefix")
3236 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3237 (const_string "maybe_vex")
3238 (const_string "orig")))
3240 (cond [(eq_attr "alternative" "3,4,9,10")
3242 (eq_attr "alternative" "5")
3244 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3246 (ne (symbol_ref "TARGET_SSE2")
3248 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3251 (const_string "V4SF"))
3252 /* For architectures resolving dependencies on
3253 whole SSE registers use APS move to break dependency
3254 chains, otherwise use short move to avoid extra work.
3256 Do the same for architectures resolving dependencies on
3257 the parts. While in DF mode it is better to always handle
3258 just register parts, the SF mode is different due to lack
3259 of instructions to load just part of the register. It is
3260 better to maintain the whole registers in single format
3261 to avoid problems on using packed logical operations. */
3262 (eq_attr "alternative" "6")
3264 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3266 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3268 (const_string "V4SF")
3269 (const_string "SF"))
3270 (eq_attr "alternative" "11")
3271 (const_string "DI")]
3272 (const_string "SF")))])
3275 [(set (match_operand 0 "any_fp_register_operand" "")
3276 (match_operand 1 "memory_operand" ""))]
3278 && (GET_MODE (operands[0]) == TFmode
3279 || GET_MODE (operands[0]) == XFmode
3280 || GET_MODE (operands[0]) == DFmode
3281 || GET_MODE (operands[0]) == SFmode)
3282 && (operands[2] = find_constant_src (insn))"
3283 [(set (match_dup 0) (match_dup 2))]
3285 rtx c = operands[2];
3286 int r = REGNO (operands[0]);
3288 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3289 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3294 [(set (match_operand 0 "any_fp_register_operand" "")
3295 (float_extend (match_operand 1 "memory_operand" "")))]
3297 && (GET_MODE (operands[0]) == TFmode
3298 || GET_MODE (operands[0]) == XFmode
3299 || GET_MODE (operands[0]) == DFmode)
3300 && (operands[2] = find_constant_src (insn))"
3301 [(set (match_dup 0) (match_dup 2))]
3303 rtx c = operands[2];
3304 int r = REGNO (operands[0]);
3306 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3307 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3311 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3313 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3314 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3316 && (standard_80387_constant_p (operands[1]) == 8
3317 || standard_80387_constant_p (operands[1]) == 9)"
3318 [(set (match_dup 0)(match_dup 1))
3320 (neg:X87MODEF (match_dup 0)))]
3324 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3325 if (real_isnegzero (&r))
3326 operands[1] = CONST0_RTX (<MODE>mode);
3328 operands[1] = CONST1_RTX (<MODE>mode);
3332 [(set (match_operand 0 "nonimmediate_operand" "")
3333 (match_operand 1 "general_operand" ""))]
3335 && (GET_MODE (operands[0]) == TFmode
3336 || GET_MODE (operands[0]) == XFmode
3337 || GET_MODE (operands[0]) == DFmode)
3338 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3340 "ix86_split_long_move (operands); DONE;")
3342 (define_insn "swapxf"
3343 [(set (match_operand:XF 0 "register_operand" "+f")
3344 (match_operand:XF 1 "register_operand" "+f"))
3349 if (STACK_TOP_P (operands[0]))
3354 [(set_attr "type" "fxch")
3355 (set_attr "mode" "XF")])
3357 (define_insn "*swap<mode>"
3358 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3359 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3362 "TARGET_80387 || reload_completed"
3364 if (STACK_TOP_P (operands[0]))
3369 [(set_attr "type" "fxch")
3370 (set_attr "mode" "<MODE>")])
3372 ;; Zero extension instructions
3374 (define_expand "zero_extendsidi2"
3375 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3376 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3381 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3386 (define_insn "*zero_extendsidi2_rex64"
3387 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3389 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3392 mov\t{%k1, %k0|%k0, %k1}
3394 movd\t{%1, %0|%0, %1}
3395 movd\t{%1, %0|%0, %1}
3396 %vmovd\t{%1, %0|%0, %1}
3397 %vmovd\t{%1, %0|%0, %1}"
3398 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3399 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3400 (set_attr "prefix_0f" "0,*,*,*,*,*")
3401 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3404 [(set (match_operand:DI 0 "memory_operand" "")
3405 (zero_extend:DI (match_dup 0)))]
3407 [(set (match_dup 4) (const_int 0))]
3408 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3410 ;; %%% Kill me once multi-word ops are sane.
3411 (define_insn "zero_extendsidi2_1"
3412 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3414 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3415 (clobber (reg:CC FLAGS_REG))]
3421 movd\t{%1, %0|%0, %1}
3422 movd\t{%1, %0|%0, %1}
3423 %vmovd\t{%1, %0|%0, %1}
3424 %vmovd\t{%1, %0|%0, %1}"
3425 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3426 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3427 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3430 [(set (match_operand:DI 0 "register_operand" "")
3431 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3432 (clobber (reg:CC FLAGS_REG))]
3433 "!TARGET_64BIT && reload_completed
3434 && true_regnum (operands[0]) == true_regnum (operands[1])"
3435 [(set (match_dup 4) (const_int 0))]
3436 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3439 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3440 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3441 (clobber (reg:CC FLAGS_REG))]
3442 "!TARGET_64BIT && reload_completed
3443 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3444 [(set (match_dup 3) (match_dup 1))
3445 (set (match_dup 4) (const_int 0))]
3446 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3448 (define_insn "zero_extend<mode>di2"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3451 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3453 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3454 [(set_attr "type" "imovx")
3455 (set_attr "mode" "SI")])
3457 (define_expand "zero_extendhisi2"
3458 [(set (match_operand:SI 0 "register_operand" "")
3459 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3462 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3464 operands[1] = force_reg (HImode, operands[1]);
3465 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3470 (define_insn_and_split "zero_extendhisi2_and"
3471 [(set (match_operand:SI 0 "register_operand" "=r")
3472 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3473 (clobber (reg:CC FLAGS_REG))]
3474 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3476 "&& reload_completed"
3477 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3478 (clobber (reg:CC FLAGS_REG))])]
3480 [(set_attr "type" "alu1")
3481 (set_attr "mode" "SI")])
3483 (define_insn "*zero_extendhisi2_movzwl"
3484 [(set (match_operand:SI 0 "register_operand" "=r")
3485 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3486 "!TARGET_ZERO_EXTEND_WITH_AND
3487 || optimize_function_for_size_p (cfun)"
3488 "movz{wl|x}\t{%1, %0|%0, %1}"
3489 [(set_attr "type" "imovx")
3490 (set_attr "mode" "SI")])
3492 (define_expand "zero_extendqi<mode>2"
3494 [(set (match_operand:SWI24 0 "register_operand" "")
3495 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3496 (clobber (reg:CC FLAGS_REG))])])
3498 (define_insn "*zero_extendqi<mode>2_and"
3499 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3500 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3501 (clobber (reg:CC FLAGS_REG))]
3502 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3504 [(set_attr "type" "alu1")
3505 (set_attr "mode" "<MODE>")])
3507 ;; When source and destination does not overlap, clear destination
3508 ;; first and then do the movb
3510 [(set (match_operand:SWI24 0 "register_operand" "")
3511 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3512 (clobber (reg:CC FLAGS_REG))]
3514 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3515 && ANY_QI_REG_P (operands[0])
3516 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3517 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3518 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3520 operands[2] = gen_lowpart (QImode, operands[0]);
3521 ix86_expand_clear (operands[0]);
3524 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3525 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3526 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3527 (clobber (reg:CC FLAGS_REG))]
3528 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3530 [(set_attr "type" "imovx,alu1")
3531 (set_attr "mode" "<MODE>")])
3533 ;; For the movzbl case strip only the clobber
3535 [(set (match_operand:SWI24 0 "register_operand" "")
3536 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3537 (clobber (reg:CC FLAGS_REG))]
3539 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3540 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3542 (zero_extend:SWI24 (match_dup 1)))])
3544 ; zero extend to SImode to avoid partial register stalls
3545 (define_insn "*zero_extendqi<mode>2_movzbl"
3546 [(set (match_operand:SWI24 0 "register_operand" "=r")
3547 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3549 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3550 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3551 [(set_attr "type" "imovx")
3552 (set_attr "mode" "SI")])
3554 ;; Rest is handled by single and.
3556 [(set (match_operand:SWI24 0 "register_operand" "")
3557 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3558 (clobber (reg:CC FLAGS_REG))]
3560 && true_regnum (operands[0]) == true_regnum (operands[1])"
3561 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3562 (clobber (reg:CC FLAGS_REG))])])
3564 ;; Sign extension instructions
3566 (define_expand "extendsidi2"
3567 [(set (match_operand:DI 0 "register_operand" "")
3568 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3573 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3578 (define_insn "*extendsidi2_rex64"
3579 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3580 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3584 movs{lq|x}\t{%1, %0|%0, %1}"
3585 [(set_attr "type" "imovx")
3586 (set_attr "mode" "DI")
3587 (set_attr "prefix_0f" "0")
3588 (set_attr "modrm" "0,1")])
3590 (define_insn "extendsidi2_1"
3591 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3592 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3593 (clobber (reg:CC FLAGS_REG))
3594 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3598 ;; Extend to memory case when source register does die.
3600 [(set (match_operand:DI 0 "memory_operand" "")
3601 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3602 (clobber (reg:CC FLAGS_REG))
3603 (clobber (match_operand:SI 2 "register_operand" ""))]
3605 && dead_or_set_p (insn, operands[1])
3606 && !reg_mentioned_p (operands[1], operands[0]))"
3607 [(set (match_dup 3) (match_dup 1))
3608 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3609 (clobber (reg:CC FLAGS_REG))])
3610 (set (match_dup 4) (match_dup 1))]
3611 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3613 ;; Extend to memory case when source register does not die.
3615 [(set (match_operand:DI 0 "memory_operand" "")
3616 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3617 (clobber (reg:CC FLAGS_REG))
3618 (clobber (match_operand:SI 2 "register_operand" ""))]
3622 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3624 emit_move_insn (operands[3], operands[1]);
3626 /* Generate a cltd if possible and doing so it profitable. */
3627 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3628 && true_regnum (operands[1]) == AX_REG
3629 && true_regnum (operands[2]) == DX_REG)
3631 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3635 emit_move_insn (operands[2], operands[1]);
3636 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3638 emit_move_insn (operands[4], operands[2]);
3642 ;; Extend to register case. Optimize case where source and destination
3643 ;; registers match and cases where we can use cltd.
3645 [(set (match_operand:DI 0 "register_operand" "")
3646 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3647 (clobber (reg:CC FLAGS_REG))
3648 (clobber (match_scratch:SI 2 ""))]
3652 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3654 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3655 emit_move_insn (operands[3], operands[1]);
3657 /* Generate a cltd if possible and doing so it profitable. */
3658 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3659 && true_regnum (operands[3]) == AX_REG
3660 && true_regnum (operands[4]) == DX_REG)
3662 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3666 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3667 emit_move_insn (operands[4], operands[1]);
3669 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3673 (define_insn "extend<mode>di2"
3674 [(set (match_operand:DI 0 "register_operand" "=r")
3676 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3678 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3679 [(set_attr "type" "imovx")
3680 (set_attr "mode" "DI")])
3682 (define_insn "extendhisi2"
3683 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3684 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3687 switch (get_attr_prefix_0f (insn))
3690 return "{cwtl|cwde}";
3692 return "movs{wl|x}\t{%1, %0|%0, %1}";
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "SI")
3697 (set (attr "prefix_0f")
3698 ;; movsx is short decodable while cwtl is vector decoded.
3699 (if_then_else (and (eq_attr "cpu" "!k6")
3700 (eq_attr "alternative" "0"))
3702 (const_string "1")))
3704 (if_then_else (eq_attr "prefix_0f" "0")
3706 (const_string "1")))])
3708 (define_insn "*extendhisi2_zext"
3709 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3712 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3715 switch (get_attr_prefix_0f (insn))
3718 return "{cwtl|cwde}";
3720 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3723 [(set_attr "type" "imovx")
3724 (set_attr "mode" "SI")
3725 (set (attr "prefix_0f")
3726 ;; movsx is short decodable while cwtl is vector decoded.
3727 (if_then_else (and (eq_attr "cpu" "!k6")
3728 (eq_attr "alternative" "0"))
3730 (const_string "1")))
3732 (if_then_else (eq_attr "prefix_0f" "0")
3734 (const_string "1")))])
3736 (define_insn "extendqisi2"
3737 [(set (match_operand:SI 0 "register_operand" "=r")
3738 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3740 "movs{bl|x}\t{%1, %0|%0, %1}"
3741 [(set_attr "type" "imovx")
3742 (set_attr "mode" "SI")])
3744 (define_insn "*extendqisi2_zext"
3745 [(set (match_operand:DI 0 "register_operand" "=r")
3747 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3749 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3750 [(set_attr "type" "imovx")
3751 (set_attr "mode" "SI")])
3753 (define_insn "extendqihi2"
3754 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3755 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3758 switch (get_attr_prefix_0f (insn))
3761 return "{cbtw|cbw}";
3763 return "movs{bw|x}\t{%1, %0|%0, %1}";
3766 [(set_attr "type" "imovx")
3767 (set_attr "mode" "HI")
3768 (set (attr "prefix_0f")
3769 ;; movsx is short decodable while cwtl is vector decoded.
3770 (if_then_else (and (eq_attr "cpu" "!k6")
3771 (eq_attr "alternative" "0"))
3773 (const_string "1")))
3775 (if_then_else (eq_attr "prefix_0f" "0")
3777 (const_string "1")))])
3779 ;; Conversions between float and double.
3781 ;; These are all no-ops in the model used for the 80387.
3782 ;; So just emit moves.
3784 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3786 [(set (match_operand:DF 0 "push_operand" "")
3787 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3789 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3790 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3793 [(set (match_operand:XF 0 "push_operand" "")
3794 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3796 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3797 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3798 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3800 (define_expand "extendsfdf2"
3801 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3802 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3803 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3805 /* ??? Needed for compress_float_constant since all fp constants
3806 are TARGET_LEGITIMATE_CONSTANT_P. */
3807 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3809 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3810 && standard_80387_constant_p (operands[1]) > 0)
3812 operands[1] = simplify_const_unary_operation
3813 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3814 emit_move_insn_1 (operands[0], operands[1]);
3817 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3821 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3823 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3825 We do the conversion post reload to avoid producing of 128bit spills
3826 that might lead to ICE on 32bit target. The sequence unlikely combine
3829 [(set (match_operand:DF 0 "register_operand" "")
3831 (match_operand:SF 1 "nonimmediate_operand" "")))]
3832 "TARGET_USE_VECTOR_FP_CONVERTS
3833 && optimize_insn_for_speed_p ()
3834 && reload_completed && SSE_REG_P (operands[0])"
3839 (parallel [(const_int 0) (const_int 1)]))))]
3841 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3842 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3843 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3844 Try to avoid move when unpacking can be done in source. */
3845 if (REG_P (operands[1]))
3847 /* If it is unsafe to overwrite upper half of source, we need
3848 to move to destination and unpack there. */
3849 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3850 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3851 && true_regnum (operands[0]) != true_regnum (operands[1]))
3853 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3854 emit_move_insn (tmp, operands[1]);
3857 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3858 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3862 emit_insn (gen_vec_setv4sf_0 (operands[3],
3863 CONST0_RTX (V4SFmode), operands[1]));
3866 (define_insn "*extendsfdf2_mixed"
3867 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3869 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3870 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3872 switch (which_alternative)
3876 return output_387_reg_move (insn, operands);
3879 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3885 [(set_attr "type" "fmov,fmov,ssecvt")
3886 (set_attr "prefix" "orig,orig,maybe_vex")
3887 (set_attr "mode" "SF,XF,DF")])
3889 (define_insn "*extendsfdf2_sse"
3890 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3891 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3892 "TARGET_SSE2 && TARGET_SSE_MATH"
3893 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3894 [(set_attr "type" "ssecvt")
3895 (set_attr "prefix" "maybe_vex")
3896 (set_attr "mode" "DF")])
3898 (define_insn "*extendsfdf2_i387"
3899 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3900 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3902 "* return output_387_reg_move (insn, operands);"
3903 [(set_attr "type" "fmov")
3904 (set_attr "mode" "SF,XF")])
3906 (define_expand "extend<mode>xf2"
3907 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3908 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3911 /* ??? Needed for compress_float_constant since all fp constants
3912 are TARGET_LEGITIMATE_CONSTANT_P. */
3913 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3915 if (standard_80387_constant_p (operands[1]) > 0)
3917 operands[1] = simplify_const_unary_operation
3918 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3919 emit_move_insn_1 (operands[0], operands[1]);
3922 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3926 (define_insn "*extend<mode>xf2_i387"
3927 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3929 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3931 "* return output_387_reg_move (insn, operands);"
3932 [(set_attr "type" "fmov")
3933 (set_attr "mode" "<MODE>,XF")])
3935 ;; %%% This seems bad bad news.
3936 ;; This cannot output into an f-reg because there is no way to be sure
3937 ;; of truncating in that case. Otherwise this is just like a simple move
3938 ;; insn. So we pretend we can output to a reg in order to get better
3939 ;; register preferencing, but we really use a stack slot.
3941 ;; Conversion from DFmode to SFmode.
3943 (define_expand "truncdfsf2"
3944 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3946 (match_operand:DF 1 "nonimmediate_operand" "")))]
3947 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3949 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3951 else if (flag_unsafe_math_optimizations)
3955 enum ix86_stack_slot slot = (virtuals_instantiated
3958 rtx temp = assign_386_stack_local (SFmode, slot);
3959 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3964 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3966 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3968 We do the conversion post reload to avoid producing of 128bit spills
3969 that might lead to ICE on 32bit target. The sequence unlikely combine
3972 [(set (match_operand:SF 0 "register_operand" "")
3974 (match_operand:DF 1 "nonimmediate_operand" "")))]
3975 "TARGET_USE_VECTOR_FP_CONVERTS
3976 && optimize_insn_for_speed_p ()
3977 && reload_completed && SSE_REG_P (operands[0])"
3980 (float_truncate:V2SF
3984 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3985 operands[3] = CONST0_RTX (V2SFmode);
3986 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3987 /* Use movsd for loading from memory, unpcklpd for registers.
3988 Try to avoid move when unpacking can be done in source, or SSE3
3989 movddup is available. */
3990 if (REG_P (operands[1]))
3993 && true_regnum (operands[0]) != true_regnum (operands[1])
3994 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3995 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3997 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3998 emit_move_insn (tmp, operands[1]);
4001 else if (!TARGET_SSE3)
4002 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4003 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4006 emit_insn (gen_sse2_loadlpd (operands[4],
4007 CONST0_RTX (V2DFmode), operands[1]));
4010 (define_expand "truncdfsf2_with_temp"
4011 [(parallel [(set (match_operand:SF 0 "" "")
4012 (float_truncate:SF (match_operand:DF 1 "" "")))
4013 (clobber (match_operand:SF 2 "" ""))])])
4015 (define_insn "*truncdfsf_fast_mixed"
4016 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4018 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4019 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4021 switch (which_alternative)
4024 return output_387_reg_move (insn, operands);
4026 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4031 [(set_attr "type" "fmov,ssecvt")
4032 (set_attr "prefix" "orig,maybe_vex")
4033 (set_attr "mode" "SF")])
4035 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4036 ;; because nothing we do here is unsafe.
4037 (define_insn "*truncdfsf_fast_sse"
4038 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4040 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4041 "TARGET_SSE2 && TARGET_SSE_MATH"
4042 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4043 [(set_attr "type" "ssecvt")
4044 (set_attr "prefix" "maybe_vex")
4045 (set_attr "mode" "SF")])
4047 (define_insn "*truncdfsf_fast_i387"
4048 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4050 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4051 "TARGET_80387 && flag_unsafe_math_optimizations"
4052 "* return output_387_reg_move (insn, operands);"
4053 [(set_attr "type" "fmov")
4054 (set_attr "mode" "SF")])
4056 (define_insn "*truncdfsf_mixed"
4057 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4059 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4060 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4061 "TARGET_MIX_SSE_I387"
4063 switch (which_alternative)
4066 return output_387_reg_move (insn, operands);
4068 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4074 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075 (set_attr "unit" "*,*,i387,i387,i387")
4076 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077 (set_attr "mode" "SF")])
4079 (define_insn "*truncdfsf_i387"
4080 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4082 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4086 switch (which_alternative)
4089 return output_387_reg_move (insn, operands);
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "unit" "*,i387,i387,i387")
4097 (set_attr "mode" "SF")])
4099 (define_insn "*truncdfsf2_i387_1"
4100 [(set (match_operand:SF 0 "memory_operand" "=m")
4102 (match_operand:DF 1 "register_operand" "f")))]
4104 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105 && !TARGET_MIX_SSE_I387"
4106 "* return output_387_reg_move (insn, operands);"
4107 [(set_attr "type" "fmov")
4108 (set_attr "mode" "SF")])
4111 [(set (match_operand:SF 0 "register_operand" "")
4113 (match_operand:DF 1 "fp_register_operand" "")))
4114 (clobber (match_operand 2 "" ""))]
4116 [(set (match_dup 2) (match_dup 1))
4117 (set (match_dup 0) (match_dup 2))]
4118 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4120 ;; Conversion from XFmode to {SF,DF}mode
4122 (define_expand "truncxf<mode>2"
4123 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124 (float_truncate:MODEF
4125 (match_operand:XF 1 "register_operand" "")))
4126 (clobber (match_dup 2))])]
4129 if (flag_unsafe_math_optimizations)
4131 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133 if (reg != operands[0])
4134 emit_move_insn (operands[0], reg);
4139 enum ix86_stack_slot slot = (virtuals_instantiated
4142 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4146 (define_insn "*truncxfsf2_mixed"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4149 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4150 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4153 gcc_assert (!which_alternative);
4154 return output_387_reg_move (insn, operands);
4156 [(set_attr "type" "fmov,multi,multi,multi")
4157 (set_attr "unit" "*,i387,i387,i387")
4158 (set_attr "mode" "SF")])
4160 (define_insn "*truncxfdf2_mixed"
4161 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4163 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4164 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4167 gcc_assert (!which_alternative);
4168 return output_387_reg_move (insn, operands);
4170 [(set_attr "type" "fmov,multi,multi,multi")
4171 (set_attr "unit" "*,i387,i387,i387")
4172 (set_attr "mode" "DF")])
4174 (define_insn "truncxf<mode>2_i387_noop"
4175 [(set (match_operand:MODEF 0 "register_operand" "=f")
4176 (float_truncate:MODEF
4177 (match_operand:XF 1 "register_operand" "f")))]
4178 "TARGET_80387 && flag_unsafe_math_optimizations"
4179 "* return output_387_reg_move (insn, operands);"
4180 [(set_attr "type" "fmov")
4181 (set_attr "mode" "<MODE>")])
4183 (define_insn "*truncxf<mode>2_i387"
4184 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4185 (float_truncate:MODEF
4186 (match_operand:XF 1 "register_operand" "f")))]
4188 "* return output_387_reg_move (insn, operands);"
4189 [(set_attr "type" "fmov")
4190 (set_attr "mode" "<MODE>")])
4193 [(set (match_operand:MODEF 0 "register_operand" "")
4194 (float_truncate:MODEF
4195 (match_operand:XF 1 "register_operand" "")))
4196 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4197 "TARGET_80387 && reload_completed"
4198 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4199 (set (match_dup 0) (match_dup 2))])
4202 [(set (match_operand:MODEF 0 "memory_operand" "")
4203 (float_truncate:MODEF
4204 (match_operand:XF 1 "register_operand" "")))
4205 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4207 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4209 ;; Signed conversion to DImode.
4211 (define_expand "fix_truncxfdi2"
4212 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4213 (fix:DI (match_operand:XF 1 "register_operand" "")))
4214 (clobber (reg:CC FLAGS_REG))])]
4219 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4224 (define_expand "fix_trunc<mode>di2"
4225 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4226 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4227 (clobber (reg:CC FLAGS_REG))])]
4228 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4231 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4233 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4236 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4238 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4239 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4240 if (out != operands[0])
4241 emit_move_insn (operands[0], out);
4246 ;; Signed conversion to SImode.
4248 (define_expand "fix_truncxfsi2"
4249 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4250 (fix:SI (match_operand:XF 1 "register_operand" "")))
4251 (clobber (reg:CC FLAGS_REG))])]
4256 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4261 (define_expand "fix_trunc<mode>si2"
4262 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4263 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4264 (clobber (reg:CC FLAGS_REG))])]
4265 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4268 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4270 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4273 if (SSE_FLOAT_MODE_P (<MODE>mode))
4275 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4276 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4277 if (out != operands[0])
4278 emit_move_insn (operands[0], out);
4283 ;; Signed conversion to HImode.
4285 (define_expand "fix_trunc<mode>hi2"
4286 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4287 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4288 (clobber (reg:CC FLAGS_REG))])]
4290 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4294 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4299 ;; Unsigned conversion to SImode.
4301 (define_expand "fixuns_trunc<mode>si2"
4303 [(set (match_operand:SI 0 "register_operand" "")
4305 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4307 (clobber (match_scratch:<ssevecmode> 3 ""))
4308 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4309 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4311 enum machine_mode mode = <MODE>mode;
4312 enum machine_mode vecmode = <ssevecmode>mode;
4313 REAL_VALUE_TYPE TWO31r;
4316 if (optimize_insn_for_size_p ())
4319 real_ldexp (&TWO31r, &dconst1, 31);
4320 two31 = const_double_from_real_value (TWO31r, mode);
4321 two31 = ix86_build_const_vector (vecmode, true, two31);
4322 operands[2] = force_reg (vecmode, two31);
4325 (define_insn_and_split "*fixuns_trunc<mode>_1"
4326 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4328 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4329 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4330 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4331 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4332 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4333 && optimize_function_for_speed_p (cfun)"
4335 "&& reload_completed"
4338 ix86_split_convert_uns_si_sse (operands);
4342 ;; Unsigned conversion to HImode.
4343 ;; Without these patterns, we'll try the unsigned SI conversion which
4344 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4346 (define_expand "fixuns_trunc<mode>hi2"
4348 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4349 (set (match_operand:HI 0 "nonimmediate_operand" "")
4350 (subreg:HI (match_dup 2) 0))]
4351 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4352 "operands[2] = gen_reg_rtx (SImode);")
4354 ;; When SSE is available, it is always faster to use it!
4355 (define_insn "fix_trunc<mode>di_sse"
4356 [(set (match_operand:DI 0 "register_operand" "=r,r")
4357 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4358 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4359 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4360 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4361 [(set_attr "type" "sseicvt")
4362 (set_attr "prefix" "maybe_vex")
4363 (set_attr "prefix_rex" "1")
4364 (set_attr "mode" "<MODE>")
4365 (set_attr "athlon_decode" "double,vector")
4366 (set_attr "amdfam10_decode" "double,double")
4367 (set_attr "bdver1_decode" "double,double")])
4369 (define_insn "fix_trunc<mode>si_sse"
4370 [(set (match_operand:SI 0 "register_operand" "=r,r")
4371 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4372 "SSE_FLOAT_MODE_P (<MODE>mode)
4373 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4374 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4375 [(set_attr "type" "sseicvt")
4376 (set_attr "prefix" "maybe_vex")
4377 (set_attr "mode" "<MODE>")
4378 (set_attr "athlon_decode" "double,vector")
4379 (set_attr "amdfam10_decode" "double,double")
4380 (set_attr "bdver1_decode" "double,double")])
4382 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4384 [(set (match_operand:MODEF 0 "register_operand" "")
4385 (match_operand:MODEF 1 "memory_operand" ""))
4386 (set (match_operand:SWI48x 2 "register_operand" "")
4387 (fix:SWI48x (match_dup 0)))]
4388 "TARGET_SHORTEN_X87_SSE
4389 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4390 && peep2_reg_dead_p (2, operands[0])"
4391 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4393 ;; Avoid vector decoded forms of the instruction.
4395 [(match_scratch:DF 2 "Y2")
4396 (set (match_operand:SWI48x 0 "register_operand" "")
4397 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4398 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4399 [(set (match_dup 2) (match_dup 1))
4400 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4403 [(match_scratch:SF 2 "x")
4404 (set (match_operand:SWI48x 0 "register_operand" "")
4405 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4406 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4407 [(set (match_dup 2) (match_dup 1))
4408 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4410 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4411 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4412 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4413 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4415 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4416 && (TARGET_64BIT || <MODE>mode != DImode))
4418 && can_create_pseudo_p ()"
4423 if (memory_operand (operands[0], VOIDmode))
4424 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4427 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4428 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4434 [(set_attr "type" "fisttp")
4435 (set_attr "mode" "<MODE>")])
4437 (define_insn "fix_trunc<mode>_i387_fisttp"
4438 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4439 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4440 (clobber (match_scratch:XF 2 "=&1f"))]
4441 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4443 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && (TARGET_64BIT || <MODE>mode != DImode))
4445 && TARGET_SSE_MATH)"
4446 "* return output_fix_trunc (insn, operands, true);"
4447 [(set_attr "type" "fisttp")
4448 (set_attr "mode" "<MODE>")])
4450 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4451 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4452 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4453 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4454 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4455 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4457 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4458 && (TARGET_64BIT || <MODE>mode != DImode))
4459 && TARGET_SSE_MATH)"
4461 [(set_attr "type" "fisttp")
4462 (set_attr "mode" "<MODE>")])
4465 [(set (match_operand:SWI248x 0 "register_operand" "")
4466 (fix:SWI248x (match_operand 1 "register_operand" "")))
4467 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4468 (clobber (match_scratch 3 ""))]
4470 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4471 (clobber (match_dup 3))])
4472 (set (match_dup 0) (match_dup 2))])
4475 [(set (match_operand:SWI248x 0 "memory_operand" "")
4476 (fix:SWI248x (match_operand 1 "register_operand" "")))
4477 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4478 (clobber (match_scratch 3 ""))]
4480 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4481 (clobber (match_dup 3))])])
4483 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4484 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4485 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4486 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4487 ;; function in i386.c.
4488 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4489 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4490 (fix:SWI248x (match_operand 1 "register_operand" "")))
4491 (clobber (reg:CC FLAGS_REG))]
4492 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4494 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && (TARGET_64BIT || <MODE>mode != DImode))
4496 && can_create_pseudo_p ()"
4501 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4503 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4504 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4505 if (memory_operand (operands[0], VOIDmode))
4506 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4507 operands[2], operands[3]));
4510 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4511 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4512 operands[2], operands[3],
4517 [(set_attr "type" "fistp")
4518 (set_attr "i387_cw" "trunc")
4519 (set_attr "mode" "<MODE>")])
4521 (define_insn "fix_truncdi_i387"
4522 [(set (match_operand:DI 0 "memory_operand" "=m")
4523 (fix:DI (match_operand 1 "register_operand" "f")))
4524 (use (match_operand:HI 2 "memory_operand" "m"))
4525 (use (match_operand:HI 3 "memory_operand" "m"))
4526 (clobber (match_scratch:XF 4 "=&1f"))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4530 "* return output_fix_trunc (insn, operands, false);"
4531 [(set_attr "type" "fistp")
4532 (set_attr "i387_cw" "trunc")
4533 (set_attr "mode" "DI")])
4535 (define_insn "fix_truncdi_i387_with_temp"
4536 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4537 (fix:DI (match_operand 1 "register_operand" "f,f")))
4538 (use (match_operand:HI 2 "memory_operand" "m,m"))
4539 (use (match_operand:HI 3 "memory_operand" "m,m"))
4540 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4541 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4542 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4544 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4546 [(set_attr "type" "fistp")
4547 (set_attr "i387_cw" "trunc")
4548 (set_attr "mode" "DI")])
4551 [(set (match_operand:DI 0 "register_operand" "")
4552 (fix:DI (match_operand 1 "register_operand" "")))
4553 (use (match_operand:HI 2 "memory_operand" ""))
4554 (use (match_operand:HI 3 "memory_operand" ""))
4555 (clobber (match_operand:DI 4 "memory_operand" ""))
4556 (clobber (match_scratch 5 ""))]
4558 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4561 (clobber (match_dup 5))])
4562 (set (match_dup 0) (match_dup 4))])
4565 [(set (match_operand:DI 0 "memory_operand" "")
4566 (fix:DI (match_operand 1 "register_operand" "")))
4567 (use (match_operand:HI 2 "memory_operand" ""))
4568 (use (match_operand:HI 3 "memory_operand" ""))
4569 (clobber (match_operand:DI 4 "memory_operand" ""))
4570 (clobber (match_scratch 5 ""))]
4572 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4575 (clobber (match_dup 5))])])
4577 (define_insn "fix_trunc<mode>_i387"
4578 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4579 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4580 (use (match_operand:HI 2 "memory_operand" "m"))
4581 (use (match_operand:HI 3 "memory_operand" "m"))]
4582 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4585 "* return output_fix_trunc (insn, operands, false);"
4586 [(set_attr "type" "fistp")
4587 (set_attr "i387_cw" "trunc")
4588 (set_attr "mode" "<MODE>")])
4590 (define_insn "fix_trunc<mode>_i387_with_temp"
4591 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4592 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4593 (use (match_operand:HI 2 "memory_operand" "m,m"))
4594 (use (match_operand:HI 3 "memory_operand" "m,m"))
4595 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4596 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4600 [(set_attr "type" "fistp")
4601 (set_attr "i387_cw" "trunc")
4602 (set_attr "mode" "<MODE>")])
4605 [(set (match_operand:SWI24 0 "register_operand" "")
4606 (fix:SWI24 (match_operand 1 "register_operand" "")))
4607 (use (match_operand:HI 2 "memory_operand" ""))
4608 (use (match_operand:HI 3 "memory_operand" ""))
4609 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4611 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4613 (use (match_dup 3))])
4614 (set (match_dup 0) (match_dup 4))])
4617 [(set (match_operand:SWI24 0 "memory_operand" "")
4618 (fix:SWI24 (match_operand 1 "register_operand" "")))
4619 (use (match_operand:HI 2 "memory_operand" ""))
4620 (use (match_operand:HI 3 "memory_operand" ""))
4621 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4623 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4625 (use (match_dup 3))])])
4627 (define_insn "x86_fnstcw_1"
4628 [(set (match_operand:HI 0 "memory_operand" "=m")
4629 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4632 [(set (attr "length")
4633 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4634 (set_attr "mode" "HI")
4635 (set_attr "unit" "i387")
4636 (set_attr "bdver1_decode" "vector")])
4638 (define_insn "x86_fldcw_1"
4639 [(set (reg:HI FPCR_REG)
4640 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4643 [(set (attr "length")
4644 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4645 (set_attr "mode" "HI")
4646 (set_attr "unit" "i387")
4647 (set_attr "athlon_decode" "vector")
4648 (set_attr "amdfam10_decode" "vector")
4649 (set_attr "bdver1_decode" "vector")])
4651 ;; Conversion between fixed point and floating point.
4653 ;; Even though we only accept memory inputs, the backend _really_
4654 ;; wants to be able to do this between registers.
4656 (define_expand "floathi<mode>2"
4657 [(set (match_operand:X87MODEF 0 "register_operand" "")
4658 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4661 || TARGET_MIX_SSE_I387)")
4663 ;; Pre-reload splitter to add memory clobber to the pattern.
4664 (define_insn_and_split "*floathi<mode>2_1"
4665 [(set (match_operand:X87MODEF 0 "register_operand" "")
4666 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4669 || TARGET_MIX_SSE_I387)
4670 && can_create_pseudo_p ()"
4673 [(parallel [(set (match_dup 0)
4674 (float:X87MODEF (match_dup 1)))
4675 (clobber (match_dup 2))])]
4676 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4678 (define_insn "*floathi<mode>2_i387_with_temp"
4679 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4680 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4681 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4684 || TARGET_MIX_SSE_I387)"
4686 [(set_attr "type" "fmov,multi")
4687 (set_attr "mode" "<MODE>")
4688 (set_attr "unit" "*,i387")
4689 (set_attr "fp_int_src" "true")])
4691 (define_insn "*floathi<mode>2_i387"
4692 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4693 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696 || TARGET_MIX_SSE_I387)"
4698 [(set_attr "type" "fmov")
4699 (set_attr "mode" "<MODE>")
4700 (set_attr "fp_int_src" "true")])
4703 [(set (match_operand:X87MODEF 0 "register_operand" "")
4704 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4705 (clobber (match_operand:HI 2 "memory_operand" ""))]
4707 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4708 || TARGET_MIX_SSE_I387)
4709 && reload_completed"
4710 [(set (match_dup 2) (match_dup 1))
4711 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4714 [(set (match_operand:X87MODEF 0 "register_operand" "")
4715 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4716 (clobber (match_operand:HI 2 "memory_operand" ""))]
4718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719 || TARGET_MIX_SSE_I387)
4720 && reload_completed"
4721 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4723 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4724 [(set (match_operand:X87MODEF 0 "register_operand" "")
4726 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4728 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4729 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4731 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4732 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4733 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4735 rtx reg = gen_reg_rtx (XFmode);
4736 rtx (*insn)(rtx, rtx);
4738 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4740 if (<X87MODEF:MODE>mode == SFmode)
4741 insn = gen_truncxfsf2;
4742 else if (<X87MODEF:MODE>mode == DFmode)
4743 insn = gen_truncxfdf2;
4747 emit_insn (insn (operands[0], reg));
4752 ;; Pre-reload splitter to add memory clobber to the pattern.
4753 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4754 [(set (match_operand:X87MODEF 0 "register_operand" "")
4755 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4757 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4758 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4759 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4760 || TARGET_MIX_SSE_I387))
4761 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4762 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4763 && ((<SWI48x:MODE>mode == SImode
4764 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4765 && optimize_function_for_speed_p (cfun)
4766 && flag_trapping_math)
4767 || !(TARGET_INTER_UNIT_CONVERSIONS
4768 || optimize_function_for_size_p (cfun)))))
4769 && can_create_pseudo_p ()"
4772 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4773 (clobber (match_dup 2))])]
4775 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4777 /* Avoid store forwarding (partial memory) stall penalty
4778 by passing DImode value through XMM registers. */
4779 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4780 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4781 && optimize_function_for_speed_p (cfun))
4783 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4790 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4791 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4793 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4794 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4795 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4796 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4798 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4799 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4800 (set_attr "unit" "*,i387,*,*,*")
4801 (set_attr "athlon_decode" "*,*,double,direct,double")
4802 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4803 (set_attr "bdver1_decode" "*,*,double,direct,double")
4804 (set_attr "fp_int_src" "true")])
4806 (define_insn "*floatsi<mode>2_vector_mixed"
4807 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4808 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4809 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4810 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4814 [(set_attr "type" "fmov,sseicvt")
4815 (set_attr "mode" "<MODE>,<ssevecmode>")
4816 (set_attr "unit" "i387,*")
4817 (set_attr "athlon_decode" "*,direct")
4818 (set_attr "amdfam10_decode" "*,double")
4819 (set_attr "bdver1_decode" "*,direct")
4820 (set_attr "fp_int_src" "true")])
4822 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4823 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4825 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4826 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4827 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4828 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4830 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4831 (set_attr "mode" "<MODEF:MODE>")
4832 (set_attr "unit" "*,i387,*,*")
4833 (set_attr "athlon_decode" "*,*,double,direct")
4834 (set_attr "amdfam10_decode" "*,*,vector,double")
4835 (set_attr "bdver1_decode" "*,*,double,direct")
4836 (set_attr "fp_int_src" "true")])
4839 [(set (match_operand:MODEF 0 "register_operand" "")
4840 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4841 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4842 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4843 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4844 && TARGET_INTER_UNIT_CONVERSIONS
4846 && (SSE_REG_P (operands[0])
4847 || (GET_CODE (operands[0]) == SUBREG
4848 && SSE_REG_P (operands[0])))"
4849 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4852 [(set (match_operand:MODEF 0 "register_operand" "")
4853 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4854 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4855 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4856 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4857 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4859 && (SSE_REG_P (operands[0])
4860 || (GET_CODE (operands[0]) == SUBREG
4861 && SSE_REG_P (operands[0])))"
4862 [(set (match_dup 2) (match_dup 1))
4863 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4865 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4866 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4868 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4869 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4870 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4871 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4874 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4875 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4876 [(set_attr "type" "fmov,sseicvt,sseicvt")
4877 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4878 (set_attr "mode" "<MODEF:MODE>")
4879 (set (attr "prefix_rex")
4881 (and (eq_attr "prefix" "maybe_vex")
4882 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4884 (const_string "*")))
4885 (set_attr "unit" "i387,*,*")
4886 (set_attr "athlon_decode" "*,double,direct")
4887 (set_attr "amdfam10_decode" "*,vector,double")
4888 (set_attr "bdver1_decode" "*,double,direct")
4889 (set_attr "fp_int_src" "true")])
4891 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4892 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4894 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4895 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4896 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4897 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4900 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4901 [(set_attr "type" "fmov,sseicvt")
4902 (set_attr "prefix" "orig,maybe_vex")
4903 (set_attr "mode" "<MODEF:MODE>")
4904 (set (attr "prefix_rex")
4906 (and (eq_attr "prefix" "maybe_vex")
4907 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4909 (const_string "*")))
4910 (set_attr "athlon_decode" "*,direct")
4911 (set_attr "amdfam10_decode" "*,double")
4912 (set_attr "bdver1_decode" "*,direct")
4913 (set_attr "fp_int_src" "true")])
4915 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4916 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4918 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4919 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4920 "TARGET_SSE2 && TARGET_SSE_MATH
4921 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4923 [(set_attr "type" "sseicvt")
4924 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4925 (set_attr "athlon_decode" "double,direct,double")
4926 (set_attr "amdfam10_decode" "vector,double,double")
4927 (set_attr "bdver1_decode" "double,direct,double")
4928 (set_attr "fp_int_src" "true")])
4930 (define_insn "*floatsi<mode>2_vector_sse"
4931 [(set (match_operand:MODEF 0 "register_operand" "=x")
4932 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4933 "TARGET_SSE2 && TARGET_SSE_MATH
4934 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4936 [(set_attr "type" "sseicvt")
4937 (set_attr "mode" "<MODE>")
4938 (set_attr "athlon_decode" "direct")
4939 (set_attr "amdfam10_decode" "double")
4940 (set_attr "bdver1_decode" "direct")
4941 (set_attr "fp_int_src" "true")])
4944 [(set (match_operand:MODEF 0 "register_operand" "")
4945 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4946 (clobber (match_operand:SI 2 "memory_operand" ""))]
4947 "TARGET_SSE2 && TARGET_SSE_MATH
4948 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4950 && (SSE_REG_P (operands[0])
4951 || (GET_CODE (operands[0]) == SUBREG
4952 && SSE_REG_P (operands[0])))"
4955 rtx op1 = operands[1];
4957 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4959 if (GET_CODE (op1) == SUBREG)
4960 op1 = SUBREG_REG (op1);
4962 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4964 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4965 emit_insn (gen_sse2_loadld (operands[4],
4966 CONST0_RTX (V4SImode), operands[1]));
4968 /* We can ignore possible trapping value in the
4969 high part of SSE register for non-trapping math. */
4970 else if (SSE_REG_P (op1) && !flag_trapping_math)
4971 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4974 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4975 emit_move_insn (operands[2], operands[1]);
4976 emit_insn (gen_sse2_loadld (operands[4],
4977 CONST0_RTX (V4SImode), operands[2]));
4980 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
4985 [(set (match_operand:MODEF 0 "register_operand" "")
4986 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4987 (clobber (match_operand:SI 2 "memory_operand" ""))]
4988 "TARGET_SSE2 && TARGET_SSE_MATH
4989 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4991 && (SSE_REG_P (operands[0])
4992 || (GET_CODE (operands[0]) == SUBREG
4993 && SSE_REG_P (operands[0])))"
4996 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4998 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5000 emit_insn (gen_sse2_loadld (operands[4],
5001 CONST0_RTX (V4SImode), operands[1]));
5003 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5008 [(set (match_operand:MODEF 0 "register_operand" "")
5009 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5010 "TARGET_SSE2 && TARGET_SSE_MATH
5011 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5013 && (SSE_REG_P (operands[0])
5014 || (GET_CODE (operands[0]) == SUBREG
5015 && SSE_REG_P (operands[0])))"
5018 rtx op1 = operands[1];
5020 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5022 if (GET_CODE (op1) == SUBREG)
5023 op1 = SUBREG_REG (op1);
5025 if (GENERAL_REG_P (op1))
5027 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5028 if (TARGET_INTER_UNIT_MOVES)
5029 emit_insn (gen_sse2_loadld (operands[4],
5030 CONST0_RTX (V4SImode), operands[1]));
5033 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5035 emit_insn (gen_sse2_loadld (operands[4],
5036 CONST0_RTX (V4SImode), operands[5]));
5037 ix86_free_from_memory (GET_MODE (operands[1]));
5040 /* We can ignore possible trapping value in the
5041 high part of SSE register for non-trapping math. */
5042 else if (SSE_REG_P (op1) && !flag_trapping_math)
5043 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5047 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5052 [(set (match_operand:MODEF 0 "register_operand" "")
5053 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5054 "TARGET_SSE2 && TARGET_SSE_MATH
5055 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5057 && (SSE_REG_P (operands[0])
5058 || (GET_CODE (operands[0]) == SUBREG
5059 && SSE_REG_P (operands[0])))"
5062 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5064 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5066 emit_insn (gen_sse2_loadld (operands[4],
5067 CONST0_RTX (V4SImode), operands[1]));
5069 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5073 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5074 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5076 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5077 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5078 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5079 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5081 [(set_attr "type" "sseicvt")
5082 (set_attr "mode" "<MODEF:MODE>")
5083 (set_attr "athlon_decode" "double,direct")
5084 (set_attr "amdfam10_decode" "vector,double")
5085 (set_attr "bdver1_decode" "double,direct")
5086 (set_attr "fp_int_src" "true")])
5088 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5089 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5091 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5092 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5093 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5094 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5095 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5096 [(set_attr "type" "sseicvt")
5097 (set_attr "prefix" "maybe_vex")
5098 (set_attr "mode" "<MODEF:MODE>")
5099 (set (attr "prefix_rex")
5101 (and (eq_attr "prefix" "maybe_vex")
5102 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5104 (const_string "*")))
5105 (set_attr "athlon_decode" "double,direct")
5106 (set_attr "amdfam10_decode" "vector,double")
5107 (set_attr "bdver1_decode" "double,direct")
5108 (set_attr "fp_int_src" "true")])
5111 [(set (match_operand:MODEF 0 "register_operand" "")
5112 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5113 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5114 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5115 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5116 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5118 && (SSE_REG_P (operands[0])
5119 || (GET_CODE (operands[0]) == SUBREG
5120 && SSE_REG_P (operands[0])))"
5121 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5123 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5124 [(set (match_operand:MODEF 0 "register_operand" "=x")
5126 (match_operand:SWI48x 1 "memory_operand" "m")))]
5127 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5128 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5129 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5130 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5131 [(set_attr "type" "sseicvt")
5132 (set_attr "prefix" "maybe_vex")
5133 (set_attr "mode" "<MODEF:MODE>")
5134 (set (attr "prefix_rex")
5136 (and (eq_attr "prefix" "maybe_vex")
5137 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5139 (const_string "*")))
5140 (set_attr "athlon_decode" "direct")
5141 (set_attr "amdfam10_decode" "double")
5142 (set_attr "bdver1_decode" "direct")
5143 (set_attr "fp_int_src" "true")])
5146 [(set (match_operand:MODEF 0 "register_operand" "")
5147 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5148 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5149 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5150 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5151 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5153 && (SSE_REG_P (operands[0])
5154 || (GET_CODE (operands[0]) == SUBREG
5155 && SSE_REG_P (operands[0])))"
5156 [(set (match_dup 2) (match_dup 1))
5157 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5160 [(set (match_operand:MODEF 0 "register_operand" "")
5161 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5162 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5163 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5166 && (SSE_REG_P (operands[0])
5167 || (GET_CODE (operands[0]) == SUBREG
5168 && SSE_REG_P (operands[0])))"
5169 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5171 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5172 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5174 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5175 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5177 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5181 [(set_attr "type" "fmov,multi")
5182 (set_attr "mode" "<X87MODEF:MODE>")
5183 (set_attr "unit" "*,i387")
5184 (set_attr "fp_int_src" "true")])
5186 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5187 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5189 (match_operand:SWI48x 1 "memory_operand" "m")))]
5191 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5193 [(set_attr "type" "fmov")
5194 (set_attr "mode" "<X87MODEF:MODE>")
5195 (set_attr "fp_int_src" "true")])
5198 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5199 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5200 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5202 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5203 && reload_completed"
5204 [(set (match_dup 2) (match_dup 1))
5205 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5208 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5209 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5210 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5212 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5213 && reload_completed"
5214 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5216 ;; Avoid store forwarding (partial memory) stall penalty
5217 ;; by passing DImode value through XMM registers. */
5219 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5220 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5222 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5223 (clobber (match_scratch:V4SI 3 "=X,x"))
5224 (clobber (match_scratch:V4SI 4 "=X,x"))
5225 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5226 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5227 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5228 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5230 [(set_attr "type" "multi")
5231 (set_attr "mode" "<X87MODEF:MODE>")
5232 (set_attr "unit" "i387")
5233 (set_attr "fp_int_src" "true")])
5236 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5237 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5238 (clobber (match_scratch:V4SI 3 ""))
5239 (clobber (match_scratch:V4SI 4 ""))
5240 (clobber (match_operand:DI 2 "memory_operand" ""))]
5241 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5242 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5243 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5244 && reload_completed"
5245 [(set (match_dup 2) (match_dup 3))
5246 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5248 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5249 Assemble the 64-bit DImode value in an xmm register. */
5250 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5251 gen_rtx_SUBREG (SImode, operands[1], 0)));
5252 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5253 gen_rtx_SUBREG (SImode, operands[1], 4)));
5254 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5257 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5261 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5262 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5263 (clobber (match_scratch:V4SI 3 ""))
5264 (clobber (match_scratch:V4SI 4 ""))
5265 (clobber (match_operand:DI 2 "memory_operand" ""))]
5266 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5267 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5268 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5269 && reload_completed"
5270 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5272 ;; Avoid store forwarding (partial memory) stall penalty by extending
5273 ;; SImode value to DImode through XMM register instead of pushing two
5274 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5275 ;; targets benefit from this optimization. Also note that fild
5276 ;; loads from memory only.
5278 (define_insn "*floatunssi<mode>2_1"
5279 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5280 (unsigned_float:X87MODEF
5281 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5282 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5283 (clobber (match_scratch:SI 3 "=X,x"))]
5285 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5288 [(set_attr "type" "multi")
5289 (set_attr "mode" "<MODE>")])
5292 [(set (match_operand:X87MODEF 0 "register_operand" "")
5293 (unsigned_float:X87MODEF
5294 (match_operand:SI 1 "register_operand" "")))
5295 (clobber (match_operand:DI 2 "memory_operand" ""))
5296 (clobber (match_scratch:SI 3 ""))]
5298 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5300 && reload_completed"
5301 [(set (match_dup 2) (match_dup 1))
5303 (float:X87MODEF (match_dup 2)))]
5304 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5307 [(set (match_operand:X87MODEF 0 "register_operand" "")
5308 (unsigned_float:X87MODEF
5309 (match_operand:SI 1 "memory_operand" "")))
5310 (clobber (match_operand:DI 2 "memory_operand" ""))
5311 (clobber (match_scratch:SI 3 ""))]
5313 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5315 && reload_completed"
5316 [(set (match_dup 2) (match_dup 3))
5318 (float:X87MODEF (match_dup 2)))]
5320 emit_move_insn (operands[3], operands[1]);
5321 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5324 (define_expand "floatunssi<mode>2"
5326 [(set (match_operand:X87MODEF 0 "register_operand" "")
5327 (unsigned_float:X87MODEF
5328 (match_operand:SI 1 "nonimmediate_operand" "")))
5329 (clobber (match_dup 2))
5330 (clobber (match_scratch:SI 3 ""))])]
5332 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5334 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5336 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5338 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5343 enum ix86_stack_slot slot = (virtuals_instantiated
5346 operands[2] = assign_386_stack_local (DImode, slot);
5350 (define_expand "floatunsdisf2"
5351 [(use (match_operand:SF 0 "register_operand" ""))
5352 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5353 "TARGET_64BIT && TARGET_SSE_MATH"
5354 "x86_emit_floatuns (operands); DONE;")
5356 (define_expand "floatunsdidf2"
5357 [(use (match_operand:DF 0 "register_operand" ""))
5358 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5359 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5360 && TARGET_SSE2 && TARGET_SSE_MATH"
5363 x86_emit_floatuns (operands);
5365 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5371 (define_expand "add<mode>3"
5372 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5373 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5374 (match_operand:SDWIM 2 "<general_operand>" "")))]
5376 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5378 (define_insn_and_split "*add<dwi>3_doubleword"
5379 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5381 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5382 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5383 (clobber (reg:CC FLAGS_REG))]
5384 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5387 [(parallel [(set (reg:CC FLAGS_REG)
5388 (unspec:CC [(match_dup 1) (match_dup 2)]
5391 (plus:DWIH (match_dup 1) (match_dup 2)))])
5392 (parallel [(set (match_dup 3)
5396 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5398 (clobber (reg:CC FLAGS_REG))])]
5399 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5401 (define_insn "*add<mode>3_cc"
5402 [(set (reg:CC FLAGS_REG)
5404 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5405 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5407 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5408 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5409 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5410 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5411 [(set_attr "type" "alu")
5412 (set_attr "mode" "<MODE>")])
5414 (define_insn "addqi3_cc"
5415 [(set (reg:CC FLAGS_REG)
5417 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5418 (match_operand:QI 2 "general_operand" "qn,qm")]
5420 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5421 (plus:QI (match_dup 1) (match_dup 2)))]
5422 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5423 "add{b}\t{%2, %0|%0, %2}"
5424 [(set_attr "type" "alu")
5425 (set_attr "mode" "QI")])
5427 (define_insn "*lea_1"
5428 [(set (match_operand:SWI48 0 "register_operand" "=r")
5429 (match_operand:SWI48 1 "no_seg_address_operand" "p"))]
5431 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5432 [(set_attr "type" "lea")
5433 (set_attr "mode" "<MODE>")])
5435 (define_insn "*lea_1_zext"
5436 [(set (match_operand:DI 0 "register_operand" "=r")
5438 (match_operand:SI 1 "no_seg_address_operand" "p")))]
5440 "lea{l}\t{%a1, %k0|%k0, %a1}"
5441 [(set_attr "type" "lea")
5442 (set_attr "mode" "SI")])
5444 (define_insn "*lea_2"
5445 [(set (match_operand:SI 0 "register_operand" "=r")
5446 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5448 "lea{l}\t{%a1, %0|%0, %a1}"
5449 [(set_attr "type" "lea")
5450 (set_attr "mode" "SI")])
5452 (define_insn "*lea_2_zext"
5453 [(set (match_operand:DI 0 "register_operand" "=r")
5455 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5457 "lea{l}\t{%a1, %k0|%k0, %a1}"
5458 [(set_attr "type" "lea")
5459 (set_attr "mode" "SI")])
5461 (define_insn "*add<mode>_1"
5462 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5464 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5465 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5466 (clobber (reg:CC FLAGS_REG))]
5467 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5469 switch (get_attr_type (insn))
5475 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5476 if (operands[2] == const1_rtx)
5477 return "inc{<imodesuffix>}\t%0";
5480 gcc_assert (operands[2] == constm1_rtx);
5481 return "dec{<imodesuffix>}\t%0";
5485 /* For most processors, ADD is faster than LEA. This alternative
5486 was added to use ADD as much as possible. */
5487 if (which_alternative == 2)
5490 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5493 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5494 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5495 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5497 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5501 (cond [(eq_attr "alternative" "3")
5502 (const_string "lea")
5503 (match_operand:SWI48 2 "incdec_operand" "")
5504 (const_string "incdec")
5506 (const_string "alu")))
5507 (set (attr "length_immediate")
5509 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5511 (const_string "*")))
5512 (set_attr "mode" "<MODE>")])
5514 ;; It may seem that nonimmediate operand is proper one for operand 1.
5515 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5516 ;; we take care in ix86_binary_operator_ok to not allow two memory
5517 ;; operands so proper swapping will be done in reload. This allow
5518 ;; patterns constructed from addsi_1 to match.
5520 (define_insn "addsi_1_zext"
5521 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5523 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5524 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5525 (clobber (reg:CC FLAGS_REG))]
5526 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5528 switch (get_attr_type (insn))
5534 if (operands[2] == const1_rtx)
5535 return "inc{l}\t%k0";
5538 gcc_assert (operands[2] == constm1_rtx);
5539 return "dec{l}\t%k0";
5543 /* For most processors, ADD is faster than LEA. This alternative
5544 was added to use ADD as much as possible. */
5545 if (which_alternative == 1)
5548 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5551 if (x86_maybe_negate_const_int (&operands[2], SImode))
5552 return "sub{l}\t{%2, %k0|%k0, %2}";
5554 return "add{l}\t{%2, %k0|%k0, %2}";
5558 (cond [(eq_attr "alternative" "2")
5559 (const_string "lea")
5560 (match_operand:SI 2 "incdec_operand" "")
5561 (const_string "incdec")
5563 (const_string "alu")))
5564 (set (attr "length_immediate")
5566 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5568 (const_string "*")))
5569 (set_attr "mode" "SI")])
5571 (define_insn "*addhi_1"
5572 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5573 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5574 (match_operand:HI 2 "general_operand" "rn,rm")))
5575 (clobber (reg:CC FLAGS_REG))]
5576 "TARGET_PARTIAL_REG_STALL
5577 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5579 switch (get_attr_type (insn))
5582 if (operands[2] == const1_rtx)
5583 return "inc{w}\t%0";
5586 gcc_assert (operands[2] == constm1_rtx);
5587 return "dec{w}\t%0";
5591 if (x86_maybe_negate_const_int (&operands[2], HImode))
5592 return "sub{w}\t{%2, %0|%0, %2}";
5594 return "add{w}\t{%2, %0|%0, %2}";
5598 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5599 (const_string "incdec")
5600 (const_string "alu")))
5601 (set (attr "length_immediate")
5603 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5605 (const_string "*")))
5606 (set_attr "mode" "HI")])
5608 (define_insn "*addhi_1_lea"
5609 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5610 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5611 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5612 (clobber (reg:CC FLAGS_REG))]
5613 "!TARGET_PARTIAL_REG_STALL
5614 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5616 switch (get_attr_type (insn))
5622 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5623 if (operands[2] == const1_rtx)
5624 return "inc{w}\t%0";
5627 gcc_assert (operands[2] == constm1_rtx);
5628 return "dec{w}\t%0";
5632 /* For most processors, ADD is faster than LEA. This alternative
5633 was added to use ADD as much as possible. */
5634 if (which_alternative == 2)
5637 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5640 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641 if (x86_maybe_negate_const_int (&operands[2], HImode))
5642 return "sub{w}\t{%2, %0|%0, %2}";
5644 return "add{w}\t{%2, %0|%0, %2}";
5648 (cond [(eq_attr "alternative" "3")
5649 (const_string "lea")
5650 (match_operand:HI 2 "incdec_operand" "")
5651 (const_string "incdec")
5653 (const_string "alu")))
5654 (set (attr "length_immediate")
5656 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5658 (const_string "*")))
5659 (set_attr "mode" "HI,HI,HI,SI")])
5661 ;; %%% Potential partial reg stall on alternative 2. What to do?
5662 (define_insn "*addqi_1"
5663 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5664 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5665 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5666 (clobber (reg:CC FLAGS_REG))]
5667 "TARGET_PARTIAL_REG_STALL
5668 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5670 int widen = (which_alternative == 2);
5671 switch (get_attr_type (insn))
5674 if (operands[2] == const1_rtx)
5675 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5678 gcc_assert (operands[2] == constm1_rtx);
5679 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5683 if (x86_maybe_negate_const_int (&operands[2], QImode))
5686 return "sub{l}\t{%2, %k0|%k0, %2}";
5688 return "sub{b}\t{%2, %0|%0, %2}";
5691 return "add{l}\t{%k2, %k0|%k0, %k2}";
5693 return "add{b}\t{%2, %0|%0, %2}";
5697 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5698 (const_string "incdec")
5699 (const_string "alu")))
5700 (set (attr "length_immediate")
5702 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5704 (const_string "*")))
5705 (set_attr "mode" "QI,QI,SI")])
5707 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5708 (define_insn "*addqi_1_lea"
5709 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5710 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5711 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5712 (clobber (reg:CC FLAGS_REG))]
5713 "!TARGET_PARTIAL_REG_STALL
5714 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5716 int widen = (which_alternative == 3 || which_alternative == 4);
5718 switch (get_attr_type (insn))
5724 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5725 if (operands[2] == const1_rtx)
5726 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5729 gcc_assert (operands[2] == constm1_rtx);
5730 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5734 /* For most processors, ADD is faster than LEA. These alternatives
5735 were added to use ADD as much as possible. */
5736 if (which_alternative == 2 || which_alternative == 4)
5739 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5742 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5743 if (x86_maybe_negate_const_int (&operands[2], QImode))
5746 return "sub{l}\t{%2, %k0|%k0, %2}";
5748 return "sub{b}\t{%2, %0|%0, %2}";
5751 return "add{l}\t{%k2, %k0|%k0, %k2}";
5753 return "add{b}\t{%2, %0|%0, %2}";
5757 (cond [(eq_attr "alternative" "5")
5758 (const_string "lea")
5759 (match_operand:QI 2 "incdec_operand" "")
5760 (const_string "incdec")
5762 (const_string "alu")))
5763 (set (attr "length_immediate")
5765 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5767 (const_string "*")))
5768 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5770 (define_insn "*addqi_1_slp"
5771 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5772 (plus:QI (match_dup 0)
5773 (match_operand:QI 1 "general_operand" "qn,qnm")))
5774 (clobber (reg:CC FLAGS_REG))]
5775 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5776 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5778 switch (get_attr_type (insn))
5781 if (operands[1] == const1_rtx)
5782 return "inc{b}\t%0";
5785 gcc_assert (operands[1] == constm1_rtx);
5786 return "dec{b}\t%0";
5790 if (x86_maybe_negate_const_int (&operands[1], QImode))
5791 return "sub{b}\t{%1, %0|%0, %1}";
5793 return "add{b}\t{%1, %0|%0, %1}";
5797 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5798 (const_string "incdec")
5799 (const_string "alu1")))
5800 (set (attr "memory")
5801 (if_then_else (match_operand 1 "memory_operand" "")
5802 (const_string "load")
5803 (const_string "none")))
5804 (set_attr "mode" "QI")])
5806 ;; Convert add to the lea pattern to avoid flags dependency.
5808 [(set (match_operand:SWI 0 "register_operand" "")
5809 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5810 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5811 (clobber (reg:CC FLAGS_REG))]
5812 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5815 enum machine_mode mode = <MODE>mode;
5818 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5821 operands[0] = gen_lowpart (mode, operands[0]);
5822 operands[1] = gen_lowpart (mode, operands[1]);
5823 operands[2] = gen_lowpart (mode, operands[2]);
5826 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5828 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5832 ;; Convert add to the lea pattern to avoid flags dependency.
5834 [(set (match_operand:DI 0 "register_operand" "")
5836 (plus:SI (match_operand:SI 1 "register_operand" "")
5837 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5838 (clobber (reg:CC FLAGS_REG))]
5839 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5841 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5843 (define_insn "*add<mode>_2"
5844 [(set (reg FLAGS_REG)
5847 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5848 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5850 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5851 (plus:SWI (match_dup 1) (match_dup 2)))]
5852 "ix86_match_ccmode (insn, CCGOCmode)
5853 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5855 switch (get_attr_type (insn))
5858 if (operands[2] == const1_rtx)
5859 return "inc{<imodesuffix>}\t%0";
5862 gcc_assert (operands[2] == constm1_rtx);
5863 return "dec{<imodesuffix>}\t%0";
5867 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5868 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5870 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5874 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5875 (const_string "incdec")
5876 (const_string "alu")))
5877 (set (attr "length_immediate")
5879 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5881 (const_string "*")))
5882 (set_attr "mode" "<MODE>")])
5884 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5885 (define_insn "*addsi_2_zext"
5886 [(set (reg FLAGS_REG)
5888 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5889 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5891 (set (match_operand:DI 0 "register_operand" "=r")
5892 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5893 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5894 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5896 switch (get_attr_type (insn))
5899 if (operands[2] == const1_rtx)
5900 return "inc{l}\t%k0";
5903 gcc_assert (operands[2] == constm1_rtx);
5904 return "dec{l}\t%k0";
5908 if (x86_maybe_negate_const_int (&operands[2], SImode))
5909 return "sub{l}\t{%2, %k0|%k0, %2}";
5911 return "add{l}\t{%2, %k0|%k0, %2}";
5915 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5916 (const_string "incdec")
5917 (const_string "alu")))
5918 (set (attr "length_immediate")
5920 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5922 (const_string "*")))
5923 (set_attr "mode" "SI")])
5925 (define_insn "*add<mode>_3"
5926 [(set (reg FLAGS_REG)
5928 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5929 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5930 (clobber (match_scratch:SWI 0 "=<r>"))]
5931 "ix86_match_ccmode (insn, CCZmode)
5932 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5934 switch (get_attr_type (insn))
5937 if (operands[2] == const1_rtx)
5938 return "inc{<imodesuffix>}\t%0";
5941 gcc_assert (operands[2] == constm1_rtx);
5942 return "dec{<imodesuffix>}\t%0";
5946 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5947 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5949 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5953 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5954 (const_string "incdec")
5955 (const_string "alu")))
5956 (set (attr "length_immediate")
5958 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5960 (const_string "*")))
5961 (set_attr "mode" "<MODE>")])
5963 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5964 (define_insn "*addsi_3_zext"
5965 [(set (reg FLAGS_REG)
5967 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5968 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5969 (set (match_operand:DI 0 "register_operand" "=r")
5970 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5971 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5972 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5974 switch (get_attr_type (insn))
5977 if (operands[2] == const1_rtx)
5978 return "inc{l}\t%k0";
5981 gcc_assert (operands[2] == constm1_rtx);
5982 return "dec{l}\t%k0";
5986 if (x86_maybe_negate_const_int (&operands[2], SImode))
5987 return "sub{l}\t{%2, %k0|%k0, %2}";
5989 return "add{l}\t{%2, %k0|%k0, %2}";
5993 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5994 (const_string "incdec")
5995 (const_string "alu")))
5996 (set (attr "length_immediate")
5998 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6000 (const_string "*")))
6001 (set_attr "mode" "SI")])
6003 ; For comparisons against 1, -1 and 128, we may generate better code
6004 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6005 ; is matched then. We can't accept general immediate, because for
6006 ; case of overflows, the result is messed up.
6007 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6008 ; only for comparisons not depending on it.
6010 (define_insn "*adddi_4"
6011 [(set (reg FLAGS_REG)
6013 (match_operand:DI 1 "nonimmediate_operand" "0")
6014 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6015 (clobber (match_scratch:DI 0 "=rm"))]
6017 && ix86_match_ccmode (insn, CCGCmode)"
6019 switch (get_attr_type (insn))
6022 if (operands[2] == constm1_rtx)
6023 return "inc{q}\t%0";
6026 gcc_assert (operands[2] == const1_rtx);
6027 return "dec{q}\t%0";
6031 if (x86_maybe_negate_const_int (&operands[2], DImode))
6032 return "add{q}\t{%2, %0|%0, %2}";
6034 return "sub{q}\t{%2, %0|%0, %2}";
6038 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6039 (const_string "incdec")
6040 (const_string "alu")))
6041 (set (attr "length_immediate")
6043 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6045 (const_string "*")))
6046 (set_attr "mode" "DI")])
6048 ; For comparisons against 1, -1 and 128, we may generate better code
6049 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6050 ; is matched then. We can't accept general immediate, because for
6051 ; case of overflows, the result is messed up.
6052 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6053 ; only for comparisons not depending on it.
6055 (define_insn "*add<mode>_4"
6056 [(set (reg FLAGS_REG)
6058 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6059 (match_operand:SWI124 2 "const_int_operand" "n")))
6060 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6061 "ix86_match_ccmode (insn, CCGCmode)"
6063 switch (get_attr_type (insn))
6066 if (operands[2] == constm1_rtx)
6067 return "inc{<imodesuffix>}\t%0";
6070 gcc_assert (operands[2] == const1_rtx);
6071 return "dec{<imodesuffix>}\t%0";
6075 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6076 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6078 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6082 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6083 (const_string "incdec")
6084 (const_string "alu")))
6085 (set (attr "length_immediate")
6087 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6089 (const_string "*")))
6090 (set_attr "mode" "<MODE>")])
6092 (define_insn "*add<mode>_5"
6093 [(set (reg FLAGS_REG)
6096 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6097 (match_operand:SWI 2 "<general_operand>" "<g>"))
6099 (clobber (match_scratch:SWI 0 "=<r>"))]
6100 "ix86_match_ccmode (insn, CCGOCmode)
6101 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6103 switch (get_attr_type (insn))
6106 if (operands[2] == const1_rtx)
6107 return "inc{<imodesuffix>}\t%0";
6110 gcc_assert (operands[2] == constm1_rtx);
6111 return "dec{<imodesuffix>}\t%0";
6115 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6116 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6118 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6122 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6123 (const_string "incdec")
6124 (const_string "alu")))
6125 (set (attr "length_immediate")
6127 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6129 (const_string "*")))
6130 (set_attr "mode" "<MODE>")])
6132 (define_insn "*addqi_ext_1_rex64"
6133 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6138 (match_operand 1 "ext_register_operand" "0")
6141 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6142 (clobber (reg:CC FLAGS_REG))]
6145 switch (get_attr_type (insn))
6148 if (operands[2] == const1_rtx)
6149 return "inc{b}\t%h0";
6152 gcc_assert (operands[2] == constm1_rtx);
6153 return "dec{b}\t%h0";
6157 return "add{b}\t{%2, %h0|%h0, %2}";
6161 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6162 (const_string "incdec")
6163 (const_string "alu")))
6164 (set_attr "modrm" "1")
6165 (set_attr "mode" "QI")])
6167 (define_insn "addqi_ext_1"
6168 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6173 (match_operand 1 "ext_register_operand" "0")
6176 (match_operand:QI 2 "general_operand" "Qmn")))
6177 (clobber (reg:CC FLAGS_REG))]
6180 switch (get_attr_type (insn))
6183 if (operands[2] == const1_rtx)
6184 return "inc{b}\t%h0";
6187 gcc_assert (operands[2] == constm1_rtx);
6188 return "dec{b}\t%h0";
6192 return "add{b}\t{%2, %h0|%h0, %2}";
6196 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6197 (const_string "incdec")
6198 (const_string "alu")))
6199 (set_attr "modrm" "1")
6200 (set_attr "mode" "QI")])
6202 (define_insn "*addqi_ext_2"
6203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6208 (match_operand 1 "ext_register_operand" "%0")
6212 (match_operand 2 "ext_register_operand" "Q")
6215 (clobber (reg:CC FLAGS_REG))]
6217 "add{b}\t{%h2, %h0|%h0, %h2}"
6218 [(set_attr "type" "alu")
6219 (set_attr "mode" "QI")])
6221 ;; The lea patterns for modes less than 32 bits need to be matched by
6222 ;; several insns converted to real lea by splitters.
6224 (define_insn_and_split "*lea_general_1"
6225 [(set (match_operand 0 "register_operand" "=r")
6226 (plus (plus (match_operand 1 "index_register_operand" "l")
6227 (match_operand 2 "register_operand" "r"))
6228 (match_operand 3 "immediate_operand" "i")))]
6229 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6230 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6231 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6232 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6233 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6234 || GET_MODE (operands[3]) == VOIDmode)"
6236 "&& reload_completed"
6239 enum machine_mode mode = SImode;
6242 operands[0] = gen_lowpart (mode, operands[0]);
6243 operands[1] = gen_lowpart (mode, operands[1]);
6244 operands[2] = gen_lowpart (mode, operands[2]);
6245 operands[3] = gen_lowpart (mode, operands[3]);
6247 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6250 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6253 [(set_attr "type" "lea")
6254 (set_attr "mode" "SI")])
6256 (define_insn_and_split "*lea_general_2"
6257 [(set (match_operand 0 "register_operand" "=r")
6258 (plus (mult (match_operand 1 "index_register_operand" "l")
6259 (match_operand 2 "const248_operand" "n"))
6260 (match_operand 3 "nonmemory_operand" "ri")))]
6261 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6262 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6263 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6264 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6265 || GET_MODE (operands[3]) == VOIDmode)"
6267 "&& reload_completed"
6270 enum machine_mode mode = SImode;
6273 operands[0] = gen_lowpart (mode, operands[0]);
6274 operands[1] = gen_lowpart (mode, operands[1]);
6275 operands[3] = gen_lowpart (mode, operands[3]);
6277 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6280 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6283 [(set_attr "type" "lea")
6284 (set_attr "mode" "SI")])
6286 (define_insn_and_split "*lea_general_3"
6287 [(set (match_operand 0 "register_operand" "=r")
6288 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6289 (match_operand 2 "const248_operand" "n"))
6290 (match_operand 3 "register_operand" "r"))
6291 (match_operand 4 "immediate_operand" "i")))]
6292 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6293 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6294 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6295 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6297 "&& reload_completed"
6300 enum machine_mode mode = SImode;
6303 operands[0] = gen_lowpart (mode, operands[0]);
6304 operands[1] = gen_lowpart (mode, operands[1]);
6305 operands[3] = gen_lowpart (mode, operands[3]);
6306 operands[4] = gen_lowpart (mode, operands[4]);
6308 pat = gen_rtx_PLUS (mode,
6310 gen_rtx_MULT (mode, operands[1],
6315 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6318 [(set_attr "type" "lea")
6319 (set_attr "mode" "SI")])
6321 (define_insn_and_split "*lea_general_4"
6322 [(set (match_operand 0 "register_operand" "=r")
6324 (match_operand 1 "index_register_operand" "l")
6325 (match_operand 2 "const_int_operand" "n"))
6326 (match_operand 3 "const_int_operand" "n")))]
6327 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6328 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6329 || GET_MODE (operands[0]) == SImode
6330 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6331 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6332 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6333 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6334 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6336 "&& reload_completed"
6339 enum machine_mode mode = GET_MODE (operands[0]);
6342 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6345 operands[0] = gen_lowpart (mode, operands[0]);
6346 operands[1] = gen_lowpart (mode, operands[1]);
6349 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6351 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6352 INTVAL (operands[3]));
6354 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6357 [(set_attr "type" "lea")
6359 (if_then_else (match_operand:DI 0 "" "")
6361 (const_string "SI")))])
6363 ;; Subtract instructions
6365 (define_expand "sub<mode>3"
6366 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6367 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6368 (match_operand:SDWIM 2 "<general_operand>" "")))]
6370 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6372 (define_insn_and_split "*sub<dwi>3_doubleword"
6373 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6375 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6376 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6377 (clobber (reg:CC FLAGS_REG))]
6378 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6381 [(parallel [(set (reg:CC FLAGS_REG)
6382 (compare:CC (match_dup 1) (match_dup 2)))
6384 (minus:DWIH (match_dup 1) (match_dup 2)))])
6385 (parallel [(set (match_dup 3)
6389 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6391 (clobber (reg:CC FLAGS_REG))])]
6392 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6394 (define_insn "*sub<mode>_1"
6395 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6397 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6398 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6399 (clobber (reg:CC FLAGS_REG))]
6400 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6401 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6402 [(set_attr "type" "alu")
6403 (set_attr "mode" "<MODE>")])
6405 (define_insn "*subsi_1_zext"
6406 [(set (match_operand:DI 0 "register_operand" "=r")
6408 (minus:SI (match_operand:SI 1 "register_operand" "0")
6409 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6410 (clobber (reg:CC FLAGS_REG))]
6411 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6412 "sub{l}\t{%2, %k0|%k0, %2}"
6413 [(set_attr "type" "alu")
6414 (set_attr "mode" "SI")])
6416 (define_insn "*subqi_1_slp"
6417 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6418 (minus:QI (match_dup 0)
6419 (match_operand:QI 1 "general_operand" "qn,qm")))
6420 (clobber (reg:CC FLAGS_REG))]
6421 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6422 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6423 "sub{b}\t{%1, %0|%0, %1}"
6424 [(set_attr "type" "alu1")
6425 (set_attr "mode" "QI")])
6427 (define_insn "*sub<mode>_2"
6428 [(set (reg FLAGS_REG)
6431 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6432 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6434 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6435 (minus:SWI (match_dup 1) (match_dup 2)))]
6436 "ix86_match_ccmode (insn, CCGOCmode)
6437 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6438 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6439 [(set_attr "type" "alu")
6440 (set_attr "mode" "<MODE>")])
6442 (define_insn "*subsi_2_zext"
6443 [(set (reg FLAGS_REG)
6445 (minus:SI (match_operand:SI 1 "register_operand" "0")
6446 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6448 (set (match_operand:DI 0 "register_operand" "=r")
6450 (minus:SI (match_dup 1)
6452 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6453 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6454 "sub{l}\t{%2, %k0|%k0, %2}"
6455 [(set_attr "type" "alu")
6456 (set_attr "mode" "SI")])
6458 (define_insn "*sub<mode>_3"
6459 [(set (reg FLAGS_REG)
6460 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6461 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6462 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6463 (minus:SWI (match_dup 1) (match_dup 2)))]
6464 "ix86_match_ccmode (insn, CCmode)
6465 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6466 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "<MODE>")])
6470 (define_insn "*subsi_3_zext"
6471 [(set (reg FLAGS_REG)
6472 (compare (match_operand:SI 1 "register_operand" "0")
6473 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6474 (set (match_operand:DI 0 "register_operand" "=r")
6476 (minus:SI (match_dup 1)
6478 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6479 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6480 "sub{l}\t{%2, %1|%1, %2}"
6481 [(set_attr "type" "alu")
6482 (set_attr "mode" "SI")])
6484 ;; Add with carry and subtract with borrow
6486 (define_expand "<plusminus_insn><mode>3_carry"
6488 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6490 (match_operand:SWI 1 "nonimmediate_operand" "")
6491 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6492 [(match_operand 3 "flags_reg_operand" "")
6494 (match_operand:SWI 2 "<general_operand>" ""))))
6495 (clobber (reg:CC FLAGS_REG))])]
6496 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6498 (define_insn "*<plusminus_insn><mode>3_carry"
6499 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6501 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6503 (match_operator 3 "ix86_carry_flag_operator"
6504 [(reg FLAGS_REG) (const_int 0)])
6505 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6506 (clobber (reg:CC FLAGS_REG))]
6507 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6508 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6509 [(set_attr "type" "alu")
6510 (set_attr "use_carry" "1")
6511 (set_attr "pent_pair" "pu")
6512 (set_attr "mode" "<MODE>")])
6514 (define_insn "*addsi3_carry_zext"
6515 [(set (match_operand:DI 0 "register_operand" "=r")
6517 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6518 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6519 [(reg FLAGS_REG) (const_int 0)])
6520 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6521 (clobber (reg:CC FLAGS_REG))]
6522 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6523 "adc{l}\t{%2, %k0|%k0, %2}"
6524 [(set_attr "type" "alu")
6525 (set_attr "use_carry" "1")
6526 (set_attr "pent_pair" "pu")
6527 (set_attr "mode" "SI")])
6529 (define_insn "*subsi3_carry_zext"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6532 (minus:SI (match_operand:SI 1 "register_operand" "0")
6533 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6534 [(reg FLAGS_REG) (const_int 0)])
6535 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6536 (clobber (reg:CC FLAGS_REG))]
6537 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6538 "sbb{l}\t{%2, %k0|%k0, %2}"
6539 [(set_attr "type" "alu")
6540 (set_attr "pent_pair" "pu")
6541 (set_attr "mode" "SI")])
6543 ;; Overflow setting add and subtract instructions
6545 (define_insn "*add<mode>3_cconly_overflow"
6546 [(set (reg:CCC FLAGS_REG)
6549 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6550 (match_operand:SWI 2 "<general_operand>" "<g>"))
6552 (clobber (match_scratch:SWI 0 "=<r>"))]
6553 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6554 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "<MODE>")])
6558 (define_insn "*sub<mode>3_cconly_overflow"
6559 [(set (reg:CCC FLAGS_REG)
6562 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6563 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6566 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6567 [(set_attr "type" "icmp")
6568 (set_attr "mode" "<MODE>")])
6570 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6571 [(set (reg:CCC FLAGS_REG)
6574 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6575 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6577 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6578 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6579 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6580 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6581 [(set_attr "type" "alu")
6582 (set_attr "mode" "<MODE>")])
6584 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6585 [(set (reg:CCC FLAGS_REG)
6588 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6589 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6591 (set (match_operand:DI 0 "register_operand" "=r")
6592 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6593 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6594 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6595 [(set_attr "type" "alu")
6596 (set_attr "mode" "SI")])
6598 ;; The patterns that match these are at the end of this file.
6600 (define_expand "<plusminus_insn>xf3"
6601 [(set (match_operand:XF 0 "register_operand" "")
6603 (match_operand:XF 1 "register_operand" "")
6604 (match_operand:XF 2 "register_operand" "")))]
6607 (define_expand "<plusminus_insn><mode>3"
6608 [(set (match_operand:MODEF 0 "register_operand" "")
6610 (match_operand:MODEF 1 "register_operand" "")
6611 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6612 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6613 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6615 ;; Multiply instructions
6617 (define_expand "mul<mode>3"
6618 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6620 (match_operand:SWIM248 1 "register_operand" "")
6621 (match_operand:SWIM248 2 "<general_operand>" "")))
6622 (clobber (reg:CC FLAGS_REG))])])
6624 (define_expand "mulqi3"
6625 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6627 (match_operand:QI 1 "register_operand" "")
6628 (match_operand:QI 2 "nonimmediate_operand" "")))
6629 (clobber (reg:CC FLAGS_REG))])]
6630 "TARGET_QIMODE_MATH")
6633 ;; IMUL reg32/64, reg32/64, imm8 Direct
6634 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6635 ;; IMUL reg32/64, reg32/64, imm32 Direct
6636 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6637 ;; IMUL reg32/64, reg32/64 Direct
6638 ;; IMUL reg32/64, mem32/64 Direct
6640 ;; On BDVER1, all above IMULs use DirectPath
6642 (define_insn "*mul<mode>3_1"
6643 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6645 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6646 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6647 (clobber (reg:CC FLAGS_REG))]
6648 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6650 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6651 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6652 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6653 [(set_attr "type" "imul")
6654 (set_attr "prefix_0f" "0,0,1")
6655 (set (attr "athlon_decode")
6656 (cond [(eq_attr "cpu" "athlon")
6657 (const_string "vector")
6658 (eq_attr "alternative" "1")
6659 (const_string "vector")
6660 (and (eq_attr "alternative" "2")
6661 (match_operand 1 "memory_operand" ""))
6662 (const_string "vector")]
6663 (const_string "direct")))
6664 (set (attr "amdfam10_decode")
6665 (cond [(and (eq_attr "alternative" "0,1")
6666 (match_operand 1 "memory_operand" ""))
6667 (const_string "vector")]
6668 (const_string "direct")))
6669 (set_attr "bdver1_decode" "direct")
6670 (set_attr "mode" "<MODE>")])
6672 (define_insn "*mulsi3_1_zext"
6673 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6675 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6676 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6677 (clobber (reg:CC FLAGS_REG))]
6679 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6681 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6682 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6683 imul{l}\t{%2, %k0|%k0, %2}"
6684 [(set_attr "type" "imul")
6685 (set_attr "prefix_0f" "0,0,1")
6686 (set (attr "athlon_decode")
6687 (cond [(eq_attr "cpu" "athlon")
6688 (const_string "vector")
6689 (eq_attr "alternative" "1")
6690 (const_string "vector")
6691 (and (eq_attr "alternative" "2")
6692 (match_operand 1 "memory_operand" ""))
6693 (const_string "vector")]
6694 (const_string "direct")))
6695 (set (attr "amdfam10_decode")
6696 (cond [(and (eq_attr "alternative" "0,1")
6697 (match_operand 1 "memory_operand" ""))
6698 (const_string "vector")]
6699 (const_string "direct")))
6700 (set_attr "bdver1_decode" "direct")
6701 (set_attr "mode" "SI")])
6704 ;; IMUL reg16, reg16, imm8 VectorPath
6705 ;; IMUL reg16, mem16, imm8 VectorPath
6706 ;; IMUL reg16, reg16, imm16 VectorPath
6707 ;; IMUL reg16, mem16, imm16 VectorPath
6708 ;; IMUL reg16, reg16 Direct
6709 ;; IMUL reg16, mem16 Direct
6711 ;; On BDVER1, all HI MULs use DoublePath
6713 (define_insn "*mulhi3_1"
6714 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6715 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6716 (match_operand:HI 2 "general_operand" "K,n,mr")))
6717 (clobber (reg:CC FLAGS_REG))]
6719 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6721 imul{w}\t{%2, %1, %0|%0, %1, %2}
6722 imul{w}\t{%2, %1, %0|%0, %1, %2}
6723 imul{w}\t{%2, %0|%0, %2}"
6724 [(set_attr "type" "imul")
6725 (set_attr "prefix_0f" "0,0,1")
6726 (set (attr "athlon_decode")
6727 (cond [(eq_attr "cpu" "athlon")
6728 (const_string "vector")
6729 (eq_attr "alternative" "1,2")
6730 (const_string "vector")]
6731 (const_string "direct")))
6732 (set (attr "amdfam10_decode")
6733 (cond [(eq_attr "alternative" "0,1")
6734 (const_string "vector")]
6735 (const_string "direct")))
6736 (set_attr "bdver1_decode" "double")
6737 (set_attr "mode" "HI")])
6739 ;;On AMDFAM10 and BDVER1
6743 (define_insn "*mulqi3_1"
6744 [(set (match_operand:QI 0 "register_operand" "=a")
6745 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6746 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6747 (clobber (reg:CC FLAGS_REG))]
6749 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6751 [(set_attr "type" "imul")
6752 (set_attr "length_immediate" "0")
6753 (set (attr "athlon_decode")
6754 (if_then_else (eq_attr "cpu" "athlon")
6755 (const_string "vector")
6756 (const_string "direct")))
6757 (set_attr "amdfam10_decode" "direct")
6758 (set_attr "bdver1_decode" "direct")
6759 (set_attr "mode" "QI")])
6761 (define_expand "<u>mul<mode><dwi>3"
6762 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6765 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6767 (match_operand:DWIH 2 "register_operand" ""))))
6768 (clobber (reg:CC FLAGS_REG))])])
6770 (define_expand "<u>mulqihi3"
6771 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6774 (match_operand:QI 1 "nonimmediate_operand" ""))
6776 (match_operand:QI 2 "register_operand" ""))))
6777 (clobber (reg:CC FLAGS_REG))])]
6778 "TARGET_QIMODE_MATH")
6780 (define_insn "*<u>mul<mode><dwi>3_1"
6781 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6784 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6786 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6787 (clobber (reg:CC FLAGS_REG))]
6788 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6789 "<sgnprefix>mul{<imodesuffix>}\t%2"
6790 [(set_attr "type" "imul")
6791 (set_attr "length_immediate" "0")
6792 (set (attr "athlon_decode")
6793 (if_then_else (eq_attr "cpu" "athlon")
6794 (const_string "vector")
6795 (const_string "double")))
6796 (set_attr "amdfam10_decode" "double")
6797 (set_attr "bdver1_decode" "direct")
6798 (set_attr "mode" "<MODE>")])
6800 (define_insn "*<u>mulqihi3_1"
6801 [(set (match_operand:HI 0 "register_operand" "=a")
6804 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6806 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6807 (clobber (reg:CC FLAGS_REG))]
6809 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6810 "<sgnprefix>mul{b}\t%2"
6811 [(set_attr "type" "imul")
6812 (set_attr "length_immediate" "0")
6813 (set (attr "athlon_decode")
6814 (if_then_else (eq_attr "cpu" "athlon")
6815 (const_string "vector")
6816 (const_string "direct")))
6817 (set_attr "amdfam10_decode" "direct")
6818 (set_attr "bdver1_decode" "direct")
6819 (set_attr "mode" "QI")])
6821 (define_expand "<s>mul<mode>3_highpart"
6822 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6827 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6829 (match_operand:SWI48 2 "register_operand" "")))
6831 (clobber (match_scratch:SWI48 3 ""))
6832 (clobber (reg:CC FLAGS_REG))])]
6834 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6836 (define_insn "*<s>muldi3_highpart_1"
6837 [(set (match_operand:DI 0 "register_operand" "=d")
6842 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6844 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6846 (clobber (match_scratch:DI 3 "=1"))
6847 (clobber (reg:CC FLAGS_REG))]
6849 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6850 "<sgnprefix>mul{q}\t%2"
6851 [(set_attr "type" "imul")
6852 (set_attr "length_immediate" "0")
6853 (set (attr "athlon_decode")
6854 (if_then_else (eq_attr "cpu" "athlon")
6855 (const_string "vector")
6856 (const_string "double")))
6857 (set_attr "amdfam10_decode" "double")
6858 (set_attr "bdver1_decode" "direct")
6859 (set_attr "mode" "DI")])
6861 (define_insn "*<s>mulsi3_highpart_1"
6862 [(set (match_operand:SI 0 "register_operand" "=d")
6867 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6869 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6871 (clobber (match_scratch:SI 3 "=1"))
6872 (clobber (reg:CC FLAGS_REG))]
6873 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6874 "<sgnprefix>mul{l}\t%2"
6875 [(set_attr "type" "imul")
6876 (set_attr "length_immediate" "0")
6877 (set (attr "athlon_decode")
6878 (if_then_else (eq_attr "cpu" "athlon")
6879 (const_string "vector")
6880 (const_string "double")))
6881 (set_attr "amdfam10_decode" "double")
6882 (set_attr "bdver1_decode" "direct")
6883 (set_attr "mode" "SI")])
6885 (define_insn "*<s>mulsi3_highpart_zext"
6886 [(set (match_operand:DI 0 "register_operand" "=d")
6887 (zero_extend:DI (truncate:SI
6889 (mult:DI (any_extend:DI
6890 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6892 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6894 (clobber (match_scratch:SI 3 "=1"))
6895 (clobber (reg:CC FLAGS_REG))]
6897 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6898 "<sgnprefix>mul{l}\t%2"
6899 [(set_attr "type" "imul")
6900 (set_attr "length_immediate" "0")
6901 (set (attr "athlon_decode")
6902 (if_then_else (eq_attr "cpu" "athlon")
6903 (const_string "vector")
6904 (const_string "double")))
6905 (set_attr "amdfam10_decode" "double")
6906 (set_attr "bdver1_decode" "direct")
6907 (set_attr "mode" "SI")])
6909 ;; The patterns that match these are at the end of this file.
6911 (define_expand "mulxf3"
6912 [(set (match_operand:XF 0 "register_operand" "")
6913 (mult:XF (match_operand:XF 1 "register_operand" "")
6914 (match_operand:XF 2 "register_operand" "")))]
6917 (define_expand "mul<mode>3"
6918 [(set (match_operand:MODEF 0 "register_operand" "")
6919 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6920 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6921 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6922 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6924 ;; Divide instructions
6926 ;; The patterns that match these are at the end of this file.
6928 (define_expand "divxf3"
6929 [(set (match_operand:XF 0 "register_operand" "")
6930 (div:XF (match_operand:XF 1 "register_operand" "")
6931 (match_operand:XF 2 "register_operand" "")))]
6934 (define_expand "divdf3"
6935 [(set (match_operand:DF 0 "register_operand" "")
6936 (div:DF (match_operand:DF 1 "register_operand" "")
6937 (match_operand:DF 2 "nonimmediate_operand" "")))]
6938 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6939 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6941 (define_expand "divsf3"
6942 [(set (match_operand:SF 0 "register_operand" "")
6943 (div:SF (match_operand:SF 1 "register_operand" "")
6944 (match_operand:SF 2 "nonimmediate_operand" "")))]
6945 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6948 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
6949 && flag_finite_math_only && !flag_trapping_math
6950 && flag_unsafe_math_optimizations)
6952 ix86_emit_swdivsf (operands[0], operands[1],
6953 operands[2], SFmode);
6958 ;; Divmod instructions.
6960 (define_expand "divmod<mode>4"
6961 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6963 (match_operand:SWIM248 1 "register_operand" "")
6964 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
6965 (set (match_operand:SWIM248 3 "register_operand" "")
6966 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6967 (clobber (reg:CC FLAGS_REG))])])
6969 ;; Split with 8bit unsigned divide:
6970 ;; if (dividend an divisor are in [0-255])
6971 ;; use 8bit unsigned integer divide
6973 ;; use original integer divide
6975 [(set (match_operand:SWI48 0 "register_operand" "")
6976 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
6977 (match_operand:SWI48 3 "nonimmediate_operand" "")))
6978 (set (match_operand:SWI48 1 "register_operand" "")
6979 (mod:SWI48 (match_dup 2) (match_dup 3)))
6980 (clobber (reg:CC FLAGS_REG))]
6981 "TARGET_USE_8BIT_IDIV
6982 && TARGET_QIMODE_MATH
6983 && can_create_pseudo_p ()
6984 && !optimize_insn_for_size_p ()"
6986 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6988 (define_insn_and_split "divmod<mode>4_1"
6989 [(set (match_operand:SWI48 0 "register_operand" "=a")
6990 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6991 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6992 (set (match_operand:SWI48 1 "register_operand" "=&d")
6993 (mod:SWI48 (match_dup 2) (match_dup 3)))
6994 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6995 (clobber (reg:CC FLAGS_REG))]
6999 [(parallel [(set (match_dup 1)
7000 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7001 (clobber (reg:CC FLAGS_REG))])
7002 (parallel [(set (match_dup 0)
7003 (div:SWI48 (match_dup 2) (match_dup 3)))
7005 (mod:SWI48 (match_dup 2) (match_dup 3)))
7007 (clobber (reg:CC FLAGS_REG))])]
7009 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7011 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7012 operands[4] = operands[2];
7015 /* Avoid use of cltd in favor of a mov+shift. */
7016 emit_move_insn (operands[1], operands[2]);
7017 operands[4] = operands[1];
7020 [(set_attr "type" "multi")
7021 (set_attr "mode" "<MODE>")])
7023 (define_insn_and_split "*divmod<mode>4"
7024 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7025 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7026 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7027 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7028 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7029 (clobber (reg:CC FLAGS_REG))]
7033 [(parallel [(set (match_dup 1)
7034 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7035 (clobber (reg:CC FLAGS_REG))])
7036 (parallel [(set (match_dup 0)
7037 (div:SWIM248 (match_dup 2) (match_dup 3)))
7039 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7041 (clobber (reg:CC FLAGS_REG))])]
7043 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7045 if (<MODE>mode != HImode
7046 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7047 operands[4] = operands[2];
7050 /* Avoid use of cltd in favor of a mov+shift. */
7051 emit_move_insn (operands[1], operands[2]);
7052 operands[4] = operands[1];
7055 [(set_attr "type" "multi")
7056 (set_attr "mode" "<MODE>")])
7058 (define_insn "*divmod<mode>4_noext"
7059 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7060 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7061 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7062 (set (match_operand:SWIM248 1 "register_operand" "=d")
7063 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7064 (use (match_operand:SWIM248 4 "register_operand" "1"))
7065 (clobber (reg:CC FLAGS_REG))]
7067 "idiv{<imodesuffix>}\t%3"
7068 [(set_attr "type" "idiv")
7069 (set_attr "mode" "<MODE>")])
7071 (define_expand "divmodqi4"
7072 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7074 (match_operand:QI 1 "register_operand" "")
7075 (match_operand:QI 2 "nonimmediate_operand" "")))
7076 (set (match_operand:QI 3 "register_operand" "")
7077 (mod:QI (match_dup 1) (match_dup 2)))
7078 (clobber (reg:CC FLAGS_REG))])]
7079 "TARGET_QIMODE_MATH"
7084 tmp0 = gen_reg_rtx (HImode);
7085 tmp1 = gen_reg_rtx (HImode);
7087 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7089 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7090 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7092 /* Extract remainder from AH. */
7093 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7094 insn = emit_move_insn (operands[3], tmp1);
7096 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7097 set_unique_reg_note (insn, REG_EQUAL, mod);
7099 /* Extract quotient from AL. */
7100 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7102 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7103 set_unique_reg_note (insn, REG_EQUAL, div);
7108 ;; Divide AX by r/m8, with result stored in
7111 ;; Change div/mod to HImode and extend the second argument to HImode
7112 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7113 ;; combine may fail.
7114 (define_insn "divmodhiqi3"
7115 [(set (match_operand:HI 0 "register_operand" "=a")
7120 (mod:HI (match_operand:HI 1 "register_operand" "0")
7122 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7126 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7127 (clobber (reg:CC FLAGS_REG))]
7128 "TARGET_QIMODE_MATH"
7130 [(set_attr "type" "idiv")
7131 (set_attr "mode" "QI")])
7133 (define_expand "udivmod<mode>4"
7134 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7136 (match_operand:SWIM248 1 "register_operand" "")
7137 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7138 (set (match_operand:SWIM248 3 "register_operand" "")
7139 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7140 (clobber (reg:CC FLAGS_REG))])])
7142 ;; Split with 8bit unsigned divide:
7143 ;; if (dividend an divisor are in [0-255])
7144 ;; use 8bit unsigned integer divide
7146 ;; use original integer divide
7148 [(set (match_operand:SWI48 0 "register_operand" "")
7149 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7150 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7151 (set (match_operand:SWI48 1 "register_operand" "")
7152 (umod:SWI48 (match_dup 2) (match_dup 3)))
7153 (clobber (reg:CC FLAGS_REG))]
7154 "TARGET_USE_8BIT_IDIV
7155 && TARGET_QIMODE_MATH
7156 && can_create_pseudo_p ()
7157 && !optimize_insn_for_size_p ()"
7159 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7161 (define_insn_and_split "udivmod<mode>4_1"
7162 [(set (match_operand:SWI48 0 "register_operand" "=a")
7163 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7164 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7165 (set (match_operand:SWI48 1 "register_operand" "=&d")
7166 (umod:SWI48 (match_dup 2) (match_dup 3)))
7167 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7168 (clobber (reg:CC FLAGS_REG))]
7172 [(set (match_dup 1) (const_int 0))
7173 (parallel [(set (match_dup 0)
7174 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7176 (umod:SWI48 (match_dup 2) (match_dup 3)))
7178 (clobber (reg:CC FLAGS_REG))])]
7180 [(set_attr "type" "multi")
7181 (set_attr "mode" "<MODE>")])
7183 (define_insn_and_split "*udivmod<mode>4"
7184 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7185 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7186 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7187 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7188 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7189 (clobber (reg:CC FLAGS_REG))]
7193 [(set (match_dup 1) (const_int 0))
7194 (parallel [(set (match_dup 0)
7195 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7197 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7199 (clobber (reg:CC FLAGS_REG))])]
7201 [(set_attr "type" "multi")
7202 (set_attr "mode" "<MODE>")])
7204 (define_insn "*udivmod<mode>4_noext"
7205 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7206 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7207 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7208 (set (match_operand:SWIM248 1 "register_operand" "=d")
7209 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7210 (use (match_operand:SWIM248 4 "register_operand" "1"))
7211 (clobber (reg:CC FLAGS_REG))]
7213 "div{<imodesuffix>}\t%3"
7214 [(set_attr "type" "idiv")
7215 (set_attr "mode" "<MODE>")])
7217 (define_expand "udivmodqi4"
7218 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7220 (match_operand:QI 1 "register_operand" "")
7221 (match_operand:QI 2 "nonimmediate_operand" "")))
7222 (set (match_operand:QI 3 "register_operand" "")
7223 (umod:QI (match_dup 1) (match_dup 2)))
7224 (clobber (reg:CC FLAGS_REG))])]
7225 "TARGET_QIMODE_MATH"
7230 tmp0 = gen_reg_rtx (HImode);
7231 tmp1 = gen_reg_rtx (HImode);
7233 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7235 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7236 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7238 /* Extract remainder from AH. */
7239 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7240 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7241 insn = emit_move_insn (operands[3], tmp1);
7243 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7244 set_unique_reg_note (insn, REG_EQUAL, mod);
7246 /* Extract quotient from AL. */
7247 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7249 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7250 set_unique_reg_note (insn, REG_EQUAL, div);
7255 (define_insn "udivmodhiqi3"
7256 [(set (match_operand:HI 0 "register_operand" "=a")
7261 (mod:HI (match_operand:HI 1 "register_operand" "0")
7263 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7267 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7268 (clobber (reg:CC FLAGS_REG))]
7269 "TARGET_QIMODE_MATH"
7271 [(set_attr "type" "idiv")
7272 (set_attr "mode" "QI")])
7274 ;; We cannot use div/idiv for double division, because it causes
7275 ;; "division by zero" on the overflow and that's not what we expect
7276 ;; from truncate. Because true (non truncating) double division is
7277 ;; never generated, we can't create this insn anyway.
7280 ; [(set (match_operand:SI 0 "register_operand" "=a")
7282 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7284 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7285 ; (set (match_operand:SI 3 "register_operand" "=d")
7287 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7288 ; (clobber (reg:CC FLAGS_REG))]
7290 ; "div{l}\t{%2, %0|%0, %2}"
7291 ; [(set_attr "type" "idiv")])
7293 ;;- Logical AND instructions
7295 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7296 ;; Note that this excludes ah.
7298 (define_expand "testsi_ccno_1"
7299 [(set (reg:CCNO FLAGS_REG)
7301 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7302 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7305 (define_expand "testqi_ccz_1"
7306 [(set (reg:CCZ FLAGS_REG)
7307 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7308 (match_operand:QI 1 "nonmemory_operand" ""))
7311 (define_expand "testdi_ccno_1"
7312 [(set (reg:CCNO FLAGS_REG)
7314 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7315 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7317 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7319 (define_insn "*testdi_1"
7320 [(set (reg FLAGS_REG)
7323 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7324 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7326 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7327 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7329 test{l}\t{%k1, %k0|%k0, %k1}
7330 test{l}\t{%k1, %k0|%k0, %k1}
7331 test{q}\t{%1, %0|%0, %1}
7332 test{q}\t{%1, %0|%0, %1}
7333 test{q}\t{%1, %0|%0, %1}"
7334 [(set_attr "type" "test")
7335 (set_attr "modrm" "0,1,0,1,1")
7336 (set_attr "mode" "SI,SI,DI,DI,DI")])
7338 (define_insn "*testqi_1_maybe_si"
7339 [(set (reg FLAGS_REG)
7342 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7343 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7345 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7346 && ix86_match_ccmode (insn,
7347 CONST_INT_P (operands[1])
7348 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7350 if (which_alternative == 3)
7352 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7353 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7354 return "test{l}\t{%1, %k0|%k0, %1}";
7356 return "test{b}\t{%1, %0|%0, %1}";
7358 [(set_attr "type" "test")
7359 (set_attr "modrm" "0,1,1,1")
7360 (set_attr "mode" "QI,QI,QI,SI")
7361 (set_attr "pent_pair" "uv,np,uv,np")])
7363 (define_insn "*test<mode>_1"
7364 [(set (reg FLAGS_REG)
7367 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7368 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7370 "ix86_match_ccmode (insn, CCNOmode)
7371 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7372 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7373 [(set_attr "type" "test")
7374 (set_attr "modrm" "0,1,1")
7375 (set_attr "mode" "<MODE>")
7376 (set_attr "pent_pair" "uv,np,uv")])
7378 (define_expand "testqi_ext_ccno_0"
7379 [(set (reg:CCNO FLAGS_REG)
7383 (match_operand 0 "ext_register_operand" "")
7386 (match_operand 1 "const_int_operand" ""))
7389 (define_insn "*testqi_ext_0"
7390 [(set (reg FLAGS_REG)
7394 (match_operand 0 "ext_register_operand" "Q")
7397 (match_operand 1 "const_int_operand" "n"))
7399 "ix86_match_ccmode (insn, CCNOmode)"
7400 "test{b}\t{%1, %h0|%h0, %1}"
7401 [(set_attr "type" "test")
7402 (set_attr "mode" "QI")
7403 (set_attr "length_immediate" "1")
7404 (set_attr "modrm" "1")
7405 (set_attr "pent_pair" "np")])
7407 (define_insn "*testqi_ext_1_rex64"
7408 [(set (reg FLAGS_REG)
7412 (match_operand 0 "ext_register_operand" "Q")
7416 (match_operand:QI 1 "register_operand" "Q")))
7418 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7419 "test{b}\t{%1, %h0|%h0, %1}"
7420 [(set_attr "type" "test")
7421 (set_attr "mode" "QI")])
7423 (define_insn "*testqi_ext_1"
7424 [(set (reg FLAGS_REG)
7428 (match_operand 0 "ext_register_operand" "Q")
7432 (match_operand:QI 1 "general_operand" "Qm")))
7434 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7435 "test{b}\t{%1, %h0|%h0, %1}"
7436 [(set_attr "type" "test")
7437 (set_attr "mode" "QI")])
7439 (define_insn "*testqi_ext_2"
7440 [(set (reg FLAGS_REG)
7444 (match_operand 0 "ext_register_operand" "Q")
7448 (match_operand 1 "ext_register_operand" "Q")
7452 "ix86_match_ccmode (insn, CCNOmode)"
7453 "test{b}\t{%h1, %h0|%h0, %h1}"
7454 [(set_attr "type" "test")
7455 (set_attr "mode" "QI")])
7457 (define_insn "*testqi_ext_3_rex64"
7458 [(set (reg FLAGS_REG)
7459 (compare (zero_extract:DI
7460 (match_operand 0 "nonimmediate_operand" "rm")
7461 (match_operand:DI 1 "const_int_operand" "")
7462 (match_operand:DI 2 "const_int_operand" ""))
7465 && ix86_match_ccmode (insn, CCNOmode)
7466 && INTVAL (operands[1]) > 0
7467 && INTVAL (operands[2]) >= 0
7468 /* Ensure that resulting mask is zero or sign extended operand. */
7469 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7470 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7471 && INTVAL (operands[1]) > 32))
7472 && (GET_MODE (operands[0]) == SImode
7473 || GET_MODE (operands[0]) == DImode
7474 || GET_MODE (operands[0]) == HImode
7475 || GET_MODE (operands[0]) == QImode)"
7478 ;; Combine likes to form bit extractions for some tests. Humor it.
7479 (define_insn "*testqi_ext_3"
7480 [(set (reg FLAGS_REG)
7481 (compare (zero_extract:SI
7482 (match_operand 0 "nonimmediate_operand" "rm")
7483 (match_operand:SI 1 "const_int_operand" "")
7484 (match_operand:SI 2 "const_int_operand" ""))
7486 "ix86_match_ccmode (insn, CCNOmode)
7487 && INTVAL (operands[1]) > 0
7488 && INTVAL (operands[2]) >= 0
7489 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7490 && (GET_MODE (operands[0]) == SImode
7491 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7492 || GET_MODE (operands[0]) == HImode
7493 || GET_MODE (operands[0]) == QImode)"
7497 [(set (match_operand 0 "flags_reg_operand" "")
7498 (match_operator 1 "compare_operator"
7500 (match_operand 2 "nonimmediate_operand" "")
7501 (match_operand 3 "const_int_operand" "")
7502 (match_operand 4 "const_int_operand" ""))
7504 "ix86_match_ccmode (insn, CCNOmode)"
7505 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7507 rtx val = operands[2];
7508 HOST_WIDE_INT len = INTVAL (operands[3]);
7509 HOST_WIDE_INT pos = INTVAL (operands[4]);
7511 enum machine_mode mode, submode;
7513 mode = GET_MODE (val);
7516 /* ??? Combine likes to put non-volatile mem extractions in QImode
7517 no matter the size of the test. So find a mode that works. */
7518 if (! MEM_VOLATILE_P (val))
7520 mode = smallest_mode_for_size (pos + len, MODE_INT);
7521 val = adjust_address (val, mode, 0);
7524 else if (GET_CODE (val) == SUBREG
7525 && (submode = GET_MODE (SUBREG_REG (val)),
7526 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7527 && pos + len <= GET_MODE_BITSIZE (submode)
7528 && GET_MODE_CLASS (submode) == MODE_INT)
7530 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7532 val = SUBREG_REG (val);
7534 else if (mode == HImode && pos + len <= 8)
7536 /* Small HImode tests can be converted to QImode. */
7538 val = gen_lowpart (QImode, val);
7541 if (len == HOST_BITS_PER_WIDE_INT)
7544 mask = ((HOST_WIDE_INT)1 << len) - 1;
7547 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7550 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7551 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7552 ;; this is relatively important trick.
7553 ;; Do the conversion only post-reload to avoid limiting of the register class
7556 [(set (match_operand 0 "flags_reg_operand" "")
7557 (match_operator 1 "compare_operator"
7558 [(and (match_operand 2 "register_operand" "")
7559 (match_operand 3 "const_int_operand" ""))
7562 && QI_REG_P (operands[2])
7563 && GET_MODE (operands[2]) != QImode
7564 && ((ix86_match_ccmode (insn, CCZmode)
7565 && !(INTVAL (operands[3]) & ~(255 << 8)))
7566 || (ix86_match_ccmode (insn, CCNOmode)
7567 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7570 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7573 "operands[2] = gen_lowpart (SImode, operands[2]);
7574 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7577 [(set (match_operand 0 "flags_reg_operand" "")
7578 (match_operator 1 "compare_operator"
7579 [(and (match_operand 2 "nonimmediate_operand" "")
7580 (match_operand 3 "const_int_operand" ""))
7583 && GET_MODE (operands[2]) != QImode
7584 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7585 && ((ix86_match_ccmode (insn, CCZmode)
7586 && !(INTVAL (operands[3]) & ~255))
7587 || (ix86_match_ccmode (insn, CCNOmode)
7588 && !(INTVAL (operands[3]) & ~127)))"
7590 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7592 "operands[2] = gen_lowpart (QImode, operands[2]);
7593 operands[3] = gen_lowpart (QImode, operands[3]);")
7595 ;; %%% This used to optimize known byte-wide and operations to memory,
7596 ;; and sometimes to QImode registers. If this is considered useful,
7597 ;; it should be done with splitters.
7599 (define_expand "and<mode>3"
7600 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7601 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7602 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7604 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7606 (define_insn "*anddi_1"
7607 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7609 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7610 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7611 (clobber (reg:CC FLAGS_REG))]
7612 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7614 switch (get_attr_type (insn))
7618 enum machine_mode mode;
7620 gcc_assert (CONST_INT_P (operands[2]));
7621 if (INTVAL (operands[2]) == 0xff)
7625 gcc_assert (INTVAL (operands[2]) == 0xffff);
7629 operands[1] = gen_lowpart (mode, operands[1]);
7631 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7633 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7637 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7638 if (get_attr_mode (insn) == MODE_SI)
7639 return "and{l}\t{%k2, %k0|%k0, %k2}";
7641 return "and{q}\t{%2, %0|%0, %2}";
7644 [(set_attr "type" "alu,alu,alu,imovx")
7645 (set_attr "length_immediate" "*,*,*,0")
7646 (set (attr "prefix_rex")
7648 (and (eq_attr "type" "imovx")
7649 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7650 (match_operand 1 "ext_QIreg_operand" "")))
7652 (const_string "*")))
7653 (set_attr "mode" "SI,DI,DI,SI")])
7655 (define_insn "*andsi_1"
7656 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7657 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7658 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7659 (clobber (reg:CC FLAGS_REG))]
7660 "ix86_binary_operator_ok (AND, SImode, operands)"
7662 switch (get_attr_type (insn))
7666 enum machine_mode mode;
7668 gcc_assert (CONST_INT_P (operands[2]));
7669 if (INTVAL (operands[2]) == 0xff)
7673 gcc_assert (INTVAL (operands[2]) == 0xffff);
7677 operands[1] = gen_lowpart (mode, operands[1]);
7679 return "movz{bl|x}\t{%1, %0|%0, %1}";
7681 return "movz{wl|x}\t{%1, %0|%0, %1}";
7685 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7686 return "and{l}\t{%2, %0|%0, %2}";
7689 [(set_attr "type" "alu,alu,imovx")
7690 (set (attr "prefix_rex")
7692 (and (eq_attr "type" "imovx")
7693 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7694 (match_operand 1 "ext_QIreg_operand" "")))
7696 (const_string "*")))
7697 (set_attr "length_immediate" "*,*,0")
7698 (set_attr "mode" "SI")])
7700 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7701 (define_insn "*andsi_1_zext"
7702 [(set (match_operand:DI 0 "register_operand" "=r")
7704 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7705 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7706 (clobber (reg:CC FLAGS_REG))]
7707 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7708 "and{l}\t{%2, %k0|%k0, %2}"
7709 [(set_attr "type" "alu")
7710 (set_attr "mode" "SI")])
7712 (define_insn "*andhi_1"
7713 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7714 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7715 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7716 (clobber (reg:CC FLAGS_REG))]
7717 "ix86_binary_operator_ok (AND, HImode, operands)"
7719 switch (get_attr_type (insn))
7722 gcc_assert (CONST_INT_P (operands[2]));
7723 gcc_assert (INTVAL (operands[2]) == 0xff);
7724 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7727 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7729 return "and{w}\t{%2, %0|%0, %2}";
7732 [(set_attr "type" "alu,alu,imovx")
7733 (set_attr "length_immediate" "*,*,0")
7734 (set (attr "prefix_rex")
7736 (and (eq_attr "type" "imovx")
7737 (match_operand 1 "ext_QIreg_operand" ""))
7739 (const_string "*")))
7740 (set_attr "mode" "HI,HI,SI")])
7742 ;; %%% Potential partial reg stall on alternative 2. What to do?
7743 (define_insn "*andqi_1"
7744 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7745 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7746 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7747 (clobber (reg:CC FLAGS_REG))]
7748 "ix86_binary_operator_ok (AND, QImode, operands)"
7750 and{b}\t{%2, %0|%0, %2}
7751 and{b}\t{%2, %0|%0, %2}
7752 and{l}\t{%k2, %k0|%k0, %k2}"
7753 [(set_attr "type" "alu")
7754 (set_attr "mode" "QI,QI,SI")])
7756 (define_insn "*andqi_1_slp"
7757 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7758 (and:QI (match_dup 0)
7759 (match_operand:QI 1 "general_operand" "qn,qmn")))
7760 (clobber (reg:CC FLAGS_REG))]
7761 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7762 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7763 "and{b}\t{%1, %0|%0, %1}"
7764 [(set_attr "type" "alu1")
7765 (set_attr "mode" "QI")])
7768 [(set (match_operand 0 "register_operand" "")
7770 (const_int -65536)))
7771 (clobber (reg:CC FLAGS_REG))]
7772 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7773 || optimize_function_for_size_p (cfun)"
7774 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7775 "operands[1] = gen_lowpart (HImode, operands[0]);")
7778 [(set (match_operand 0 "ext_register_operand" "")
7781 (clobber (reg:CC FLAGS_REG))]
7782 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7783 && reload_completed"
7784 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7785 "operands[1] = gen_lowpart (QImode, operands[0]);")
7788 [(set (match_operand 0 "ext_register_operand" "")
7790 (const_int -65281)))
7791 (clobber (reg:CC FLAGS_REG))]
7792 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7793 && reload_completed"
7794 [(parallel [(set (zero_extract:SI (match_dup 0)
7798 (zero_extract:SI (match_dup 0)
7801 (zero_extract:SI (match_dup 0)
7804 (clobber (reg:CC FLAGS_REG))])]
7805 "operands[0] = gen_lowpart (SImode, operands[0]);")
7807 (define_insn "*anddi_2"
7808 [(set (reg FLAGS_REG)
7811 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7812 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7814 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7815 (and:DI (match_dup 1) (match_dup 2)))]
7816 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7817 && ix86_binary_operator_ok (AND, DImode, operands)"
7819 and{l}\t{%k2, %k0|%k0, %k2}
7820 and{q}\t{%2, %0|%0, %2}
7821 and{q}\t{%2, %0|%0, %2}"
7822 [(set_attr "type" "alu")
7823 (set_attr "mode" "SI,DI,DI")])
7825 (define_insn "*andqi_2_maybe_si"
7826 [(set (reg FLAGS_REG)
7828 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7829 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7831 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7832 (and:QI (match_dup 1) (match_dup 2)))]
7833 "ix86_binary_operator_ok (AND, QImode, operands)
7834 && ix86_match_ccmode (insn,
7835 CONST_INT_P (operands[2])
7836 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7838 if (which_alternative == 2)
7840 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7841 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7842 return "and{l}\t{%2, %k0|%k0, %2}";
7844 return "and{b}\t{%2, %0|%0, %2}";
7846 [(set_attr "type" "alu")
7847 (set_attr "mode" "QI,QI,SI")])
7849 (define_insn "*and<mode>_2"
7850 [(set (reg FLAGS_REG)
7851 (compare (and:SWI124
7852 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7853 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7855 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7856 (and:SWI124 (match_dup 1) (match_dup 2)))]
7857 "ix86_match_ccmode (insn, CCNOmode)
7858 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7859 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7860 [(set_attr "type" "alu")
7861 (set_attr "mode" "<MODE>")])
7863 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7864 (define_insn "*andsi_2_zext"
7865 [(set (reg FLAGS_REG)
7867 (match_operand:SI 1 "nonimmediate_operand" "%0")
7868 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7870 (set (match_operand:DI 0 "register_operand" "=r")
7871 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7872 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7873 && ix86_binary_operator_ok (AND, SImode, operands)"
7874 "and{l}\t{%2, %k0|%k0, %2}"
7875 [(set_attr "type" "alu")
7876 (set_attr "mode" "SI")])
7878 (define_insn "*andqi_2_slp"
7879 [(set (reg FLAGS_REG)
7881 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7882 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7884 (set (strict_low_part (match_dup 0))
7885 (and:QI (match_dup 0) (match_dup 1)))]
7886 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7887 && ix86_match_ccmode (insn, CCNOmode)
7888 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7889 "and{b}\t{%1, %0|%0, %1}"
7890 [(set_attr "type" "alu1")
7891 (set_attr "mode" "QI")])
7893 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7894 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7895 ;; for a QImode operand, which of course failed.
7896 (define_insn "andqi_ext_0"
7897 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7902 (match_operand 1 "ext_register_operand" "0")
7905 (match_operand 2 "const_int_operand" "n")))
7906 (clobber (reg:CC FLAGS_REG))]
7908 "and{b}\t{%2, %h0|%h0, %2}"
7909 [(set_attr "type" "alu")
7910 (set_attr "length_immediate" "1")
7911 (set_attr "modrm" "1")
7912 (set_attr "mode" "QI")])
7914 ;; Generated by peephole translating test to and. This shows up
7915 ;; often in fp comparisons.
7916 (define_insn "*andqi_ext_0_cc"
7917 [(set (reg FLAGS_REG)
7921 (match_operand 1 "ext_register_operand" "0")
7924 (match_operand 2 "const_int_operand" "n"))
7926 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7935 "ix86_match_ccmode (insn, CCNOmode)"
7936 "and{b}\t{%2, %h0|%h0, %2}"
7937 [(set_attr "type" "alu")
7938 (set_attr "length_immediate" "1")
7939 (set_attr "modrm" "1")
7940 (set_attr "mode" "QI")])
7942 (define_insn "*andqi_ext_1_rex64"
7943 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7948 (match_operand 1 "ext_register_operand" "0")
7952 (match_operand 2 "ext_register_operand" "Q"))))
7953 (clobber (reg:CC FLAGS_REG))]
7955 "and{b}\t{%2, %h0|%h0, %2}"
7956 [(set_attr "type" "alu")
7957 (set_attr "length_immediate" "0")
7958 (set_attr "mode" "QI")])
7960 (define_insn "*andqi_ext_1"
7961 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7966 (match_operand 1 "ext_register_operand" "0")
7970 (match_operand:QI 2 "general_operand" "Qm"))))
7971 (clobber (reg:CC FLAGS_REG))]
7973 "and{b}\t{%2, %h0|%h0, %2}"
7974 [(set_attr "type" "alu")
7975 (set_attr "length_immediate" "0")
7976 (set_attr "mode" "QI")])
7978 (define_insn "*andqi_ext_2"
7979 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7984 (match_operand 1 "ext_register_operand" "%0")
7988 (match_operand 2 "ext_register_operand" "Q")
7991 (clobber (reg:CC FLAGS_REG))]
7993 "and{b}\t{%h2, %h0|%h0, %h2}"
7994 [(set_attr "type" "alu")
7995 (set_attr "length_immediate" "0")
7996 (set_attr "mode" "QI")])
7998 ;; Convert wide AND instructions with immediate operand to shorter QImode
7999 ;; equivalents when possible.
8000 ;; Don't do the splitting with memory operands, since it introduces risk
8001 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8002 ;; for size, but that can (should?) be handled by generic code instead.
8004 [(set (match_operand 0 "register_operand" "")
8005 (and (match_operand 1 "register_operand" "")
8006 (match_operand 2 "const_int_operand" "")))
8007 (clobber (reg:CC FLAGS_REG))]
8009 && QI_REG_P (operands[0])
8010 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8011 && !(~INTVAL (operands[2]) & ~(255 << 8))
8012 && GET_MODE (operands[0]) != QImode"
8013 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8014 (and:SI (zero_extract:SI (match_dup 1)
8015 (const_int 8) (const_int 8))
8017 (clobber (reg:CC FLAGS_REG))])]
8018 "operands[0] = gen_lowpart (SImode, operands[0]);
8019 operands[1] = gen_lowpart (SImode, operands[1]);
8020 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8022 ;; Since AND can be encoded with sign extended immediate, this is only
8023 ;; profitable when 7th bit is not set.
8025 [(set (match_operand 0 "register_operand" "")
8026 (and (match_operand 1 "general_operand" "")
8027 (match_operand 2 "const_int_operand" "")))
8028 (clobber (reg:CC FLAGS_REG))]
8030 && ANY_QI_REG_P (operands[0])
8031 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8032 && !(~INTVAL (operands[2]) & ~255)
8033 && !(INTVAL (operands[2]) & 128)
8034 && GET_MODE (operands[0]) != QImode"
8035 [(parallel [(set (strict_low_part (match_dup 0))
8036 (and:QI (match_dup 1)
8038 (clobber (reg:CC FLAGS_REG))])]
8039 "operands[0] = gen_lowpart (QImode, operands[0]);
8040 operands[1] = gen_lowpart (QImode, operands[1]);
8041 operands[2] = gen_lowpart (QImode, operands[2]);")
8043 ;; Logical inclusive and exclusive OR instructions
8045 ;; %%% This used to optimize known byte-wide and operations to memory.
8046 ;; If this is considered useful, it should be done with splitters.
8048 (define_expand "<code><mode>3"
8049 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8050 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8051 (match_operand:SWIM 2 "<general_operand>" "")))]
8053 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8055 (define_insn "*<code><mode>_1"
8056 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8058 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8059 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8060 (clobber (reg:CC FLAGS_REG))]
8061 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8062 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8063 [(set_attr "type" "alu")
8064 (set_attr "mode" "<MODE>")])
8066 ;; %%% Potential partial reg stall on alternative 2. What to do?
8067 (define_insn "*<code>qi_1"
8068 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8069 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8070 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8071 (clobber (reg:CC FLAGS_REG))]
8072 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8074 <logic>{b}\t{%2, %0|%0, %2}
8075 <logic>{b}\t{%2, %0|%0, %2}
8076 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8077 [(set_attr "type" "alu")
8078 (set_attr "mode" "QI,QI,SI")])
8080 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8081 (define_insn "*<code>si_1_zext"
8082 [(set (match_operand:DI 0 "register_operand" "=r")
8084 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8085 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8086 (clobber (reg:CC FLAGS_REG))]
8087 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8088 "<logic>{l}\t{%2, %k0|%k0, %2}"
8089 [(set_attr "type" "alu")
8090 (set_attr "mode" "SI")])
8092 (define_insn "*<code>si_1_zext_imm"
8093 [(set (match_operand:DI 0 "register_operand" "=r")
8095 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8096 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8097 (clobber (reg:CC FLAGS_REG))]
8098 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8099 "<logic>{l}\t{%2, %k0|%k0, %2}"
8100 [(set_attr "type" "alu")
8101 (set_attr "mode" "SI")])
8103 (define_insn "*<code>qi_1_slp"
8104 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8105 (any_or:QI (match_dup 0)
8106 (match_operand:QI 1 "general_operand" "qmn,qn")))
8107 (clobber (reg:CC FLAGS_REG))]
8108 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8109 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8110 "<logic>{b}\t{%1, %0|%0, %1}"
8111 [(set_attr "type" "alu1")
8112 (set_attr "mode" "QI")])
8114 (define_insn "*<code><mode>_2"
8115 [(set (reg FLAGS_REG)
8116 (compare (any_or:SWI
8117 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8118 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8120 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8121 (any_or:SWI (match_dup 1) (match_dup 2)))]
8122 "ix86_match_ccmode (insn, CCNOmode)
8123 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8124 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8125 [(set_attr "type" "alu")
8126 (set_attr "mode" "<MODE>")])
8128 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8129 ;; ??? Special case for immediate operand is missing - it is tricky.
8130 (define_insn "*<code>si_2_zext"
8131 [(set (reg FLAGS_REG)
8132 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8133 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8135 (set (match_operand:DI 0 "register_operand" "=r")
8136 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8137 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8138 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8139 "<logic>{l}\t{%2, %k0|%k0, %2}"
8140 [(set_attr "type" "alu")
8141 (set_attr "mode" "SI")])
8143 (define_insn "*<code>si_2_zext_imm"
8144 [(set (reg FLAGS_REG)
8146 (match_operand:SI 1 "nonimmediate_operand" "%0")
8147 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8149 (set (match_operand:DI 0 "register_operand" "=r")
8150 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8151 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8152 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8153 "<logic>{l}\t{%2, %k0|%k0, %2}"
8154 [(set_attr "type" "alu")
8155 (set_attr "mode" "SI")])
8157 (define_insn "*<code>qi_2_slp"
8158 [(set (reg FLAGS_REG)
8159 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8160 (match_operand:QI 1 "general_operand" "qmn,qn"))
8162 (set (strict_low_part (match_dup 0))
8163 (any_or:QI (match_dup 0) (match_dup 1)))]
8164 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8165 && ix86_match_ccmode (insn, CCNOmode)
8166 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8167 "<logic>{b}\t{%1, %0|%0, %1}"
8168 [(set_attr "type" "alu1")
8169 (set_attr "mode" "QI")])
8171 (define_insn "*<code><mode>_3"
8172 [(set (reg FLAGS_REG)
8173 (compare (any_or:SWI
8174 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8175 (match_operand:SWI 2 "<general_operand>" "<g>"))
8177 (clobber (match_scratch:SWI 0 "=<r>"))]
8178 "ix86_match_ccmode (insn, CCNOmode)
8179 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8180 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8181 [(set_attr "type" "alu")
8182 (set_attr "mode" "<MODE>")])
8184 (define_insn "*<code>qi_ext_0"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8190 (match_operand 1 "ext_register_operand" "0")
8193 (match_operand 2 "const_int_operand" "n")))
8194 (clobber (reg:CC FLAGS_REG))]
8195 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8196 "<logic>{b}\t{%2, %h0|%h0, %2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "length_immediate" "1")
8199 (set_attr "modrm" "1")
8200 (set_attr "mode" "QI")])
8202 (define_insn "*<code>qi_ext_1_rex64"
8203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8208 (match_operand 1 "ext_register_operand" "0")
8212 (match_operand 2 "ext_register_operand" "Q"))))
8213 (clobber (reg:CC FLAGS_REG))]
8215 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8216 "<logic>{b}\t{%2, %h0|%h0, %2}"
8217 [(set_attr "type" "alu")
8218 (set_attr "length_immediate" "0")
8219 (set_attr "mode" "QI")])
8221 (define_insn "*<code>qi_ext_1"
8222 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8227 (match_operand 1 "ext_register_operand" "0")
8231 (match_operand:QI 2 "general_operand" "Qm"))))
8232 (clobber (reg:CC FLAGS_REG))]
8234 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8235 "<logic>{b}\t{%2, %h0|%h0, %2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "length_immediate" "0")
8238 (set_attr "mode" "QI")])
8240 (define_insn "*<code>qi_ext_2"
8241 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8245 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8248 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8251 (clobber (reg:CC FLAGS_REG))]
8252 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8253 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "length_immediate" "0")
8256 (set_attr "mode" "QI")])
8259 [(set (match_operand 0 "register_operand" "")
8260 (any_or (match_operand 1 "register_operand" "")
8261 (match_operand 2 "const_int_operand" "")))
8262 (clobber (reg:CC FLAGS_REG))]
8264 && QI_REG_P (operands[0])
8265 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8266 && !(INTVAL (operands[2]) & ~(255 << 8))
8267 && GET_MODE (operands[0]) != QImode"
8268 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8269 (any_or:SI (zero_extract:SI (match_dup 1)
8270 (const_int 8) (const_int 8))
8272 (clobber (reg:CC FLAGS_REG))])]
8273 "operands[0] = gen_lowpart (SImode, operands[0]);
8274 operands[1] = gen_lowpart (SImode, operands[1]);
8275 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8277 ;; Since OR can be encoded with sign extended immediate, this is only
8278 ;; profitable when 7th bit is set.
8280 [(set (match_operand 0 "register_operand" "")
8281 (any_or (match_operand 1 "general_operand" "")
8282 (match_operand 2 "const_int_operand" "")))
8283 (clobber (reg:CC FLAGS_REG))]
8285 && ANY_QI_REG_P (operands[0])
8286 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8287 && !(INTVAL (operands[2]) & ~255)
8288 && (INTVAL (operands[2]) & 128)
8289 && GET_MODE (operands[0]) != QImode"
8290 [(parallel [(set (strict_low_part (match_dup 0))
8291 (any_or:QI (match_dup 1)
8293 (clobber (reg:CC FLAGS_REG))])]
8294 "operands[0] = gen_lowpart (QImode, operands[0]);
8295 operands[1] = gen_lowpart (QImode, operands[1]);
8296 operands[2] = gen_lowpart (QImode, operands[2]);")
8298 (define_expand "xorqi_cc_ext_1"
8300 (set (reg:CCNO FLAGS_REG)
8304 (match_operand 1 "ext_register_operand" "")
8307 (match_operand:QI 2 "general_operand" ""))
8309 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8319 (define_insn "*xorqi_cc_ext_1_rex64"
8320 [(set (reg FLAGS_REG)
8324 (match_operand 1 "ext_register_operand" "0")
8327 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8329 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8338 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8339 "xor{b}\t{%2, %h0|%h0, %2}"
8340 [(set_attr "type" "alu")
8341 (set_attr "modrm" "1")
8342 (set_attr "mode" "QI")])
8344 (define_insn "*xorqi_cc_ext_1"
8345 [(set (reg FLAGS_REG)
8349 (match_operand 1 "ext_register_operand" "0")
8352 (match_operand:QI 2 "general_operand" "qmn"))
8354 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8363 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8364 "xor{b}\t{%2, %h0|%h0, %2}"
8365 [(set_attr "type" "alu")
8366 (set_attr "modrm" "1")
8367 (set_attr "mode" "QI")])
8369 ;; Negation instructions
8371 (define_expand "neg<mode>2"
8372 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8373 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8375 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8377 (define_insn_and_split "*neg<dwi>2_doubleword"
8378 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8379 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8380 (clobber (reg:CC FLAGS_REG))]
8381 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8385 [(set (reg:CCZ FLAGS_REG)
8386 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8387 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8390 (plus:DWIH (match_dup 3)
8391 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8393 (clobber (reg:CC FLAGS_REG))])
8396 (neg:DWIH (match_dup 2)))
8397 (clobber (reg:CC FLAGS_REG))])]
8398 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8400 (define_insn "*neg<mode>2_1"
8401 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8402 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8403 (clobber (reg:CC FLAGS_REG))]
8404 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8405 "neg{<imodesuffix>}\t%0"
8406 [(set_attr "type" "negnot")
8407 (set_attr "mode" "<MODE>")])
8409 ;; Combine is quite creative about this pattern.
8410 (define_insn "*negsi2_1_zext"
8411 [(set (match_operand:DI 0 "register_operand" "=r")
8413 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8416 (clobber (reg:CC FLAGS_REG))]
8417 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8419 [(set_attr "type" "negnot")
8420 (set_attr "mode" "SI")])
8422 ;; The problem with neg is that it does not perform (compare x 0),
8423 ;; it really performs (compare 0 x), which leaves us with the zero
8424 ;; flag being the only useful item.
8426 (define_insn "*neg<mode>2_cmpz"
8427 [(set (reg:CCZ FLAGS_REG)
8429 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8431 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8432 (neg:SWI (match_dup 1)))]
8433 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8434 "neg{<imodesuffix>}\t%0"
8435 [(set_attr "type" "negnot")
8436 (set_attr "mode" "<MODE>")])
8438 (define_insn "*negsi2_cmpz_zext"
8439 [(set (reg:CCZ FLAGS_REG)
8443 (match_operand:DI 1 "register_operand" "0")
8447 (set (match_operand:DI 0 "register_operand" "=r")
8448 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8451 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8453 [(set_attr "type" "negnot")
8454 (set_attr "mode" "SI")])
8456 ;; Changing of sign for FP values is doable using integer unit too.
8458 (define_expand "<code><mode>2"
8459 [(set (match_operand:X87MODEF 0 "register_operand" "")
8460 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8461 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8462 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8464 (define_insn "*absneg<mode>2_mixed"
8465 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8466 (match_operator:MODEF 3 "absneg_operator"
8467 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8468 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8469 (clobber (reg:CC FLAGS_REG))]
8470 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8473 (define_insn "*absneg<mode>2_sse"
8474 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8475 (match_operator:MODEF 3 "absneg_operator"
8476 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8477 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8482 (define_insn "*absneg<mode>2_i387"
8483 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8484 (match_operator:X87MODEF 3 "absneg_operator"
8485 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8486 (use (match_operand 2 "" ""))
8487 (clobber (reg:CC FLAGS_REG))]
8488 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8491 (define_expand "<code>tf2"
8492 [(set (match_operand:TF 0 "register_operand" "")
8493 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8495 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8497 (define_insn "*absnegtf2_sse"
8498 [(set (match_operand:TF 0 "register_operand" "=x,x")
8499 (match_operator:TF 3 "absneg_operator"
8500 [(match_operand:TF 1 "register_operand" "0,x")]))
8501 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8502 (clobber (reg:CC FLAGS_REG))]
8506 ;; Splitters for fp abs and neg.
8509 [(set (match_operand 0 "fp_register_operand" "")
8510 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8511 (use (match_operand 2 "" ""))
8512 (clobber (reg:CC FLAGS_REG))]
8514 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8517 [(set (match_operand 0 "register_operand" "")
8518 (match_operator 3 "absneg_operator"
8519 [(match_operand 1 "register_operand" "")]))
8520 (use (match_operand 2 "nonimmediate_operand" ""))
8521 (clobber (reg:CC FLAGS_REG))]
8522 "reload_completed && SSE_REG_P (operands[0])"
8523 [(set (match_dup 0) (match_dup 3))]
8525 enum machine_mode mode = GET_MODE (operands[0]);
8526 enum machine_mode vmode = GET_MODE (operands[2]);
8529 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8530 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8531 if (operands_match_p (operands[0], operands[2]))
8534 operands[1] = operands[2];
8537 if (GET_CODE (operands[3]) == ABS)
8538 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8540 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8545 [(set (match_operand:SF 0 "register_operand" "")
8546 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8547 (use (match_operand:V4SF 2 "" ""))
8548 (clobber (reg:CC FLAGS_REG))]
8550 [(parallel [(set (match_dup 0) (match_dup 1))
8551 (clobber (reg:CC FLAGS_REG))])]
8554 operands[0] = gen_lowpart (SImode, operands[0]);
8555 if (GET_CODE (operands[1]) == ABS)
8557 tmp = gen_int_mode (0x7fffffff, SImode);
8558 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8562 tmp = gen_int_mode (0x80000000, SImode);
8563 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8569 [(set (match_operand:DF 0 "register_operand" "")
8570 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8571 (use (match_operand 2 "" ""))
8572 (clobber (reg:CC FLAGS_REG))]
8574 [(parallel [(set (match_dup 0) (match_dup 1))
8575 (clobber (reg:CC FLAGS_REG))])]
8580 tmp = gen_lowpart (DImode, operands[0]);
8581 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8584 if (GET_CODE (operands[1]) == ABS)
8587 tmp = gen_rtx_NOT (DImode, tmp);
8591 operands[0] = gen_highpart (SImode, operands[0]);
8592 if (GET_CODE (operands[1]) == ABS)
8594 tmp = gen_int_mode (0x7fffffff, SImode);
8595 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8599 tmp = gen_int_mode (0x80000000, SImode);
8600 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8607 [(set (match_operand:XF 0 "register_operand" "")
8608 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8609 (use (match_operand 2 "" ""))
8610 (clobber (reg:CC FLAGS_REG))]
8612 [(parallel [(set (match_dup 0) (match_dup 1))
8613 (clobber (reg:CC FLAGS_REG))])]
8616 operands[0] = gen_rtx_REG (SImode,
8617 true_regnum (operands[0])
8618 + (TARGET_64BIT ? 1 : 2));
8619 if (GET_CODE (operands[1]) == ABS)
8621 tmp = GEN_INT (0x7fff);
8622 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8626 tmp = GEN_INT (0x8000);
8627 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8632 ;; Conditionalize these after reload. If they match before reload, we
8633 ;; lose the clobber and ability to use integer instructions.
8635 (define_insn "*<code><mode>2_1"
8636 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8637 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8639 && (reload_completed
8640 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8641 "f<absneg_mnemonic>"
8642 [(set_attr "type" "fsgn")
8643 (set_attr "mode" "<MODE>")])
8645 (define_insn "*<code>extendsfdf2"
8646 [(set (match_operand:DF 0 "register_operand" "=f")
8647 (absneg:DF (float_extend:DF
8648 (match_operand:SF 1 "register_operand" "0"))))]
8649 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8650 "f<absneg_mnemonic>"
8651 [(set_attr "type" "fsgn")
8652 (set_attr "mode" "DF")])
8654 (define_insn "*<code>extendsfxf2"
8655 [(set (match_operand:XF 0 "register_operand" "=f")
8656 (absneg:XF (float_extend:XF
8657 (match_operand:SF 1 "register_operand" "0"))))]
8659 "f<absneg_mnemonic>"
8660 [(set_attr "type" "fsgn")
8661 (set_attr "mode" "XF")])
8663 (define_insn "*<code>extenddfxf2"
8664 [(set (match_operand:XF 0 "register_operand" "=f")
8665 (absneg:XF (float_extend:XF
8666 (match_operand:DF 1 "register_operand" "0"))))]
8668 "f<absneg_mnemonic>"
8669 [(set_attr "type" "fsgn")
8670 (set_attr "mode" "XF")])
8672 ;; Copysign instructions
8674 (define_mode_iterator CSGNMODE [SF DF TF])
8675 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8677 (define_expand "copysign<mode>3"
8678 [(match_operand:CSGNMODE 0 "register_operand" "")
8679 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8680 (match_operand:CSGNMODE 2 "register_operand" "")]
8681 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8682 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8683 "ix86_expand_copysign (operands); DONE;")
8685 (define_insn_and_split "copysign<mode>3_const"
8686 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8688 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8689 (match_operand:CSGNMODE 2 "register_operand" "0")
8690 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8692 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8693 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8695 "&& reload_completed"
8697 "ix86_split_copysign_const (operands); DONE;")
8699 (define_insn "copysign<mode>3_var"
8700 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8702 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8703 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8704 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8705 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8707 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8708 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8709 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8713 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8715 [(match_operand:CSGNMODE 2 "register_operand" "")
8716 (match_operand:CSGNMODE 3 "register_operand" "")
8717 (match_operand:<CSGNVMODE> 4 "" "")
8718 (match_operand:<CSGNVMODE> 5 "" "")]
8720 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8721 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8722 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8723 && reload_completed"
8725 "ix86_split_copysign_var (operands); DONE;")
8727 ;; One complement instructions
8729 (define_expand "one_cmpl<mode>2"
8730 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8731 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8733 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8735 (define_insn "*one_cmpl<mode>2_1"
8736 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8737 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8738 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8739 "not{<imodesuffix>}\t%0"
8740 [(set_attr "type" "negnot")
8741 (set_attr "mode" "<MODE>")])
8743 ;; %%% Potential partial reg stall on alternative 1. What to do?
8744 (define_insn "*one_cmplqi2_1"
8745 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8746 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8747 "ix86_unary_operator_ok (NOT, QImode, operands)"
8751 [(set_attr "type" "negnot")
8752 (set_attr "mode" "QI,SI")])
8754 ;; ??? Currently never generated - xor is used instead.
8755 (define_insn "*one_cmplsi2_1_zext"
8756 [(set (match_operand:DI 0 "register_operand" "=r")
8758 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8759 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8761 [(set_attr "type" "negnot")
8762 (set_attr "mode" "SI")])
8764 (define_insn "*one_cmpl<mode>2_2"
8765 [(set (reg FLAGS_REG)
8766 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8768 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8769 (not:SWI (match_dup 1)))]
8770 "ix86_match_ccmode (insn, CCNOmode)
8771 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8773 [(set_attr "type" "alu1")
8774 (set_attr "mode" "<MODE>")])
8777 [(set (match_operand 0 "flags_reg_operand" "")
8778 (match_operator 2 "compare_operator"
8779 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8781 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8782 (not:SWI (match_dup 3)))]
8783 "ix86_match_ccmode (insn, CCNOmode)"
8784 [(parallel [(set (match_dup 0)
8785 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8788 (xor:SWI (match_dup 3) (const_int -1)))])])
8790 ;; ??? Currently never generated - xor is used instead.
8791 (define_insn "*one_cmplsi2_2_zext"
8792 [(set (reg FLAGS_REG)
8793 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8795 (set (match_operand:DI 0 "register_operand" "=r")
8796 (zero_extend:DI (not:SI (match_dup 1))))]
8797 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8798 && ix86_unary_operator_ok (NOT, SImode, operands)"
8800 [(set_attr "type" "alu1")
8801 (set_attr "mode" "SI")])
8804 [(set (match_operand 0 "flags_reg_operand" "")
8805 (match_operator 2 "compare_operator"
8806 [(not:SI (match_operand:SI 3 "register_operand" ""))
8808 (set (match_operand:DI 1 "register_operand" "")
8809 (zero_extend:DI (not:SI (match_dup 3))))]
8810 "ix86_match_ccmode (insn, CCNOmode)"
8811 [(parallel [(set (match_dup 0)
8812 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8815 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8817 ;; Shift instructions
8819 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8820 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8821 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8822 ;; from the assembler input.
8824 ;; This instruction shifts the target reg/mem as usual, but instead of
8825 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8826 ;; is a left shift double, bits are taken from the high order bits of
8827 ;; reg, else if the insn is a shift right double, bits are taken from the
8828 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8829 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8831 ;; Since sh[lr]d does not change the `reg' operand, that is done
8832 ;; separately, making all shifts emit pairs of shift double and normal
8833 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8834 ;; support a 63 bit shift, each shift where the count is in a reg expands
8835 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8837 ;; If the shift count is a constant, we need never emit more than one
8838 ;; shift pair, instead using moves and sign extension for counts greater
8841 (define_expand "ashl<mode>3"
8842 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8843 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8844 (match_operand:QI 2 "nonmemory_operand" "")))]
8846 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8848 (define_insn "*ashl<mode>3_doubleword"
8849 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8850 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8851 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8852 (clobber (reg:CC FLAGS_REG))]
8855 [(set_attr "type" "multi")])
8858 [(set (match_operand:DWI 0 "register_operand" "")
8859 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8860 (match_operand:QI 2 "nonmemory_operand" "")))
8861 (clobber (reg:CC FLAGS_REG))]
8862 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8864 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8866 ;; By default we don't ask for a scratch register, because when DWImode
8867 ;; values are manipulated, registers are already at a premium. But if
8868 ;; we have one handy, we won't turn it away.
8871 [(match_scratch:DWIH 3 "r")
8872 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8874 (match_operand:<DWI> 1 "nonmemory_operand" "")
8875 (match_operand:QI 2 "nonmemory_operand" "")))
8876 (clobber (reg:CC FLAGS_REG))])
8880 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8882 (define_insn "x86_64_shld"
8883 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8884 (ior:DI (ashift:DI (match_dup 0)
8885 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8886 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8887 (minus:QI (const_int 64) (match_dup 2)))))
8888 (clobber (reg:CC FLAGS_REG))]
8890 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8891 [(set_attr "type" "ishift")
8892 (set_attr "prefix_0f" "1")
8893 (set_attr "mode" "DI")
8894 (set_attr "athlon_decode" "vector")
8895 (set_attr "amdfam10_decode" "vector")
8896 (set_attr "bdver1_decode" "vector")])
8898 (define_insn "x86_shld"
8899 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8900 (ior:SI (ashift:SI (match_dup 0)
8901 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8902 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8903 (minus:QI (const_int 32) (match_dup 2)))))
8904 (clobber (reg:CC FLAGS_REG))]
8906 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8907 [(set_attr "type" "ishift")
8908 (set_attr "prefix_0f" "1")
8909 (set_attr "mode" "SI")
8910 (set_attr "pent_pair" "np")
8911 (set_attr "athlon_decode" "vector")
8912 (set_attr "amdfam10_decode" "vector")
8913 (set_attr "bdver1_decode" "vector")])
8915 (define_expand "x86_shift<mode>_adj_1"
8916 [(set (reg:CCZ FLAGS_REG)
8917 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8920 (set (match_operand:SWI48 0 "register_operand" "")
8921 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8922 (match_operand:SWI48 1 "register_operand" "")
8925 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8926 (match_operand:SWI48 3 "register_operand" "r")
8929 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8931 (define_expand "x86_shift<mode>_adj_2"
8932 [(use (match_operand:SWI48 0 "register_operand" ""))
8933 (use (match_operand:SWI48 1 "register_operand" ""))
8934 (use (match_operand:QI 2 "register_operand" ""))]
8937 rtx label = gen_label_rtx ();
8940 emit_insn (gen_testqi_ccz_1 (operands[2],
8941 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8943 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8944 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8945 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8946 gen_rtx_LABEL_REF (VOIDmode, label),
8948 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8949 JUMP_LABEL (tmp) = label;
8951 emit_move_insn (operands[0], operands[1]);
8952 ix86_expand_clear (operands[1]);
8955 LABEL_NUSES (label) = 1;
8960 ;; Avoid useless masking of count operand.
8961 (define_insn_and_split "*ashl<mode>3_mask"
8962 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8964 (match_operand:SWI48 1 "nonimmediate_operand" "0")
8967 (match_operand:SI 2 "nonimmediate_operand" "c")
8968 (match_operand:SI 3 "const_int_operand" "n")) 0)))
8969 (clobber (reg:CC FLAGS_REG))]
8970 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8971 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8972 == GET_MODE_BITSIZE (<MODE>mode)-1"
8975 [(parallel [(set (match_dup 0)
8976 (ashift:SWI48 (match_dup 1) (match_dup 2)))
8977 (clobber (reg:CC FLAGS_REG))])]
8979 if (can_create_pseudo_p ())
8980 operands [2] = force_reg (SImode, operands[2]);
8982 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
8984 [(set_attr "type" "ishift")
8985 (set_attr "mode" "<MODE>")])
8987 (define_insn "*ashl<mode>3_1"
8988 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8989 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
8990 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
8991 (clobber (reg:CC FLAGS_REG))]
8992 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
8994 switch (get_attr_type (insn))
9000 gcc_assert (operands[2] == const1_rtx);
9001 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9002 return "add{<imodesuffix>}\t%0, %0";
9005 if (operands[2] == const1_rtx
9006 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9007 return "sal{<imodesuffix>}\t%0";
9009 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9013 (cond [(eq_attr "alternative" "1")
9014 (const_string "lea")
9015 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9017 (match_operand 0 "register_operand" ""))
9018 (match_operand 2 "const1_operand" ""))
9019 (const_string "alu")
9021 (const_string "ishift")))
9022 (set (attr "length_immediate")
9024 (ior (eq_attr "type" "alu")
9025 (and (eq_attr "type" "ishift")
9026 (and (match_operand 2 "const1_operand" "")
9027 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9030 (const_string "*")))
9031 (set_attr "mode" "<MODE>")])
9033 (define_insn "*ashlsi3_1_zext"
9034 [(set (match_operand:DI 0 "register_operand" "=r,r")
9036 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9037 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9038 (clobber (reg:CC FLAGS_REG))]
9039 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9041 switch (get_attr_type (insn))
9047 gcc_assert (operands[2] == const1_rtx);
9048 return "add{l}\t%k0, %k0";
9051 if (operands[2] == const1_rtx
9052 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9053 return "sal{l}\t%k0";
9055 return "sal{l}\t{%2, %k0|%k0, %2}";
9059 (cond [(eq_attr "alternative" "1")
9060 (const_string "lea")
9061 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9063 (match_operand 2 "const1_operand" ""))
9064 (const_string "alu")
9066 (const_string "ishift")))
9067 (set (attr "length_immediate")
9069 (ior (eq_attr "type" "alu")
9070 (and (eq_attr "type" "ishift")
9071 (and (match_operand 2 "const1_operand" "")
9072 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9075 (const_string "*")))
9076 (set_attr "mode" "SI")])
9078 (define_insn "*ashlhi3_1"
9079 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9080 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9081 (match_operand:QI 2 "nonmemory_operand" "cI")))
9082 (clobber (reg:CC FLAGS_REG))]
9083 "TARGET_PARTIAL_REG_STALL
9084 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9086 switch (get_attr_type (insn))
9089 gcc_assert (operands[2] == const1_rtx);
9090 return "add{w}\t%0, %0";
9093 if (operands[2] == const1_rtx
9094 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9095 return "sal{w}\t%0";
9097 return "sal{w}\t{%2, %0|%0, %2}";
9101 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9103 (match_operand 0 "register_operand" ""))
9104 (match_operand 2 "const1_operand" ""))
9105 (const_string "alu")
9107 (const_string "ishift")))
9108 (set (attr "length_immediate")
9110 (ior (eq_attr "type" "alu")
9111 (and (eq_attr "type" "ishift")
9112 (and (match_operand 2 "const1_operand" "")
9113 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9116 (const_string "*")))
9117 (set_attr "mode" "HI")])
9119 (define_insn "*ashlhi3_1_lea"
9120 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9121 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9122 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9123 (clobber (reg:CC FLAGS_REG))]
9124 "!TARGET_PARTIAL_REG_STALL
9125 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9127 switch (get_attr_type (insn))
9133 gcc_assert (operands[2] == const1_rtx);
9134 return "add{w}\t%0, %0";
9137 if (operands[2] == const1_rtx
9138 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9139 return "sal{w}\t%0";
9141 return "sal{w}\t{%2, %0|%0, %2}";
9145 (cond [(eq_attr "alternative" "1")
9146 (const_string "lea")
9147 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9149 (match_operand 0 "register_operand" ""))
9150 (match_operand 2 "const1_operand" ""))
9151 (const_string "alu")
9153 (const_string "ishift")))
9154 (set (attr "length_immediate")
9156 (ior (eq_attr "type" "alu")
9157 (and (eq_attr "type" "ishift")
9158 (and (match_operand 2 "const1_operand" "")
9159 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9162 (const_string "*")))
9163 (set_attr "mode" "HI,SI")])
9165 (define_insn "*ashlqi3_1"
9166 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9167 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9168 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9169 (clobber (reg:CC FLAGS_REG))]
9170 "TARGET_PARTIAL_REG_STALL
9171 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9173 switch (get_attr_type (insn))
9176 gcc_assert (operands[2] == const1_rtx);
9177 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9178 return "add{l}\t%k0, %k0";
9180 return "add{b}\t%0, %0";
9183 if (operands[2] == const1_rtx
9184 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9186 if (get_attr_mode (insn) == MODE_SI)
9187 return "sal{l}\t%k0";
9189 return "sal{b}\t%0";
9193 if (get_attr_mode (insn) == MODE_SI)
9194 return "sal{l}\t{%2, %k0|%k0, %2}";
9196 return "sal{b}\t{%2, %0|%0, %2}";
9201 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9203 (match_operand 0 "register_operand" ""))
9204 (match_operand 2 "const1_operand" ""))
9205 (const_string "alu")
9207 (const_string "ishift")))
9208 (set (attr "length_immediate")
9210 (ior (eq_attr "type" "alu")
9211 (and (eq_attr "type" "ishift")
9212 (and (match_operand 2 "const1_operand" "")
9213 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9216 (const_string "*")))
9217 (set_attr "mode" "QI,SI")])
9219 ;; %%% Potential partial reg stall on alternative 2. What to do?
9220 (define_insn "*ashlqi3_1_lea"
9221 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9222 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9223 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9224 (clobber (reg:CC FLAGS_REG))]
9225 "!TARGET_PARTIAL_REG_STALL
9226 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9228 switch (get_attr_type (insn))
9234 gcc_assert (operands[2] == const1_rtx);
9235 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9236 return "add{l}\t%k0, %k0";
9238 return "add{b}\t%0, %0";
9241 if (operands[2] == const1_rtx
9242 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9244 if (get_attr_mode (insn) == MODE_SI)
9245 return "sal{l}\t%k0";
9247 return "sal{b}\t%0";
9251 if (get_attr_mode (insn) == MODE_SI)
9252 return "sal{l}\t{%2, %k0|%k0, %2}";
9254 return "sal{b}\t{%2, %0|%0, %2}";
9259 (cond [(eq_attr "alternative" "2")
9260 (const_string "lea")
9261 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9263 (match_operand 0 "register_operand" ""))
9264 (match_operand 2 "const1_operand" ""))
9265 (const_string "alu")
9267 (const_string "ishift")))
9268 (set (attr "length_immediate")
9270 (ior (eq_attr "type" "alu")
9271 (and (eq_attr "type" "ishift")
9272 (and (match_operand 2 "const1_operand" "")
9273 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9276 (const_string "*")))
9277 (set_attr "mode" "QI,SI,SI")])
9279 (define_insn "*ashlqi3_1_slp"
9280 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9281 (ashift:QI (match_dup 0)
9282 (match_operand:QI 1 "nonmemory_operand" "cI")))
9283 (clobber (reg:CC FLAGS_REG))]
9284 "(optimize_function_for_size_p (cfun)
9285 || !TARGET_PARTIAL_FLAG_REG_STALL
9286 || (operands[1] == const1_rtx
9288 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9290 switch (get_attr_type (insn))
9293 gcc_assert (operands[1] == const1_rtx);
9294 return "add{b}\t%0, %0";
9297 if (operands[1] == const1_rtx
9298 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9299 return "sal{b}\t%0";
9301 return "sal{b}\t{%1, %0|%0, %1}";
9305 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9307 (match_operand 0 "register_operand" ""))
9308 (match_operand 1 "const1_operand" ""))
9309 (const_string "alu")
9311 (const_string "ishift1")))
9312 (set (attr "length_immediate")
9314 (ior (eq_attr "type" "alu")
9315 (and (eq_attr "type" "ishift1")
9316 (and (match_operand 1 "const1_operand" "")
9317 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9320 (const_string "*")))
9321 (set_attr "mode" "QI")])
9323 ;; Convert ashift to the lea pattern to avoid flags dependency.
9325 [(set (match_operand 0 "register_operand" "")
9326 (ashift (match_operand 1 "index_register_operand" "")
9327 (match_operand:QI 2 "const_int_operand" "")))
9328 (clobber (reg:CC FLAGS_REG))]
9329 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9331 && true_regnum (operands[0]) != true_regnum (operands[1])"
9334 enum machine_mode mode = GET_MODE (operands[0]);
9337 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9340 operands[0] = gen_lowpart (mode, operands[0]);
9341 operands[1] = gen_lowpart (mode, operands[1]);
9344 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9346 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9348 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9352 ;; Convert ashift to the lea pattern to avoid flags dependency.
9354 [(set (match_operand:DI 0 "register_operand" "")
9356 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9357 (match_operand:QI 2 "const_int_operand" ""))))
9358 (clobber (reg:CC FLAGS_REG))]
9359 "TARGET_64BIT && reload_completed
9360 && true_regnum (operands[0]) != true_regnum (operands[1])"
9362 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9364 operands[1] = gen_lowpart (DImode, operands[1]);
9365 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9368 ;; This pattern can't accept a variable shift count, since shifts by
9369 ;; zero don't affect the flags. We assume that shifts by constant
9370 ;; zero are optimized away.
9371 (define_insn "*ashl<mode>3_cmp"
9372 [(set (reg FLAGS_REG)
9374 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9375 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9377 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9378 (ashift:SWI (match_dup 1) (match_dup 2)))]
9379 "(optimize_function_for_size_p (cfun)
9380 || !TARGET_PARTIAL_FLAG_REG_STALL
9381 || (operands[2] == const1_rtx
9383 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9384 && ix86_match_ccmode (insn, CCGOCmode)
9385 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9387 switch (get_attr_type (insn))
9390 gcc_assert (operands[2] == const1_rtx);
9391 return "add{<imodesuffix>}\t%0, %0";
9394 if (operands[2] == const1_rtx
9395 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9396 return "sal{<imodesuffix>}\t%0";
9398 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9402 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9404 (match_operand 0 "register_operand" ""))
9405 (match_operand 2 "const1_operand" ""))
9406 (const_string "alu")
9408 (const_string "ishift")))
9409 (set (attr "length_immediate")
9411 (ior (eq_attr "type" "alu")
9412 (and (eq_attr "type" "ishift")
9413 (and (match_operand 2 "const1_operand" "")
9414 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9417 (const_string "*")))
9418 (set_attr "mode" "<MODE>")])
9420 (define_insn "*ashlsi3_cmp_zext"
9421 [(set (reg FLAGS_REG)
9423 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9424 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9426 (set (match_operand:DI 0 "register_operand" "=r")
9427 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9429 && (optimize_function_for_size_p (cfun)
9430 || !TARGET_PARTIAL_FLAG_REG_STALL
9431 || (operands[2] == const1_rtx
9433 || TARGET_DOUBLE_WITH_ADD)))
9434 && ix86_match_ccmode (insn, CCGOCmode)
9435 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9437 switch (get_attr_type (insn))
9440 gcc_assert (operands[2] == const1_rtx);
9441 return "add{l}\t%k0, %k0";
9444 if (operands[2] == const1_rtx
9445 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9446 return "sal{l}\t%k0";
9448 return "sal{l}\t{%2, %k0|%k0, %2}";
9452 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9454 (match_operand 2 "const1_operand" ""))
9455 (const_string "alu")
9457 (const_string "ishift")))
9458 (set (attr "length_immediate")
9460 (ior (eq_attr "type" "alu")
9461 (and (eq_attr "type" "ishift")
9462 (and (match_operand 2 "const1_operand" "")
9463 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9466 (const_string "*")))
9467 (set_attr "mode" "SI")])
9469 (define_insn "*ashl<mode>3_cconly"
9470 [(set (reg FLAGS_REG)
9472 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9473 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9475 (clobber (match_scratch:SWI 0 "=<r>"))]
9476 "(optimize_function_for_size_p (cfun)
9477 || !TARGET_PARTIAL_FLAG_REG_STALL
9478 || (operands[2] == const1_rtx
9480 || TARGET_DOUBLE_WITH_ADD)))
9481 && ix86_match_ccmode (insn, CCGOCmode)"
9483 switch (get_attr_type (insn))
9486 gcc_assert (operands[2] == const1_rtx);
9487 return "add{<imodesuffix>}\t%0, %0";
9490 if (operands[2] == const1_rtx
9491 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9492 return "sal{<imodesuffix>}\t%0";
9494 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9498 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9500 (match_operand 0 "register_operand" ""))
9501 (match_operand 2 "const1_operand" ""))
9502 (const_string "alu")
9504 (const_string "ishift")))
9505 (set (attr "length_immediate")
9507 (ior (eq_attr "type" "alu")
9508 (and (eq_attr "type" "ishift")
9509 (and (match_operand 2 "const1_operand" "")
9510 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9513 (const_string "*")))
9514 (set_attr "mode" "<MODE>")])
9516 ;; See comment above `ashl<mode>3' about how this works.
9518 (define_expand "<shiftrt_insn><mode>3"
9519 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9520 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9521 (match_operand:QI 2 "nonmemory_operand" "")))]
9523 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9525 ;; Avoid useless masking of count operand.
9526 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9527 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9529 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9532 (match_operand:SI 2 "nonimmediate_operand" "c")
9533 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9534 (clobber (reg:CC FLAGS_REG))]
9535 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9536 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9537 == GET_MODE_BITSIZE (<MODE>mode)-1"
9540 [(parallel [(set (match_dup 0)
9541 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9542 (clobber (reg:CC FLAGS_REG))])]
9544 if (can_create_pseudo_p ())
9545 operands [2] = force_reg (SImode, operands[2]);
9547 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9549 [(set_attr "type" "ishift")
9550 (set_attr "mode" "<MODE>")])
9552 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9553 [(set (match_operand:DWI 0 "register_operand" "=r")
9554 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9555 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9556 (clobber (reg:CC FLAGS_REG))]
9559 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9561 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9562 [(set_attr "type" "multi")])
9564 ;; By default we don't ask for a scratch register, because when DWImode
9565 ;; values are manipulated, registers are already at a premium. But if
9566 ;; we have one handy, we won't turn it away.
9569 [(match_scratch:DWIH 3 "r")
9570 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9572 (match_operand:<DWI> 1 "register_operand" "")
9573 (match_operand:QI 2 "nonmemory_operand" "")))
9574 (clobber (reg:CC FLAGS_REG))])
9578 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9580 (define_insn "x86_64_shrd"
9581 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9582 (ior:DI (ashiftrt:DI (match_dup 0)
9583 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9584 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9585 (minus:QI (const_int 64) (match_dup 2)))))
9586 (clobber (reg:CC FLAGS_REG))]
9588 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9589 [(set_attr "type" "ishift")
9590 (set_attr "prefix_0f" "1")
9591 (set_attr "mode" "DI")
9592 (set_attr "athlon_decode" "vector")
9593 (set_attr "amdfam10_decode" "vector")
9594 (set_attr "bdver1_decode" "vector")])
9596 (define_insn "x86_shrd"
9597 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9598 (ior:SI (ashiftrt:SI (match_dup 0)
9599 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9600 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9601 (minus:QI (const_int 32) (match_dup 2)))))
9602 (clobber (reg:CC FLAGS_REG))]
9604 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9605 [(set_attr "type" "ishift")
9606 (set_attr "prefix_0f" "1")
9607 (set_attr "mode" "SI")
9608 (set_attr "pent_pair" "np")
9609 (set_attr "athlon_decode" "vector")
9610 (set_attr "amdfam10_decode" "vector")
9611 (set_attr "bdver1_decode" "vector")])
9613 (define_insn "ashrdi3_cvt"
9614 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9615 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9616 (match_operand:QI 2 "const_int_operand" "")))
9617 (clobber (reg:CC FLAGS_REG))]
9618 "TARGET_64BIT && INTVAL (operands[2]) == 63
9619 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9620 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9623 sar{q}\t{%2, %0|%0, %2}"
9624 [(set_attr "type" "imovx,ishift")
9625 (set_attr "prefix_0f" "0,*")
9626 (set_attr "length_immediate" "0,*")
9627 (set_attr "modrm" "0,1")
9628 (set_attr "mode" "DI")])
9630 (define_insn "ashrsi3_cvt"
9631 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9632 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9633 (match_operand:QI 2 "const_int_operand" "")))
9634 (clobber (reg:CC FLAGS_REG))]
9635 "INTVAL (operands[2]) == 31
9636 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9637 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9640 sar{l}\t{%2, %0|%0, %2}"
9641 [(set_attr "type" "imovx,ishift")
9642 (set_attr "prefix_0f" "0,*")
9643 (set_attr "length_immediate" "0,*")
9644 (set_attr "modrm" "0,1")
9645 (set_attr "mode" "SI")])
9647 (define_insn "*ashrsi3_cvt_zext"
9648 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9650 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9651 (match_operand:QI 2 "const_int_operand" ""))))
9652 (clobber (reg:CC FLAGS_REG))]
9653 "TARGET_64BIT && INTVAL (operands[2]) == 31
9654 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9655 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9658 sar{l}\t{%2, %k0|%k0, %2}"
9659 [(set_attr "type" "imovx,ishift")
9660 (set_attr "prefix_0f" "0,*")
9661 (set_attr "length_immediate" "0,*")
9662 (set_attr "modrm" "0,1")
9663 (set_attr "mode" "SI")])
9665 (define_expand "x86_shift<mode>_adj_3"
9666 [(use (match_operand:SWI48 0 "register_operand" ""))
9667 (use (match_operand:SWI48 1 "register_operand" ""))
9668 (use (match_operand:QI 2 "register_operand" ""))]
9671 rtx label = gen_label_rtx ();
9674 emit_insn (gen_testqi_ccz_1 (operands[2],
9675 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9677 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9678 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9679 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9680 gen_rtx_LABEL_REF (VOIDmode, label),
9682 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9683 JUMP_LABEL (tmp) = label;
9685 emit_move_insn (operands[0], operands[1]);
9686 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9687 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9689 LABEL_NUSES (label) = 1;
9694 (define_insn "*<shiftrt_insn><mode>3_1"
9695 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9696 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9697 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9698 (clobber (reg:CC FLAGS_REG))]
9699 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9701 if (operands[2] == const1_rtx
9702 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9703 return "<shiftrt>{<imodesuffix>}\t%0";
9705 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9707 [(set_attr "type" "ishift")
9708 (set (attr "length_immediate")
9710 (and (match_operand 2 "const1_operand" "")
9711 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9714 (const_string "*")))
9715 (set_attr "mode" "<MODE>")])
9717 (define_insn "*<shiftrt_insn>si3_1_zext"
9718 [(set (match_operand:DI 0 "register_operand" "=r")
9720 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9721 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9722 (clobber (reg:CC FLAGS_REG))]
9723 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9725 if (operands[2] == const1_rtx
9726 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9727 return "<shiftrt>{l}\t%k0";
9729 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9731 [(set_attr "type" "ishift")
9732 (set (attr "length_immediate")
9734 (and (match_operand 2 "const1_operand" "")
9735 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9738 (const_string "*")))
9739 (set_attr "mode" "SI")])
9741 (define_insn "*<shiftrt_insn>qi3_1_slp"
9742 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9743 (any_shiftrt:QI (match_dup 0)
9744 (match_operand:QI 1 "nonmemory_operand" "cI")))
9745 (clobber (reg:CC FLAGS_REG))]
9746 "(optimize_function_for_size_p (cfun)
9747 || !TARGET_PARTIAL_REG_STALL
9748 || (operands[1] == const1_rtx
9751 if (operands[1] == const1_rtx
9752 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9753 return "<shiftrt>{b}\t%0";
9755 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9757 [(set_attr "type" "ishift1")
9758 (set (attr "length_immediate")
9760 (and (match_operand 1 "const1_operand" "")
9761 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9764 (const_string "*")))
9765 (set_attr "mode" "QI")])
9767 ;; This pattern can't accept a variable shift count, since shifts by
9768 ;; zero don't affect the flags. We assume that shifts by constant
9769 ;; zero are optimized away.
9770 (define_insn "*<shiftrt_insn><mode>3_cmp"
9771 [(set (reg FLAGS_REG)
9774 (match_operand:SWI 1 "nonimmediate_operand" "0")
9775 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9777 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9778 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9779 "(optimize_function_for_size_p (cfun)
9780 || !TARGET_PARTIAL_FLAG_REG_STALL
9781 || (operands[2] == const1_rtx
9783 && ix86_match_ccmode (insn, CCGOCmode)
9784 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9786 if (operands[2] == const1_rtx
9787 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9788 return "<shiftrt>{<imodesuffix>}\t%0";
9790 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9792 [(set_attr "type" "ishift")
9793 (set (attr "length_immediate")
9795 (and (match_operand 2 "const1_operand" "")
9796 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9799 (const_string "*")))
9800 (set_attr "mode" "<MODE>")])
9802 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9803 [(set (reg FLAGS_REG)
9805 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9806 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9808 (set (match_operand:DI 0 "register_operand" "=r")
9809 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9811 && (optimize_function_for_size_p (cfun)
9812 || !TARGET_PARTIAL_FLAG_REG_STALL
9813 || (operands[2] == const1_rtx
9815 && ix86_match_ccmode (insn, CCGOCmode)
9816 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9818 if (operands[2] == const1_rtx
9819 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9820 return "<shiftrt>{l}\t%k0";
9822 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9824 [(set_attr "type" "ishift")
9825 (set (attr "length_immediate")
9827 (and (match_operand 2 "const1_operand" "")
9828 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9831 (const_string "*")))
9832 (set_attr "mode" "SI")])
9834 (define_insn "*<shiftrt_insn><mode>3_cconly"
9835 [(set (reg FLAGS_REG)
9838 (match_operand:SWI 1 "register_operand" "0")
9839 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9841 (clobber (match_scratch:SWI 0 "=<r>"))]
9842 "(optimize_function_for_size_p (cfun)
9843 || !TARGET_PARTIAL_FLAG_REG_STALL
9844 || (operands[2] == const1_rtx
9846 && ix86_match_ccmode (insn, CCGOCmode)"
9848 if (operands[2] == const1_rtx
9849 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9850 return "<shiftrt>{<imodesuffix>}\t%0";
9852 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9854 [(set_attr "type" "ishift")
9855 (set (attr "length_immediate")
9857 (and (match_operand 2 "const1_operand" "")
9858 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9861 (const_string "*")))
9862 (set_attr "mode" "<MODE>")])
9864 ;; Rotate instructions
9866 (define_expand "<rotate_insn>ti3"
9867 [(set (match_operand:TI 0 "register_operand" "")
9868 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9869 (match_operand:QI 2 "nonmemory_operand" "")))]
9872 if (const_1_to_63_operand (operands[2], VOIDmode))
9873 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9874 (operands[0], operands[1], operands[2]));
9881 (define_expand "<rotate_insn>di3"
9882 [(set (match_operand:DI 0 "shiftdi_operand" "")
9883 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9884 (match_operand:QI 2 "nonmemory_operand" "")))]
9888 ix86_expand_binary_operator (<CODE>, DImode, operands);
9889 else if (const_1_to_31_operand (operands[2], VOIDmode))
9890 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9891 (operands[0], operands[1], operands[2]));
9898 (define_expand "<rotate_insn><mode>3"
9899 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9900 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9901 (match_operand:QI 2 "nonmemory_operand" "")))]
9903 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9905 ;; Avoid useless masking of count operand.
9906 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9907 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9909 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9912 (match_operand:SI 2 "nonimmediate_operand" "c")
9913 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9914 (clobber (reg:CC FLAGS_REG))]
9915 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9916 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9917 == GET_MODE_BITSIZE (<MODE>mode)-1"
9920 [(parallel [(set (match_dup 0)
9921 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9922 (clobber (reg:CC FLAGS_REG))])]
9924 if (can_create_pseudo_p ())
9925 operands [2] = force_reg (SImode, operands[2]);
9927 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9929 [(set_attr "type" "rotate")
9930 (set_attr "mode" "<MODE>")])
9932 ;; Implement rotation using two double-precision
9933 ;; shift instructions and a scratch register.
9935 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9936 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9937 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9938 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9939 (clobber (reg:CC FLAGS_REG))
9940 (clobber (match_scratch:DWIH 3 "=&r"))]
9944 [(set (match_dup 3) (match_dup 4))
9947 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9948 (lshiftrt:DWIH (match_dup 5)
9949 (minus:QI (match_dup 6) (match_dup 2)))))
9950 (clobber (reg:CC FLAGS_REG))])
9953 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9954 (lshiftrt:DWIH (match_dup 3)
9955 (minus:QI (match_dup 6) (match_dup 2)))))
9956 (clobber (reg:CC FLAGS_REG))])]
9958 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9960 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9963 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9964 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9965 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9966 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9967 (clobber (reg:CC FLAGS_REG))
9968 (clobber (match_scratch:DWIH 3 "=&r"))]
9972 [(set (match_dup 3) (match_dup 4))
9975 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9976 (ashift:DWIH (match_dup 5)
9977 (minus:QI (match_dup 6) (match_dup 2)))))
9978 (clobber (reg:CC FLAGS_REG))])
9981 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
9982 (ashift:DWIH (match_dup 3)
9983 (minus:QI (match_dup 6) (match_dup 2)))))
9984 (clobber (reg:CC FLAGS_REG))])]
9986 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9988 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9991 (define_insn "*<rotate_insn><mode>3_1"
9992 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9993 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9994 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9995 (clobber (reg:CC FLAGS_REG))]
9996 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9998 if (operands[2] == const1_rtx
9999 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10000 return "<rotate>{<imodesuffix>}\t%0";
10002 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10004 [(set_attr "type" "rotate")
10005 (set (attr "length_immediate")
10007 (and (match_operand 2 "const1_operand" "")
10008 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10011 (const_string "*")))
10012 (set_attr "mode" "<MODE>")])
10014 (define_insn "*<rotate_insn>si3_1_zext"
10015 [(set (match_operand:DI 0 "register_operand" "=r")
10017 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10018 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10019 (clobber (reg:CC FLAGS_REG))]
10020 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10022 if (operands[2] == const1_rtx
10023 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10024 return "<rotate>{l}\t%k0";
10026 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10028 [(set_attr "type" "rotate")
10029 (set (attr "length_immediate")
10031 (and (match_operand 2 "const1_operand" "")
10032 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10035 (const_string "*")))
10036 (set_attr "mode" "SI")])
10038 (define_insn "*<rotate_insn>qi3_1_slp"
10039 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10040 (any_rotate:QI (match_dup 0)
10041 (match_operand:QI 1 "nonmemory_operand" "cI")))
10042 (clobber (reg:CC FLAGS_REG))]
10043 "(optimize_function_for_size_p (cfun)
10044 || !TARGET_PARTIAL_REG_STALL
10045 || (operands[1] == const1_rtx
10046 && TARGET_SHIFT1))"
10048 if (operands[1] == const1_rtx
10049 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10050 return "<rotate>{b}\t%0";
10052 return "<rotate>{b}\t{%1, %0|%0, %1}";
10054 [(set_attr "type" "rotate1")
10055 (set (attr "length_immediate")
10057 (and (match_operand 1 "const1_operand" "")
10058 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10061 (const_string "*")))
10062 (set_attr "mode" "QI")])
10065 [(set (match_operand:HI 0 "register_operand" "")
10066 (any_rotate:HI (match_dup 0) (const_int 8)))
10067 (clobber (reg:CC FLAGS_REG))]
10069 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10070 [(parallel [(set (strict_low_part (match_dup 0))
10071 (bswap:HI (match_dup 0)))
10072 (clobber (reg:CC FLAGS_REG))])])
10074 ;; Bit set / bit test instructions
10076 (define_expand "extv"
10077 [(set (match_operand:SI 0 "register_operand" "")
10078 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10079 (match_operand:SI 2 "const8_operand" "")
10080 (match_operand:SI 3 "const8_operand" "")))]
10083 /* Handle extractions from %ah et al. */
10084 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10087 /* From mips.md: extract_bit_field doesn't verify that our source
10088 matches the predicate, so check it again here. */
10089 if (! ext_register_operand (operands[1], VOIDmode))
10093 (define_expand "extzv"
10094 [(set (match_operand:SI 0 "register_operand" "")
10095 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10096 (match_operand:SI 2 "const8_operand" "")
10097 (match_operand:SI 3 "const8_operand" "")))]
10100 /* Handle extractions from %ah et al. */
10101 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10104 /* From mips.md: extract_bit_field doesn't verify that our source
10105 matches the predicate, so check it again here. */
10106 if (! ext_register_operand (operands[1], VOIDmode))
10110 (define_expand "insv"
10111 [(set (zero_extract (match_operand 0 "register_operand" "")
10112 (match_operand 1 "const_int_operand" "")
10113 (match_operand 2 "const_int_operand" ""))
10114 (match_operand 3 "register_operand" ""))]
10117 rtx (*gen_mov_insv_1) (rtx, rtx);
10119 if (ix86_expand_pinsr (operands))
10122 /* Handle insertions to %ah et al. */
10123 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10126 /* From mips.md: insert_bit_field doesn't verify that our source
10127 matches the predicate, so check it again here. */
10128 if (! ext_register_operand (operands[0], VOIDmode))
10131 gen_mov_insv_1 = (TARGET_64BIT
10132 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10134 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10138 ;; %%% bts, btr, btc, bt.
10139 ;; In general these instructions are *slow* when applied to memory,
10140 ;; since they enforce atomic operation. When applied to registers,
10141 ;; it depends on the cpu implementation. They're never faster than
10142 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10143 ;; no point. But in 64-bit, we can't hold the relevant immediates
10144 ;; within the instruction itself, so operating on bits in the high
10145 ;; 32-bits of a register becomes easier.
10147 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10148 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10149 ;; negdf respectively, so they can never be disabled entirely.
10151 (define_insn "*btsq"
10152 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10154 (match_operand:DI 1 "const_0_to_63_operand" ""))
10156 (clobber (reg:CC FLAGS_REG))]
10157 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10158 "bts{q}\t{%1, %0|%0, %1}"
10159 [(set_attr "type" "alu1")
10160 (set_attr "prefix_0f" "1")
10161 (set_attr "mode" "DI")])
10163 (define_insn "*btrq"
10164 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10166 (match_operand:DI 1 "const_0_to_63_operand" ""))
10168 (clobber (reg:CC FLAGS_REG))]
10169 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10170 "btr{q}\t{%1, %0|%0, %1}"
10171 [(set_attr "type" "alu1")
10172 (set_attr "prefix_0f" "1")
10173 (set_attr "mode" "DI")])
10175 (define_insn "*btcq"
10176 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10178 (match_operand:DI 1 "const_0_to_63_operand" ""))
10179 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10182 "btc{q}\t{%1, %0|%0, %1}"
10183 [(set_attr "type" "alu1")
10184 (set_attr "prefix_0f" "1")
10185 (set_attr "mode" "DI")])
10187 ;; Allow Nocona to avoid these instructions if a register is available.
10190 [(match_scratch:DI 2 "r")
10191 (parallel [(set (zero_extract:DI
10192 (match_operand:DI 0 "register_operand" "")
10194 (match_operand:DI 1 "const_0_to_63_operand" ""))
10196 (clobber (reg:CC FLAGS_REG))])]
10197 "TARGET_64BIT && !TARGET_USE_BT"
10200 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10203 if (HOST_BITS_PER_WIDE_INT >= 64)
10204 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10205 else if (i < HOST_BITS_PER_WIDE_INT)
10206 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10208 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10210 op1 = immed_double_const (lo, hi, DImode);
10213 emit_move_insn (operands[2], op1);
10217 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10222 [(match_scratch:DI 2 "r")
10223 (parallel [(set (zero_extract:DI
10224 (match_operand:DI 0 "register_operand" "")
10226 (match_operand:DI 1 "const_0_to_63_operand" ""))
10228 (clobber (reg:CC FLAGS_REG))])]
10229 "TARGET_64BIT && !TARGET_USE_BT"
10232 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10235 if (HOST_BITS_PER_WIDE_INT >= 64)
10236 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10237 else if (i < HOST_BITS_PER_WIDE_INT)
10238 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10240 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10242 op1 = immed_double_const (~lo, ~hi, DImode);
10245 emit_move_insn (operands[2], op1);
10249 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10254 [(match_scratch:DI 2 "r")
10255 (parallel [(set (zero_extract:DI
10256 (match_operand:DI 0 "register_operand" "")
10258 (match_operand:DI 1 "const_0_to_63_operand" ""))
10259 (not:DI (zero_extract:DI
10260 (match_dup 0) (const_int 1) (match_dup 1))))
10261 (clobber (reg:CC FLAGS_REG))])]
10262 "TARGET_64BIT && !TARGET_USE_BT"
10265 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10268 if (HOST_BITS_PER_WIDE_INT >= 64)
10269 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10270 else if (i < HOST_BITS_PER_WIDE_INT)
10271 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10273 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10275 op1 = immed_double_const (lo, hi, DImode);
10278 emit_move_insn (operands[2], op1);
10282 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10286 (define_insn "*bt<mode>"
10287 [(set (reg:CCC FLAGS_REG)
10289 (zero_extract:SWI48
10290 (match_operand:SWI48 0 "register_operand" "r")
10292 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10294 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10295 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10296 [(set_attr "type" "alu1")
10297 (set_attr "prefix_0f" "1")
10298 (set_attr "mode" "<MODE>")])
10300 ;; Store-flag instructions.
10302 ;; For all sCOND expanders, also expand the compare or test insn that
10303 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10305 (define_insn_and_split "*setcc_di_1"
10306 [(set (match_operand:DI 0 "register_operand" "=q")
10307 (match_operator:DI 1 "ix86_comparison_operator"
10308 [(reg FLAGS_REG) (const_int 0)]))]
10309 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10311 "&& reload_completed"
10312 [(set (match_dup 2) (match_dup 1))
10313 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10315 PUT_MODE (operands[1], QImode);
10316 operands[2] = gen_lowpart (QImode, operands[0]);
10319 (define_insn_and_split "*setcc_si_1_and"
10320 [(set (match_operand:SI 0 "register_operand" "=q")
10321 (match_operator:SI 1 "ix86_comparison_operator"
10322 [(reg FLAGS_REG) (const_int 0)]))
10323 (clobber (reg:CC FLAGS_REG))]
10324 "!TARGET_PARTIAL_REG_STALL
10325 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10327 "&& reload_completed"
10328 [(set (match_dup 2) (match_dup 1))
10329 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10330 (clobber (reg:CC FLAGS_REG))])]
10332 PUT_MODE (operands[1], QImode);
10333 operands[2] = gen_lowpart (QImode, operands[0]);
10336 (define_insn_and_split "*setcc_si_1_movzbl"
10337 [(set (match_operand:SI 0 "register_operand" "=q")
10338 (match_operator:SI 1 "ix86_comparison_operator"
10339 [(reg FLAGS_REG) (const_int 0)]))]
10340 "!TARGET_PARTIAL_REG_STALL
10341 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10343 "&& reload_completed"
10344 [(set (match_dup 2) (match_dup 1))
10345 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10347 PUT_MODE (operands[1], QImode);
10348 operands[2] = gen_lowpart (QImode, operands[0]);
10351 (define_insn "*setcc_qi"
10352 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10353 (match_operator:QI 1 "ix86_comparison_operator"
10354 [(reg FLAGS_REG) (const_int 0)]))]
10357 [(set_attr "type" "setcc")
10358 (set_attr "mode" "QI")])
10360 (define_insn "*setcc_qi_slp"
10361 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10362 (match_operator:QI 1 "ix86_comparison_operator"
10363 [(reg FLAGS_REG) (const_int 0)]))]
10366 [(set_attr "type" "setcc")
10367 (set_attr "mode" "QI")])
10369 ;; In general it is not safe to assume too much about CCmode registers,
10370 ;; so simplify-rtx stops when it sees a second one. Under certain
10371 ;; conditions this is safe on x86, so help combine not create
10378 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10379 (ne:QI (match_operator 1 "ix86_comparison_operator"
10380 [(reg FLAGS_REG) (const_int 0)])
10383 [(set (match_dup 0) (match_dup 1))]
10384 "PUT_MODE (operands[1], QImode);")
10387 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10388 (ne:QI (match_operator 1 "ix86_comparison_operator"
10389 [(reg FLAGS_REG) (const_int 0)])
10392 [(set (match_dup 0) (match_dup 1))]
10393 "PUT_MODE (operands[1], QImode);")
10396 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10397 (eq:QI (match_operator 1 "ix86_comparison_operator"
10398 [(reg FLAGS_REG) (const_int 0)])
10401 [(set (match_dup 0) (match_dup 1))]
10403 rtx new_op1 = copy_rtx (operands[1]);
10404 operands[1] = new_op1;
10405 PUT_MODE (new_op1, QImode);
10406 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10407 GET_MODE (XEXP (new_op1, 0))));
10409 /* Make sure that (a) the CCmode we have for the flags is strong
10410 enough for the reversed compare or (b) we have a valid FP compare. */
10411 if (! ix86_comparison_operator (new_op1, VOIDmode))
10416 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10417 (eq:QI (match_operator 1 "ix86_comparison_operator"
10418 [(reg FLAGS_REG) (const_int 0)])
10421 [(set (match_dup 0) (match_dup 1))]
10423 rtx new_op1 = copy_rtx (operands[1]);
10424 operands[1] = new_op1;
10425 PUT_MODE (new_op1, QImode);
10426 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10427 GET_MODE (XEXP (new_op1, 0))));
10429 /* Make sure that (a) the CCmode we have for the flags is strong
10430 enough for the reversed compare or (b) we have a valid FP compare. */
10431 if (! ix86_comparison_operator (new_op1, VOIDmode))
10435 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10436 ;; subsequent logical operations are used to imitate conditional moves.
10437 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10440 (define_insn "setcc_<mode>_sse"
10441 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10442 (match_operator:MODEF 3 "sse_comparison_operator"
10443 [(match_operand:MODEF 1 "register_operand" "0,x")
10444 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10445 "SSE_FLOAT_MODE_P (<MODE>mode)"
10447 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10448 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10449 [(set_attr "isa" "noavx,avx")
10450 (set_attr "type" "ssecmp")
10451 (set_attr "length_immediate" "1")
10452 (set_attr "prefix" "orig,vex")
10453 (set_attr "mode" "<MODE>")])
10455 ;; Basic conditional jump instructions.
10456 ;; We ignore the overflow flag for signed branch instructions.
10458 (define_insn "*jcc_1"
10460 (if_then_else (match_operator 1 "ix86_comparison_operator"
10461 [(reg FLAGS_REG) (const_int 0)])
10462 (label_ref (match_operand 0 "" ""))
10466 [(set_attr "type" "ibr")
10467 (set_attr "modrm" "0")
10468 (set (attr "length")
10469 (if_then_else (and (ge (minus (match_dup 0) (pc))
10471 (lt (minus (match_dup 0) (pc))
10476 (define_insn "*jcc_2"
10478 (if_then_else (match_operator 1 "ix86_comparison_operator"
10479 [(reg FLAGS_REG) (const_int 0)])
10481 (label_ref (match_operand 0 "" ""))))]
10484 [(set_attr "type" "ibr")
10485 (set_attr "modrm" "0")
10486 (set (attr "length")
10487 (if_then_else (and (ge (minus (match_dup 0) (pc))
10489 (lt (minus (match_dup 0) (pc))
10494 ;; In general it is not safe to assume too much about CCmode registers,
10495 ;; so simplify-rtx stops when it sees a second one. Under certain
10496 ;; conditions this is safe on x86, so help combine not create
10504 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10505 [(reg FLAGS_REG) (const_int 0)])
10507 (label_ref (match_operand 1 "" ""))
10511 (if_then_else (match_dup 0)
10512 (label_ref (match_dup 1))
10514 "PUT_MODE (operands[0], VOIDmode);")
10518 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10519 [(reg FLAGS_REG) (const_int 0)])
10521 (label_ref (match_operand 1 "" ""))
10525 (if_then_else (match_dup 0)
10526 (label_ref (match_dup 1))
10529 rtx new_op0 = copy_rtx (operands[0]);
10530 operands[0] = new_op0;
10531 PUT_MODE (new_op0, VOIDmode);
10532 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10533 GET_MODE (XEXP (new_op0, 0))));
10535 /* Make sure that (a) the CCmode we have for the flags is strong
10536 enough for the reversed compare or (b) we have a valid FP compare. */
10537 if (! ix86_comparison_operator (new_op0, VOIDmode))
10541 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10542 ;; pass generates from shift insn with QImode operand. Actually, the mode
10543 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10544 ;; appropriate modulo of the bit offset value.
10546 (define_insn_and_split "*jcc_bt<mode>"
10548 (if_then_else (match_operator 0 "bt_comparison_operator"
10549 [(zero_extract:SWI48
10550 (match_operand:SWI48 1 "register_operand" "r")
10553 (match_operand:QI 2 "register_operand" "r")))
10555 (label_ref (match_operand 3 "" ""))
10557 (clobber (reg:CC FLAGS_REG))]
10558 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10561 [(set (reg:CCC FLAGS_REG)
10563 (zero_extract:SWI48
10569 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10570 (label_ref (match_dup 3))
10573 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10575 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10578 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10579 ;; also for DImode, this is what combine produces.
10580 (define_insn_and_split "*jcc_bt<mode>_mask"
10582 (if_then_else (match_operator 0 "bt_comparison_operator"
10583 [(zero_extract:SWI48
10584 (match_operand:SWI48 1 "register_operand" "r")
10587 (match_operand:SI 2 "register_operand" "r")
10588 (match_operand:SI 3 "const_int_operand" "n")))])
10589 (label_ref (match_operand 4 "" ""))
10591 (clobber (reg:CC FLAGS_REG))]
10592 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10593 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10594 == GET_MODE_BITSIZE (<MODE>mode)-1"
10597 [(set (reg:CCC FLAGS_REG)
10599 (zero_extract:SWI48
10605 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10606 (label_ref (match_dup 4))
10609 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10611 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10614 (define_insn_and_split "*jcc_btsi_1"
10616 (if_then_else (match_operator 0 "bt_comparison_operator"
10619 (match_operand:SI 1 "register_operand" "r")
10620 (match_operand:QI 2 "register_operand" "r"))
10623 (label_ref (match_operand 3 "" ""))
10625 (clobber (reg:CC FLAGS_REG))]
10626 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10629 [(set (reg:CCC FLAGS_REG)
10637 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10638 (label_ref (match_dup 3))
10641 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10643 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10646 ;; avoid useless masking of bit offset operand
10647 (define_insn_and_split "*jcc_btsi_mask_1"
10650 (match_operator 0 "bt_comparison_operator"
10653 (match_operand:SI 1 "register_operand" "r")
10656 (match_operand:SI 2 "register_operand" "r")
10657 (match_operand:SI 3 "const_int_operand" "n")) 0))
10660 (label_ref (match_operand 4 "" ""))
10662 (clobber (reg:CC FLAGS_REG))]
10663 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10664 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10667 [(set (reg:CCC FLAGS_REG)
10675 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10676 (label_ref (match_dup 4))
10678 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10680 ;; Define combination compare-and-branch fp compare instructions to help
10683 (define_insn "*fp_jcc_1_387"
10685 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10686 [(match_operand 1 "register_operand" "f")
10687 (match_operand 2 "nonimmediate_operand" "fm")])
10688 (label_ref (match_operand 3 "" ""))
10690 (clobber (reg:CCFP FPSR_REG))
10691 (clobber (reg:CCFP FLAGS_REG))
10692 (clobber (match_scratch:HI 4 "=a"))]
10694 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10695 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10696 && SELECT_CC_MODE (GET_CODE (operands[0]),
10697 operands[1], operands[2]) == CCFPmode
10701 (define_insn "*fp_jcc_1r_387"
10703 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10704 [(match_operand 1 "register_operand" "f")
10705 (match_operand 2 "nonimmediate_operand" "fm")])
10707 (label_ref (match_operand 3 "" ""))))
10708 (clobber (reg:CCFP FPSR_REG))
10709 (clobber (reg:CCFP FLAGS_REG))
10710 (clobber (match_scratch:HI 4 "=a"))]
10712 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10713 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10714 && SELECT_CC_MODE (GET_CODE (operands[0]),
10715 operands[1], operands[2]) == CCFPmode
10719 (define_insn "*fp_jcc_2_387"
10721 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10722 [(match_operand 1 "register_operand" "f")
10723 (match_operand 2 "register_operand" "f")])
10724 (label_ref (match_operand 3 "" ""))
10726 (clobber (reg:CCFP FPSR_REG))
10727 (clobber (reg:CCFP FLAGS_REG))
10728 (clobber (match_scratch:HI 4 "=a"))]
10729 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10730 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10734 (define_insn "*fp_jcc_2r_387"
10736 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10737 [(match_operand 1 "register_operand" "f")
10738 (match_operand 2 "register_operand" "f")])
10740 (label_ref (match_operand 3 "" ""))))
10741 (clobber (reg:CCFP FPSR_REG))
10742 (clobber (reg:CCFP FLAGS_REG))
10743 (clobber (match_scratch:HI 4 "=a"))]
10744 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10745 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10749 (define_insn "*fp_jcc_3_387"
10751 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10752 [(match_operand 1 "register_operand" "f")
10753 (match_operand 2 "const0_operand" "")])
10754 (label_ref (match_operand 3 "" ""))
10756 (clobber (reg:CCFP FPSR_REG))
10757 (clobber (reg:CCFP FLAGS_REG))
10758 (clobber (match_scratch:HI 4 "=a"))]
10759 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10760 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10761 && SELECT_CC_MODE (GET_CODE (operands[0]),
10762 operands[1], operands[2]) == CCFPmode
10768 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10769 [(match_operand 1 "register_operand" "")
10770 (match_operand 2 "nonimmediate_operand" "")])
10771 (match_operand 3 "" "")
10772 (match_operand 4 "" "")))
10773 (clobber (reg:CCFP FPSR_REG))
10774 (clobber (reg:CCFP FLAGS_REG))]
10778 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10779 operands[3], operands[4], NULL_RTX, NULL_RTX);
10785 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10786 [(match_operand 1 "register_operand" "")
10787 (match_operand 2 "general_operand" "")])
10788 (match_operand 3 "" "")
10789 (match_operand 4 "" "")))
10790 (clobber (reg:CCFP FPSR_REG))
10791 (clobber (reg:CCFP FLAGS_REG))
10792 (clobber (match_scratch:HI 5 "=a"))]
10796 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10797 operands[3], operands[4], operands[5], NULL_RTX);
10801 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10802 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10803 ;; with a precedence over other operators and is always put in the first
10804 ;; place. Swap condition and operands to match ficom instruction.
10806 (define_insn "*fp_jcc_4_<mode>_387"
10809 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10810 [(match_operator 1 "float_operator"
10811 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10812 (match_operand 3 "register_operand" "f,f")])
10813 (label_ref (match_operand 4 "" ""))
10815 (clobber (reg:CCFP FPSR_REG))
10816 (clobber (reg:CCFP FLAGS_REG))
10817 (clobber (match_scratch:HI 5 "=a,a"))]
10818 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10819 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10820 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10821 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10828 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10829 [(match_operator 1 "float_operator"
10830 [(match_operand:SWI24 2 "memory_operand" "")])
10831 (match_operand 3 "register_operand" "")])
10832 (match_operand 4 "" "")
10833 (match_operand 5 "" "")))
10834 (clobber (reg:CCFP FPSR_REG))
10835 (clobber (reg:CCFP FLAGS_REG))
10836 (clobber (match_scratch:HI 6 "=a"))]
10840 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10842 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10843 operands[3], operands[7],
10844 operands[4], operands[5], operands[6], NULL_RTX);
10848 ;; %%% Kill this when reload knows how to do it.
10852 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10853 [(match_operator 1 "float_operator"
10854 [(match_operand:SWI24 2 "register_operand" "")])
10855 (match_operand 3 "register_operand" "")])
10856 (match_operand 4 "" "")
10857 (match_operand 5 "" "")))
10858 (clobber (reg:CCFP FPSR_REG))
10859 (clobber (reg:CCFP FLAGS_REG))
10860 (clobber (match_scratch:HI 6 "=a"))]
10864 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10865 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10867 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10868 operands[3], operands[7],
10869 operands[4], operands[5], operands[6], operands[2]);
10873 ;; Unconditional and other jump instructions
10875 (define_insn "jump"
10877 (label_ref (match_operand 0 "" "")))]
10880 [(set_attr "type" "ibr")
10881 (set (attr "length")
10882 (if_then_else (and (ge (minus (match_dup 0) (pc))
10884 (lt (minus (match_dup 0) (pc))
10888 (set_attr "modrm" "0")])
10890 (define_expand "indirect_jump"
10891 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
10893 (define_insn "*indirect_jump"
10894 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
10897 [(set_attr "type" "ibr")
10898 (set_attr "length_immediate" "0")])
10900 (define_expand "tablejump"
10901 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
10902 (use (label_ref (match_operand 1 "" "")))])]
10905 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10906 relative. Convert the relative address to an absolute address. */
10910 enum rtx_code code;
10912 /* We can't use @GOTOFF for text labels on VxWorks;
10913 see gotoff_operand. */
10914 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10918 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10920 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10924 op1 = pic_offset_table_rtx;
10929 op0 = pic_offset_table_rtx;
10933 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10936 else if (TARGET_X32)
10937 operands[0] = convert_memory_address (Pmode, operands[0]);
10940 (define_insn "*tablejump_1"
10941 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
10942 (use (label_ref (match_operand 1 "" "")))]
10945 [(set_attr "type" "ibr")
10946 (set_attr "length_immediate" "0")])
10948 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10951 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10952 (set (match_operand:QI 1 "register_operand" "")
10953 (match_operator:QI 2 "ix86_comparison_operator"
10954 [(reg FLAGS_REG) (const_int 0)]))
10955 (set (match_operand 3 "q_regs_operand" "")
10956 (zero_extend (match_dup 1)))]
10957 "(peep2_reg_dead_p (3, operands[1])
10958 || operands_match_p (operands[1], operands[3]))
10959 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10960 [(set (match_dup 4) (match_dup 0))
10961 (set (strict_low_part (match_dup 5))
10964 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10965 operands[5] = gen_lowpart (QImode, operands[3]);
10966 ix86_expand_clear (operands[3]);
10969 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
10972 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10973 (set (match_operand:QI 1 "register_operand" "")
10974 (match_operator:QI 2 "ix86_comparison_operator"
10975 [(reg FLAGS_REG) (const_int 0)]))
10976 (parallel [(set (match_operand 3 "q_regs_operand" "")
10977 (zero_extend (match_dup 1)))
10978 (clobber (reg:CC FLAGS_REG))])]
10979 "(peep2_reg_dead_p (3, operands[1])
10980 || operands_match_p (operands[1], operands[3]))
10981 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10982 [(set (match_dup 4) (match_dup 0))
10983 (set (strict_low_part (match_dup 5))
10986 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10987 operands[5] = gen_lowpart (QImode, operands[3]);
10988 ix86_expand_clear (operands[3]);
10991 ;; Call instructions.
10993 ;; The predicates normally associated with named expanders are not properly
10994 ;; checked for calls. This is a bug in the generic code, but it isn't that
10995 ;; easy to fix. Ignore it for now and be prepared to fix things up.
10997 ;; P6 processors will jump to the address after the decrement when %esp
10998 ;; is used as a call operand, so they will execute return address as a code.
10999 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11001 ;; Register constraint for call instruction.
11002 (define_mode_attr c [(SI "l") (DI "r")])
11004 ;; Call subroutine returning no value.
11006 (define_expand "call"
11007 [(call (match_operand:QI 0 "" "")
11008 (match_operand 1 "" ""))
11009 (use (match_operand 2 "" ""))]
11012 ix86_expand_call (NULL, operands[0], operands[1],
11013 operands[2], NULL, false);
11017 (define_expand "sibcall"
11018 [(call (match_operand:QI 0 "" "")
11019 (match_operand 1 "" ""))
11020 (use (match_operand 2 "" ""))]
11023 ix86_expand_call (NULL, operands[0], operands[1],
11024 operands[2], NULL, true);
11028 (define_insn_and_split "*call_vzeroupper"
11029 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11030 (match_operand 1 "" ""))
11031 (unspec [(match_operand 2 "const_int_operand" "")]
11032 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11033 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11035 "&& reload_completed"
11037 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11038 [(set_attr "type" "call")])
11040 (define_insn "*call"
11041 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11042 (match_operand 1 "" ""))]
11043 "!SIBLING_CALL_P (insn)"
11044 "* return ix86_output_call_insn (insn, operands[0]);"
11045 [(set_attr "type" "call")])
11047 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11049 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11050 (match_operand 1 "" ""))
11051 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11052 (clobber (reg:TI XMM6_REG))
11053 (clobber (reg:TI XMM7_REG))
11054 (clobber (reg:TI XMM8_REG))
11055 (clobber (reg:TI XMM9_REG))
11056 (clobber (reg:TI XMM10_REG))
11057 (clobber (reg:TI XMM11_REG))
11058 (clobber (reg:TI XMM12_REG))
11059 (clobber (reg:TI XMM13_REG))
11060 (clobber (reg:TI XMM14_REG))
11061 (clobber (reg:TI XMM15_REG))
11062 (clobber (reg:DI SI_REG))
11063 (clobber (reg:DI DI_REG))])
11064 (unspec [(match_operand 2 "const_int_operand" "")]
11065 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11066 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11068 "&& reload_completed"
11070 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11071 [(set_attr "type" "call")])
11073 (define_insn "*call_rex64_ms_sysv"
11074 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11075 (match_operand 1 "" ""))
11076 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11077 (clobber (reg:TI XMM6_REG))
11078 (clobber (reg:TI XMM7_REG))
11079 (clobber (reg:TI XMM8_REG))
11080 (clobber (reg:TI XMM9_REG))
11081 (clobber (reg:TI XMM10_REG))
11082 (clobber (reg:TI XMM11_REG))
11083 (clobber (reg:TI XMM12_REG))
11084 (clobber (reg:TI XMM13_REG))
11085 (clobber (reg:TI XMM14_REG))
11086 (clobber (reg:TI XMM15_REG))
11087 (clobber (reg:DI SI_REG))
11088 (clobber (reg:DI DI_REG))]
11089 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11090 "* return ix86_output_call_insn (insn, operands[0]);"
11091 [(set_attr "type" "call")])
11093 (define_insn_and_split "*sibcall_vzeroupper"
11094 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11095 (match_operand 1 "" ""))
11096 (unspec [(match_operand 2 "const_int_operand" "")]
11097 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11098 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11100 "&& reload_completed"
11102 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11103 [(set_attr "type" "call")])
11105 (define_insn "*sibcall"
11106 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11107 (match_operand 1 "" ""))]
11108 "SIBLING_CALL_P (insn)"
11109 "* return ix86_output_call_insn (insn, operands[0]);"
11110 [(set_attr "type" "call")])
11112 (define_expand "call_pop"
11113 [(parallel [(call (match_operand:QI 0 "" "")
11114 (match_operand:SI 1 "" ""))
11115 (set (reg:SI SP_REG)
11116 (plus:SI (reg:SI SP_REG)
11117 (match_operand:SI 3 "" "")))])]
11120 ix86_expand_call (NULL, operands[0], operands[1],
11121 operands[2], operands[3], false);
11125 (define_insn_and_split "*call_pop_vzeroupper"
11127 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11128 (match_operand:SI 1 "" ""))
11129 (set (reg:SI SP_REG)
11130 (plus:SI (reg:SI SP_REG)
11131 (match_operand:SI 2 "immediate_operand" "i")))])
11132 (unspec [(match_operand 3 "const_int_operand" "")]
11133 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11134 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11136 "&& reload_completed"
11138 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11139 [(set_attr "type" "call")])
11141 (define_insn "*call_pop"
11142 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11143 (match_operand 1 "" ""))
11144 (set (reg:SI SP_REG)
11145 (plus:SI (reg:SI SP_REG)
11146 (match_operand:SI 2 "immediate_operand" "i")))]
11147 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11148 "* return ix86_output_call_insn (insn, operands[0]);"
11149 [(set_attr "type" "call")])
11151 (define_insn_and_split "*sibcall_pop_vzeroupper"
11153 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11154 (match_operand 1 "" ""))
11155 (set (reg:SI SP_REG)
11156 (plus:SI (reg:SI SP_REG)
11157 (match_operand:SI 2 "immediate_operand" "i")))])
11158 (unspec [(match_operand 3 "const_int_operand" "")]
11159 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11160 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11162 "&& reload_completed"
11164 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11165 [(set_attr "type" "call")])
11167 (define_insn "*sibcall_pop"
11168 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11169 (match_operand 1 "" ""))
11170 (set (reg:SI SP_REG)
11171 (plus:SI (reg:SI SP_REG)
11172 (match_operand:SI 2 "immediate_operand" "i")))]
11173 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11174 "* return ix86_output_call_insn (insn, operands[0]);"
11175 [(set_attr "type" "call")])
11177 ;; Call subroutine, returning value in operand 0
11179 (define_expand "call_value"
11180 [(set (match_operand 0 "" "")
11181 (call (match_operand:QI 1 "" "")
11182 (match_operand 2 "" "")))
11183 (use (match_operand 3 "" ""))]
11186 ix86_expand_call (operands[0], operands[1], operands[2],
11187 operands[3], NULL, false);
11191 (define_expand "sibcall_value"
11192 [(set (match_operand 0 "" "")
11193 (call (match_operand:QI 1 "" "")
11194 (match_operand 2 "" "")))
11195 (use (match_operand 3 "" ""))]
11198 ix86_expand_call (operands[0], operands[1], operands[2],
11199 operands[3], NULL, true);
11203 (define_insn_and_split "*call_value_vzeroupper"
11204 [(set (match_operand 0 "" "")
11205 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11206 (match_operand 2 "" "")))
11207 (unspec [(match_operand 3 "const_int_operand" "")]
11208 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11209 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11211 "&& reload_completed"
11213 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11214 [(set_attr "type" "callv")])
11216 (define_insn "*call_value"
11217 [(set (match_operand 0 "" "")
11218 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11219 (match_operand 2 "" "")))]
11220 "!SIBLING_CALL_P (insn)"
11221 "* return ix86_output_call_insn (insn, operands[1]);"
11222 [(set_attr "type" "callv")])
11224 (define_insn_and_split "*sibcall_value_vzeroupper"
11225 [(set (match_operand 0 "" "")
11226 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11227 (match_operand 2 "" "")))
11228 (unspec [(match_operand 3 "const_int_operand" "")]
11229 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11230 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11232 "&& reload_completed"
11234 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11235 [(set_attr "type" "callv")])
11237 (define_insn "*sibcall_value"
11238 [(set (match_operand 0 "" "")
11239 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11240 (match_operand 2 "" "")))]
11241 "SIBLING_CALL_P (insn)"
11242 "* return ix86_output_call_insn (insn, operands[1]);"
11243 [(set_attr "type" "callv")])
11245 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11247 [(set (match_operand 0 "" "")
11248 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11249 (match_operand 2 "" "")))
11250 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11251 (clobber (reg:TI XMM6_REG))
11252 (clobber (reg:TI XMM7_REG))
11253 (clobber (reg:TI XMM8_REG))
11254 (clobber (reg:TI XMM9_REG))
11255 (clobber (reg:TI XMM10_REG))
11256 (clobber (reg:TI XMM11_REG))
11257 (clobber (reg:TI XMM12_REG))
11258 (clobber (reg:TI XMM13_REG))
11259 (clobber (reg:TI XMM14_REG))
11260 (clobber (reg:TI XMM15_REG))
11261 (clobber (reg:DI SI_REG))
11262 (clobber (reg:DI DI_REG))])
11263 (unspec [(match_operand 3 "const_int_operand" "")]
11264 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11265 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11267 "&& reload_completed"
11269 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11270 [(set_attr "type" "callv")])
11272 (define_insn "*call_value_rex64_ms_sysv"
11273 [(set (match_operand 0 "" "")
11274 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11275 (match_operand 2 "" "")))
11276 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11277 (clobber (reg:TI XMM6_REG))
11278 (clobber (reg:TI XMM7_REG))
11279 (clobber (reg:TI XMM8_REG))
11280 (clobber (reg:TI XMM9_REG))
11281 (clobber (reg:TI XMM10_REG))
11282 (clobber (reg:TI XMM11_REG))
11283 (clobber (reg:TI XMM12_REG))
11284 (clobber (reg:TI XMM13_REG))
11285 (clobber (reg:TI XMM14_REG))
11286 (clobber (reg:TI XMM15_REG))
11287 (clobber (reg:DI SI_REG))
11288 (clobber (reg:DI DI_REG))]
11289 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11290 "* return ix86_output_call_insn (insn, operands[1]);"
11291 [(set_attr "type" "callv")])
11293 (define_expand "call_value_pop"
11294 [(parallel [(set (match_operand 0 "" "")
11295 (call (match_operand:QI 1 "" "")
11296 (match_operand:SI 2 "" "")))
11297 (set (reg:SI SP_REG)
11298 (plus:SI (reg:SI SP_REG)
11299 (match_operand:SI 4 "" "")))])]
11302 ix86_expand_call (operands[0], operands[1], operands[2],
11303 operands[3], operands[4], false);
11307 (define_insn_and_split "*call_value_pop_vzeroupper"
11309 [(set (match_operand 0 "" "")
11310 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11311 (match_operand 2 "" "")))
11312 (set (reg:SI SP_REG)
11313 (plus:SI (reg:SI SP_REG)
11314 (match_operand:SI 3 "immediate_operand" "i")))])
11315 (unspec [(match_operand 4 "const_int_operand" "")]
11316 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11317 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11319 "&& reload_completed"
11321 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11322 [(set_attr "type" "callv")])
11324 (define_insn "*call_value_pop"
11325 [(set (match_operand 0 "" "")
11326 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11327 (match_operand 2 "" "")))
11328 (set (reg:SI SP_REG)
11329 (plus:SI (reg:SI SP_REG)
11330 (match_operand:SI 3 "immediate_operand" "i")))]
11331 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11332 "* return ix86_output_call_insn (insn, operands[1]);"
11333 [(set_attr "type" "callv")])
11335 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11337 [(set (match_operand 0 "" "")
11338 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11339 (match_operand 2 "" "")))
11340 (set (reg:SI SP_REG)
11341 (plus:SI (reg:SI SP_REG)
11342 (match_operand:SI 3 "immediate_operand" "i")))])
11343 (unspec [(match_operand 4 "const_int_operand" "")]
11344 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11345 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11347 "&& reload_completed"
11349 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11350 [(set_attr "type" "callv")])
11352 (define_insn "*sibcall_value_pop"
11353 [(set (match_operand 0 "" "")
11354 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11355 (match_operand 2 "" "")))
11356 (set (reg:SI SP_REG)
11357 (plus:SI (reg:SI SP_REG)
11358 (match_operand:SI 3 "immediate_operand" "i")))]
11359 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11360 "* return ix86_output_call_insn (insn, operands[1]);"
11361 [(set_attr "type" "callv")])
11363 ;; Call subroutine returning any type.
11365 (define_expand "untyped_call"
11366 [(parallel [(call (match_operand 0 "" "")
11368 (match_operand 1 "" "")
11369 (match_operand 2 "" "")])]
11374 /* In order to give reg-stack an easier job in validating two
11375 coprocessor registers as containing a possible return value,
11376 simply pretend the untyped call returns a complex long double
11379 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11380 and should have the default ABI. */
11382 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11383 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11384 operands[0], const0_rtx,
11385 GEN_INT ((TARGET_64BIT
11386 ? (ix86_abi == SYSV_ABI
11387 ? X86_64_SSE_REGPARM_MAX
11388 : X86_64_MS_SSE_REGPARM_MAX)
11389 : X86_32_SSE_REGPARM_MAX)
11393 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11395 rtx set = XVECEXP (operands[2], 0, i);
11396 emit_move_insn (SET_DEST (set), SET_SRC (set));
11399 /* The optimizer does not know that the call sets the function value
11400 registers we stored in the result block. We avoid problems by
11401 claiming that all hard registers are used and clobbered at this
11403 emit_insn (gen_blockage ());
11408 ;; Prologue and epilogue instructions
11410 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11411 ;; all of memory. This blocks insns from being moved across this point.
11413 (define_insn "blockage"
11414 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11417 [(set_attr "length" "0")])
11419 ;; Do not schedule instructions accessing memory across this point.
11421 (define_expand "memory_blockage"
11422 [(set (match_dup 0)
11423 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11426 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11427 MEM_VOLATILE_P (operands[0]) = 1;
11430 (define_insn "*memory_blockage"
11431 [(set (match_operand:BLK 0 "" "")
11432 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11435 [(set_attr "length" "0")])
11437 ;; As USE insns aren't meaningful after reload, this is used instead
11438 ;; to prevent deleting instructions setting registers for PIC code
11439 (define_insn "prologue_use"
11440 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11443 [(set_attr "length" "0")])
11445 ;; Insn emitted into the body of a function to return from a function.
11446 ;; This is only done if the function's epilogue is known to be simple.
11447 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11449 (define_expand "return"
11451 "ix86_can_use_return_insn_p ()"
11453 if (crtl->args.pops_args)
11455 rtx popc = GEN_INT (crtl->args.pops_args);
11456 emit_jump_insn (gen_return_pop_internal (popc));
11461 (define_insn "return_internal"
11465 [(set_attr "length" "1")
11466 (set_attr "atom_unit" "jeu")
11467 (set_attr "length_immediate" "0")
11468 (set_attr "modrm" "0")])
11470 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11471 ;; instruction Athlon and K8 have.
11473 (define_insn "return_internal_long"
11475 (unspec [(const_int 0)] UNSPEC_REP)]
11478 [(set_attr "length" "2")
11479 (set_attr "atom_unit" "jeu")
11480 (set_attr "length_immediate" "0")
11481 (set_attr "prefix_rep" "1")
11482 (set_attr "modrm" "0")])
11484 (define_insn "return_pop_internal"
11486 (use (match_operand:SI 0 "const_int_operand" ""))]
11489 [(set_attr "length" "3")
11490 (set_attr "atom_unit" "jeu")
11491 (set_attr "length_immediate" "2")
11492 (set_attr "modrm" "0")])
11494 (define_insn "return_indirect_internal"
11496 (use (match_operand:SI 0 "register_operand" "r"))]
11499 [(set_attr "type" "ibr")
11500 (set_attr "length_immediate" "0")])
11506 [(set_attr "length" "1")
11507 (set_attr "length_immediate" "0")
11508 (set_attr "modrm" "0")])
11510 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11511 (define_insn "nops"
11512 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11516 int num = INTVAL (operands[0]);
11518 gcc_assert (num >= 1 && num <= 8);
11521 fputs ("\tnop\n", asm_out_file);
11525 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11526 (set_attr "length_immediate" "0")
11527 (set_attr "modrm" "0")])
11529 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11530 ;; branch prediction penalty for the third jump in a 16-byte
11534 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11537 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11538 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11540 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11541 The align insn is used to avoid 3 jump instructions in the row to improve
11542 branch prediction and the benefits hardly outweigh the cost of extra 8
11543 nops on the average inserted by full alignment pseudo operation. */
11547 [(set_attr "length" "16")])
11549 (define_expand "prologue"
11552 "ix86_expand_prologue (); DONE;")
11554 (define_insn "set_got"
11555 [(set (match_operand:SI 0 "register_operand" "=r")
11556 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11557 (clobber (reg:CC FLAGS_REG))]
11559 "* return output_set_got (operands[0], NULL_RTX);"
11560 [(set_attr "type" "multi")
11561 (set_attr "length" "12")])
11563 (define_insn "set_got_labelled"
11564 [(set (match_operand:SI 0 "register_operand" "=r")
11565 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11567 (clobber (reg:CC FLAGS_REG))]
11569 "* return output_set_got (operands[0], operands[1]);"
11570 [(set_attr "type" "multi")
11571 (set_attr "length" "12")])
11573 (define_insn "set_got_rex64"
11574 [(set (match_operand:DI 0 "register_operand" "=r")
11575 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11577 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11578 [(set_attr "type" "lea")
11579 (set_attr "length_address" "4")
11580 (set_attr "mode" "DI")])
11582 (define_insn "set_rip_rex64"
11583 [(set (match_operand:DI 0 "register_operand" "=r")
11584 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11586 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11587 [(set_attr "type" "lea")
11588 (set_attr "length_address" "4")
11589 (set_attr "mode" "DI")])
11591 (define_insn "set_got_offset_rex64"
11592 [(set (match_operand:DI 0 "register_operand" "=r")
11594 [(label_ref (match_operand 1 "" ""))]
11595 UNSPEC_SET_GOT_OFFSET))]
11597 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11598 [(set_attr "type" "imov")
11599 (set_attr "length_immediate" "0")
11600 (set_attr "length_address" "8")
11601 (set_attr "mode" "DI")])
11603 (define_expand "epilogue"
11606 "ix86_expand_epilogue (1); DONE;")
11608 (define_expand "sibcall_epilogue"
11611 "ix86_expand_epilogue (0); DONE;")
11613 (define_expand "eh_return"
11614 [(use (match_operand 0 "register_operand" ""))]
11617 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11619 /* Tricky bit: we write the address of the handler to which we will
11620 be returning into someone else's stack frame, one word below the
11621 stack address we wish to restore. */
11622 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11623 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11624 tmp = gen_rtx_MEM (Pmode, tmp);
11625 emit_move_insn (tmp, ra);
11627 emit_jump_insn (gen_eh_return_internal ());
11632 (define_insn_and_split "eh_return_internal"
11636 "epilogue_completed"
11638 "ix86_expand_epilogue (2); DONE;")
11640 (define_insn "leave"
11641 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11642 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11643 (clobber (mem:BLK (scratch)))]
11646 [(set_attr "type" "leave")])
11648 (define_insn "leave_rex64"
11649 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11650 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11651 (clobber (mem:BLK (scratch)))]
11654 [(set_attr "type" "leave")])
11656 ;; Handle -fsplit-stack.
11658 (define_expand "split_stack_prologue"
11662 ix86_expand_split_stack_prologue ();
11666 ;; In order to support the call/return predictor, we use a return
11667 ;; instruction which the middle-end doesn't see.
11668 (define_insn "split_stack_return"
11669 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11670 UNSPECV_SPLIT_STACK_RETURN)]
11673 if (operands[0] == const0_rtx)
11678 [(set_attr "atom_unit" "jeu")
11679 (set_attr "modrm" "0")
11680 (set (attr "length")
11681 (if_then_else (match_operand:SI 0 "const0_operand" "")
11684 (set (attr "length_immediate")
11685 (if_then_else (match_operand:SI 0 "const0_operand" "")
11689 ;; If there are operand 0 bytes available on the stack, jump to
11692 (define_expand "split_stack_space_check"
11693 [(set (pc) (if_then_else
11694 (ltu (minus (reg SP_REG)
11695 (match_operand 0 "register_operand" ""))
11696 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11697 (label_ref (match_operand 1 "" ""))
11701 rtx reg, size, limit;
11703 reg = gen_reg_rtx (Pmode);
11704 size = force_reg (Pmode, operands[0]);
11705 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11706 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11707 UNSPEC_STACK_CHECK);
11708 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11709 ix86_expand_branch (GEU, reg, limit, operands[1]);
11714 ;; Bit manipulation instructions.
11716 (define_expand "ffs<mode>2"
11717 [(set (match_dup 2) (const_int -1))
11718 (parallel [(set (reg:CCZ FLAGS_REG)
11720 (match_operand:SWI48 1 "nonimmediate_operand" "")
11722 (set (match_operand:SWI48 0 "register_operand" "")
11723 (ctz:SWI48 (match_dup 1)))])
11724 (set (match_dup 0) (if_then_else:SWI48
11725 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11728 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11729 (clobber (reg:CC FLAGS_REG))])]
11732 if (<MODE>mode == SImode && !TARGET_CMOVE)
11734 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11737 operands[2] = gen_reg_rtx (<MODE>mode);
11740 (define_insn_and_split "ffssi2_no_cmove"
11741 [(set (match_operand:SI 0 "register_operand" "=r")
11742 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11743 (clobber (match_scratch:SI 2 "=&q"))
11744 (clobber (reg:CC FLAGS_REG))]
11747 "&& reload_completed"
11748 [(parallel [(set (reg:CCZ FLAGS_REG)
11749 (compare:CCZ (match_dup 1) (const_int 0)))
11750 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11751 (set (strict_low_part (match_dup 3))
11752 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11753 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11754 (clobber (reg:CC FLAGS_REG))])
11755 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11756 (clobber (reg:CC FLAGS_REG))])
11757 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11758 (clobber (reg:CC FLAGS_REG))])]
11760 operands[3] = gen_lowpart (QImode, operands[2]);
11761 ix86_expand_clear (operands[2]);
11764 (define_insn "*ffs<mode>_1"
11765 [(set (reg:CCZ FLAGS_REG)
11766 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11768 (set (match_operand:SWI48 0 "register_operand" "=r")
11769 (ctz:SWI48 (match_dup 1)))]
11771 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11772 [(set_attr "type" "alu1")
11773 (set_attr "prefix_0f" "1")
11774 (set_attr "mode" "<MODE>")])
11776 (define_insn "ctz<mode>2"
11777 [(set (match_operand:SWI248 0 "register_operand" "=r")
11778 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11779 (clobber (reg:CC FLAGS_REG))]
11783 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11785 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11787 [(set_attr "type" "alu1")
11788 (set_attr "prefix_0f" "1")
11789 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11790 (set_attr "mode" "<MODE>")])
11792 (define_expand "clz<mode>2"
11794 [(set (match_operand:SWI248 0 "register_operand" "")
11797 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11798 (clobber (reg:CC FLAGS_REG))])
11800 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11801 (clobber (reg:CC FLAGS_REG))])]
11806 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11809 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11812 (define_insn "clz<mode>2_abm"
11813 [(set (match_operand:SWI248 0 "register_operand" "=r")
11814 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11815 (clobber (reg:CC FLAGS_REG))]
11816 "TARGET_ABM || TARGET_BMI"
11817 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11818 [(set_attr "prefix_rep" "1")
11819 (set_attr "type" "bitmanip")
11820 (set_attr "mode" "<MODE>")])
11822 ;; BMI instructions.
11823 (define_insn "*bmi_andn_<mode>"
11824 [(set (match_operand:SWI48 0 "register_operand" "=r")
11827 (match_operand:SWI48 1 "register_operand" "r"))
11828 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11829 (clobber (reg:CC FLAGS_REG))]
11831 "andn\t{%2, %1, %0|%0, %1, %2}"
11832 [(set_attr "type" "bitmanip")
11833 (set_attr "mode" "<MODE>")])
11835 (define_insn "bmi_bextr_<mode>"
11836 [(set (match_operand:SWI48 0 "register_operand" "=r")
11837 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11838 (match_operand:SWI48 2 "register_operand" "r")]
11840 (clobber (reg:CC FLAGS_REG))]
11842 "bextr\t{%2, %1, %0|%0, %1, %2}"
11843 [(set_attr "type" "bitmanip")
11844 (set_attr "mode" "<MODE>")])
11846 (define_insn "*bmi_blsi_<mode>"
11847 [(set (match_operand:SWI48 0 "register_operand" "=r")
11850 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11852 (clobber (reg:CC FLAGS_REG))]
11854 "blsi\t{%1, %0|%0, %1}"
11855 [(set_attr "type" "bitmanip")
11856 (set_attr "mode" "<MODE>")])
11858 (define_insn "*bmi_blsmsk_<mode>"
11859 [(set (match_operand:SWI48 0 "register_operand" "=r")
11862 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11865 (clobber (reg:CC FLAGS_REG))]
11867 "blsmsk\t{%1, %0|%0, %1}"
11868 [(set_attr "type" "bitmanip")
11869 (set_attr "mode" "<MODE>")])
11871 (define_insn "*bmi_blsr_<mode>"
11872 [(set (match_operand:SWI48 0 "register_operand" "=r")
11875 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11878 (clobber (reg:CC FLAGS_REG))]
11880 "blsr\t{%1, %0|%0, %1}"
11881 [(set_attr "type" "bitmanip")
11882 (set_attr "mode" "<MODE>")])
11884 ;; TBM instructions.
11885 (define_insn "tbm_bextri_<mode>"
11886 [(set (match_operand:SWI48 0 "register_operand" "=r")
11887 (zero_extract:SWI48
11888 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11889 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11890 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11891 (clobber (reg:CC FLAGS_REG))]
11894 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11895 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11897 [(set_attr "type" "bitmanip")
11898 (set_attr "mode" "<MODE>")])
11900 (define_insn "*tbm_blcfill_<mode>"
11901 [(set (match_operand:SWI48 0 "register_operand" "=r")
11904 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11907 (clobber (reg:CC FLAGS_REG))]
11909 "blcfill\t{%1, %0|%0, %1}"
11910 [(set_attr "type" "bitmanip")
11911 (set_attr "mode" "<MODE>")])
11913 (define_insn "*tbm_blci_<mode>"
11914 [(set (match_operand:SWI48 0 "register_operand" "=r")
11918 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11921 (clobber (reg:CC FLAGS_REG))]
11923 "blci\t{%1, %0|%0, %1}"
11924 [(set_attr "type" "bitmanip")
11925 (set_attr "mode" "<MODE>")])
11927 (define_insn "*tbm_blcic_<mode>"
11928 [(set (match_operand:SWI48 0 "register_operand" "=r")
11931 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11935 (clobber (reg:CC FLAGS_REG))]
11937 "blcic\t{%1, %0|%0, %1}"
11938 [(set_attr "type" "bitmanip")
11939 (set_attr "mode" "<MODE>")])
11941 (define_insn "*tbm_blcmsk_<mode>"
11942 [(set (match_operand:SWI48 0 "register_operand" "=r")
11945 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11948 (clobber (reg:CC FLAGS_REG))]
11950 "blcmsk\t{%1, %0|%0, %1}"
11951 [(set_attr "type" "bitmanip")
11952 (set_attr "mode" "<MODE>")])
11954 (define_insn "*tbm_blcs_<mode>"
11955 [(set (match_operand:SWI48 0 "register_operand" "=r")
11958 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11961 (clobber (reg:CC FLAGS_REG))]
11963 "blcs\t{%1, %0|%0, %1}"
11964 [(set_attr "type" "bitmanip")
11965 (set_attr "mode" "<MODE>")])
11967 (define_insn "*tbm_blsfill_<mode>"
11968 [(set (match_operand:SWI48 0 "register_operand" "=r")
11971 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11974 (clobber (reg:CC FLAGS_REG))]
11976 "blsfill\t{%1, %0|%0, %1}"
11977 [(set_attr "type" "bitmanip")
11978 (set_attr "mode" "<MODE>")])
11980 (define_insn "*tbm_blsic_<mode>"
11981 [(set (match_operand:SWI48 0 "register_operand" "=r")
11984 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11988 (clobber (reg:CC FLAGS_REG))]
11990 "blsic\t{%1, %0|%0, %1}"
11991 [(set_attr "type" "bitmanip")
11992 (set_attr "mode" "<MODE>")])
11994 (define_insn "*tbm_t1mskc_<mode>"
11995 [(set (match_operand:SWI48 0 "register_operand" "=r")
11998 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12002 (clobber (reg:CC FLAGS_REG))]
12004 "t1mskc\t{%1, %0|%0, %1}"
12005 [(set_attr "type" "bitmanip")
12006 (set_attr "mode" "<MODE>")])
12008 (define_insn "*tbm_tzmsk_<mode>"
12009 [(set (match_operand:SWI48 0 "register_operand" "=r")
12012 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12016 (clobber (reg:CC FLAGS_REG))]
12018 "tzmsk\t{%1, %0|%0, %1}"
12019 [(set_attr "type" "bitmanip")
12020 (set_attr "mode" "<MODE>")])
12022 (define_insn "bsr_rex64"
12023 [(set (match_operand:DI 0 "register_operand" "=r")
12024 (minus:DI (const_int 63)
12025 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12026 (clobber (reg:CC FLAGS_REG))]
12028 "bsr{q}\t{%1, %0|%0, %1}"
12029 [(set_attr "type" "alu1")
12030 (set_attr "prefix_0f" "1")
12031 (set_attr "mode" "DI")])
12034 [(set (match_operand:SI 0 "register_operand" "=r")
12035 (minus:SI (const_int 31)
12036 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12037 (clobber (reg:CC FLAGS_REG))]
12039 "bsr{l}\t{%1, %0|%0, %1}"
12040 [(set_attr "type" "alu1")
12041 (set_attr "prefix_0f" "1")
12042 (set_attr "mode" "SI")])
12044 (define_insn "*bsrhi"
12045 [(set (match_operand:HI 0 "register_operand" "=r")
12046 (minus:HI (const_int 15)
12047 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12048 (clobber (reg:CC FLAGS_REG))]
12050 "bsr{w}\t{%1, %0|%0, %1}"
12051 [(set_attr "type" "alu1")
12052 (set_attr "prefix_0f" "1")
12053 (set_attr "mode" "HI")])
12055 (define_insn "popcount<mode>2"
12056 [(set (match_operand:SWI248 0 "register_operand" "=r")
12058 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12059 (clobber (reg:CC FLAGS_REG))]
12063 return "popcnt\t{%1, %0|%0, %1}";
12065 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12068 [(set_attr "prefix_rep" "1")
12069 (set_attr "type" "bitmanip")
12070 (set_attr "mode" "<MODE>")])
12072 (define_insn "*popcount<mode>2_cmp"
12073 [(set (reg FLAGS_REG)
12076 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12078 (set (match_operand:SWI248 0 "register_operand" "=r")
12079 (popcount:SWI248 (match_dup 1)))]
12080 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12083 return "popcnt\t{%1, %0|%0, %1}";
12085 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12088 [(set_attr "prefix_rep" "1")
12089 (set_attr "type" "bitmanip")
12090 (set_attr "mode" "<MODE>")])
12092 (define_insn "*popcountsi2_cmp_zext"
12093 [(set (reg FLAGS_REG)
12095 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12097 (set (match_operand:DI 0 "register_operand" "=r")
12098 (zero_extend:DI(popcount:SI (match_dup 1))))]
12099 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12102 return "popcnt\t{%1, %0|%0, %1}";
12104 return "popcnt{l}\t{%1, %0|%0, %1}";
12107 [(set_attr "prefix_rep" "1")
12108 (set_attr "type" "bitmanip")
12109 (set_attr "mode" "SI")])
12111 (define_expand "bswap<mode>2"
12112 [(set (match_operand:SWI48 0 "register_operand" "")
12113 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12116 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12118 rtx x = operands[0];
12120 emit_move_insn (x, operands[1]);
12121 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12122 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12123 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12128 (define_insn "*bswap<mode>2_movbe"
12129 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12130 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12132 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12135 movbe\t{%1, %0|%0, %1}
12136 movbe\t{%1, %0|%0, %1}"
12137 [(set_attr "type" "bitmanip,imov,imov")
12138 (set_attr "modrm" "0,1,1")
12139 (set_attr "prefix_0f" "*,1,1")
12140 (set_attr "prefix_extra" "*,1,1")
12141 (set_attr "mode" "<MODE>")])
12143 (define_insn "*bswap<mode>2_1"
12144 [(set (match_operand:SWI48 0 "register_operand" "=r")
12145 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12148 [(set_attr "type" "bitmanip")
12149 (set_attr "modrm" "0")
12150 (set_attr "mode" "<MODE>")])
12152 (define_insn "*bswaphi_lowpart_1"
12153 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12154 (bswap:HI (match_dup 0)))
12155 (clobber (reg:CC FLAGS_REG))]
12156 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12158 xchg{b}\t{%h0, %b0|%b0, %h0}
12159 rol{w}\t{$8, %0|%0, 8}"
12160 [(set_attr "length" "2,4")
12161 (set_attr "mode" "QI,HI")])
12163 (define_insn "bswaphi_lowpart"
12164 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12165 (bswap:HI (match_dup 0)))
12166 (clobber (reg:CC FLAGS_REG))]
12168 "rol{w}\t{$8, %0|%0, 8}"
12169 [(set_attr "length" "4")
12170 (set_attr "mode" "HI")])
12172 (define_expand "paritydi2"
12173 [(set (match_operand:DI 0 "register_operand" "")
12174 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12177 rtx scratch = gen_reg_rtx (QImode);
12180 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12181 NULL_RTX, operands[1]));
12183 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12184 gen_rtx_REG (CCmode, FLAGS_REG),
12186 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12189 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12192 rtx tmp = gen_reg_rtx (SImode);
12194 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12195 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12200 (define_expand "paritysi2"
12201 [(set (match_operand:SI 0 "register_operand" "")
12202 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12205 rtx scratch = gen_reg_rtx (QImode);
12208 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12210 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12211 gen_rtx_REG (CCmode, FLAGS_REG),
12213 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12215 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12219 (define_insn_and_split "paritydi2_cmp"
12220 [(set (reg:CC FLAGS_REG)
12221 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12223 (clobber (match_scratch:DI 0 "=r"))
12224 (clobber (match_scratch:SI 1 "=&r"))
12225 (clobber (match_scratch:HI 2 "=Q"))]
12228 "&& reload_completed"
12230 [(set (match_dup 1)
12231 (xor:SI (match_dup 1) (match_dup 4)))
12232 (clobber (reg:CC FLAGS_REG))])
12234 [(set (reg:CC FLAGS_REG)
12235 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12236 (clobber (match_dup 1))
12237 (clobber (match_dup 2))])]
12239 operands[4] = gen_lowpart (SImode, operands[3]);
12243 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12244 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12247 operands[1] = gen_highpart (SImode, operands[3]);
12250 (define_insn_and_split "paritysi2_cmp"
12251 [(set (reg:CC FLAGS_REG)
12252 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12254 (clobber (match_scratch:SI 0 "=r"))
12255 (clobber (match_scratch:HI 1 "=&Q"))]
12258 "&& reload_completed"
12260 [(set (match_dup 1)
12261 (xor:HI (match_dup 1) (match_dup 3)))
12262 (clobber (reg:CC FLAGS_REG))])
12264 [(set (reg:CC FLAGS_REG)
12265 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12266 (clobber (match_dup 1))])]
12268 operands[3] = gen_lowpart (HImode, operands[2]);
12270 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12271 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12274 (define_insn "*parityhi2_cmp"
12275 [(set (reg:CC FLAGS_REG)
12276 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12278 (clobber (match_scratch:HI 0 "=Q"))]
12280 "xor{b}\t{%h0, %b0|%b0, %h0}"
12281 [(set_attr "length" "2")
12282 (set_attr "mode" "HI")])
12284 ;; Thread-local storage patterns for ELF.
12286 ;; Note that these code sequences must appear exactly as shown
12287 ;; in order to allow linker relaxation.
12289 (define_insn "*tls_global_dynamic_32_gnu"
12290 [(set (match_operand:SI 0 "register_operand" "=a")
12292 [(match_operand:SI 1 "register_operand" "b")
12293 (match_operand:SI 2 "tls_symbolic_operand" "")
12294 (match_operand:SI 3 "constant_call_address_operand" "z")]
12296 (clobber (match_scratch:SI 4 "=d"))
12297 (clobber (match_scratch:SI 5 "=c"))
12298 (clobber (reg:CC FLAGS_REG))]
12299 "!TARGET_64BIT && TARGET_GNU_TLS"
12302 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12303 if (TARGET_SUN_TLS)
12304 #ifdef HAVE_AS_IX86_TLSGDPLT
12305 return "call\t%a2@tlsgdplt";
12307 return "call\t%p3@plt";
12309 return "call\t%P3";
12311 [(set_attr "type" "multi")
12312 (set_attr "length" "12")])
12314 (define_expand "tls_global_dynamic_32"
12316 [(set (match_operand:SI 0 "register_operand" "")
12317 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12318 (match_operand:SI 1 "tls_symbolic_operand" "")
12319 (match_operand:SI 3 "constant_call_address_operand" "")]
12321 (clobber (match_scratch:SI 4 ""))
12322 (clobber (match_scratch:SI 5 ""))
12323 (clobber (reg:CC FLAGS_REG))])])
12325 (define_insn "*tls_global_dynamic_64"
12326 [(set (match_operand:DI 0 "register_operand" "=a")
12328 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12329 (match_operand:DI 3 "" "")))
12330 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12335 fputs (ASM_BYTE "0x66\n", asm_out_file);
12337 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12338 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12339 fputs ("\trex64\n", asm_out_file);
12340 if (TARGET_SUN_TLS)
12341 return "call\t%p2@plt";
12342 return "call\t%P2";
12344 [(set_attr "type" "multi")
12345 (set (attr "length")
12346 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12348 (define_expand "tls_global_dynamic_64"
12350 [(set (match_operand:DI 0 "register_operand" "")
12352 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12354 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12357 (define_insn "*tls_local_dynamic_base_32_gnu"
12358 [(set (match_operand:SI 0 "register_operand" "=a")
12360 [(match_operand:SI 1 "register_operand" "b")
12361 (match_operand:SI 2 "constant_call_address_operand" "z")]
12362 UNSPEC_TLS_LD_BASE))
12363 (clobber (match_scratch:SI 3 "=d"))
12364 (clobber (match_scratch:SI 4 "=c"))
12365 (clobber (reg:CC FLAGS_REG))]
12366 "!TARGET_64BIT && TARGET_GNU_TLS"
12369 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12370 if (TARGET_SUN_TLS)
12371 #ifdef HAVE_AS_IX86_TLSLDMPLT
12372 return "call\t%&@tlsldmplt";
12374 return "call\t%p2@plt";
12376 return "call\t%P2";
12378 [(set_attr "type" "multi")
12379 (set_attr "length" "11")])
12381 (define_expand "tls_local_dynamic_base_32"
12383 [(set (match_operand:SI 0 "register_operand" "")
12385 [(match_operand:SI 1 "register_operand" "")
12386 (match_operand:SI 2 "constant_call_address_operand" "")]
12387 UNSPEC_TLS_LD_BASE))
12388 (clobber (match_scratch:SI 3 ""))
12389 (clobber (match_scratch:SI 4 ""))
12390 (clobber (reg:CC FLAGS_REG))])])
12392 (define_insn "*tls_local_dynamic_base_64"
12393 [(set (match_operand:DI 0 "register_operand" "=a")
12395 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12396 (match_operand:DI 2 "" "")))
12397 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12401 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12402 if (TARGET_SUN_TLS)
12403 return "call\t%p1@plt";
12404 return "call\t%P1";
12406 [(set_attr "type" "multi")
12407 (set_attr "length" "12")])
12409 (define_expand "tls_local_dynamic_base_64"
12411 [(set (match_operand:DI 0 "register_operand" "")
12413 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12415 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12417 ;; Local dynamic of a single variable is a lose. Show combine how
12418 ;; to convert that back to global dynamic.
12420 (define_insn_and_split "*tls_local_dynamic_32_once"
12421 [(set (match_operand:SI 0 "register_operand" "=a")
12423 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12424 (match_operand:SI 2 "constant_call_address_operand" "z")]
12425 UNSPEC_TLS_LD_BASE)
12426 (const:SI (unspec:SI
12427 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12429 (clobber (match_scratch:SI 4 "=d"))
12430 (clobber (match_scratch:SI 5 "=c"))
12431 (clobber (reg:CC FLAGS_REG))]
12436 [(set (match_dup 0)
12437 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12439 (clobber (match_dup 4))
12440 (clobber (match_dup 5))
12441 (clobber (reg:CC FLAGS_REG))])])
12443 ;; Segment register for the thread base ptr load
12444 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12446 ;; Load and add the thread base pointer from %<tp_seg>:0.
12447 (define_insn "*load_tp_<mode>"
12448 [(set (match_operand:P 0 "register_operand" "=r")
12449 (unspec:P [(const_int 0)] UNSPEC_TP))]
12451 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12452 [(set_attr "type" "imov")
12453 (set_attr "modrm" "0")
12454 (set_attr "length" "7")
12455 (set_attr "memory" "load")
12456 (set_attr "imm_disp" "false")])
12458 (define_insn "*add_tp_<mode>"
12459 [(set (match_operand:P 0 "register_operand" "=r")
12460 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12461 (match_operand:P 1 "register_operand" "0")))
12462 (clobber (reg:CC FLAGS_REG))]
12464 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12465 [(set_attr "type" "alu")
12466 (set_attr "modrm" "0")
12467 (set_attr "length" "7")
12468 (set_attr "memory" "load")
12469 (set_attr "imm_disp" "false")])
12471 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12472 ;; %rax as destination of the initial executable code sequence.
12473 (define_insn "tls_initial_exec_64_sun"
12474 [(set (match_operand:DI 0 "register_operand" "=a")
12476 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12477 UNSPEC_TLS_IE_SUN))
12478 (clobber (reg:CC FLAGS_REG))]
12479 "TARGET_64BIT && TARGET_SUN_TLS"
12482 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12483 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12485 [(set_attr "type" "multi")])
12487 ;; GNU2 TLS patterns can be split.
12489 (define_expand "tls_dynamic_gnu2_32"
12490 [(set (match_dup 3)
12491 (plus:SI (match_operand:SI 2 "register_operand" "")
12493 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12496 [(set (match_operand:SI 0 "register_operand" "")
12497 (unspec:SI [(match_dup 1) (match_dup 3)
12498 (match_dup 2) (reg:SI SP_REG)]
12500 (clobber (reg:CC FLAGS_REG))])]
12501 "!TARGET_64BIT && TARGET_GNU2_TLS"
12503 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12504 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12507 (define_insn "*tls_dynamic_gnu2_lea_32"
12508 [(set (match_operand:SI 0 "register_operand" "=r")
12509 (plus:SI (match_operand:SI 1 "register_operand" "b")
12511 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12512 UNSPEC_TLSDESC))))]
12513 "!TARGET_64BIT && TARGET_GNU2_TLS"
12514 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12515 [(set_attr "type" "lea")
12516 (set_attr "mode" "SI")
12517 (set_attr "length" "6")
12518 (set_attr "length_address" "4")])
12520 (define_insn "*tls_dynamic_gnu2_call_32"
12521 [(set (match_operand:SI 0 "register_operand" "=a")
12522 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12523 (match_operand:SI 2 "register_operand" "0")
12524 ;; we have to make sure %ebx still points to the GOT
12525 (match_operand:SI 3 "register_operand" "b")
12528 (clobber (reg:CC FLAGS_REG))]
12529 "!TARGET_64BIT && TARGET_GNU2_TLS"
12530 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12531 [(set_attr "type" "call")
12532 (set_attr "length" "2")
12533 (set_attr "length_address" "0")])
12535 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12536 [(set (match_operand:SI 0 "register_operand" "=&a")
12538 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12539 (match_operand:SI 4 "" "")
12540 (match_operand:SI 2 "register_operand" "b")
12543 (const:SI (unspec:SI
12544 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12546 (clobber (reg:CC FLAGS_REG))]
12547 "!TARGET_64BIT && TARGET_GNU2_TLS"
12550 [(set (match_dup 0) (match_dup 5))]
12552 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12553 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12556 (define_expand "tls_dynamic_gnu2_64"
12557 [(set (match_dup 2)
12558 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12561 [(set (match_operand:DI 0 "register_operand" "")
12562 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12564 (clobber (reg:CC FLAGS_REG))])]
12565 "TARGET_64BIT && TARGET_GNU2_TLS"
12567 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12568 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12571 (define_insn "*tls_dynamic_gnu2_lea_64"
12572 [(set (match_operand:DI 0 "register_operand" "=r")
12573 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12575 "TARGET_64BIT && TARGET_GNU2_TLS"
12576 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12577 [(set_attr "type" "lea")
12578 (set_attr "mode" "DI")
12579 (set_attr "length" "7")
12580 (set_attr "length_address" "4")])
12582 (define_insn "*tls_dynamic_gnu2_call_64"
12583 [(set (match_operand:DI 0 "register_operand" "=a")
12584 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12585 (match_operand:DI 2 "register_operand" "0")
12588 (clobber (reg:CC FLAGS_REG))]
12589 "TARGET_64BIT && TARGET_GNU2_TLS"
12590 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12591 [(set_attr "type" "call")
12592 (set_attr "length" "2")
12593 (set_attr "length_address" "0")])
12595 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12596 [(set (match_operand:DI 0 "register_operand" "=&a")
12598 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12599 (match_operand:DI 3 "" "")
12602 (const:DI (unspec:DI
12603 [(match_operand 1 "tls_symbolic_operand" "")]
12605 (clobber (reg:CC FLAGS_REG))]
12606 "TARGET_64BIT && TARGET_GNU2_TLS"
12609 [(set (match_dup 0) (match_dup 4))]
12611 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12612 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12615 ;; These patterns match the binary 387 instructions for addM3, subM3,
12616 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12617 ;; SFmode. The first is the normal insn, the second the same insn but
12618 ;; with one operand a conversion, and the third the same insn but with
12619 ;; the other operand a conversion. The conversion may be SFmode or
12620 ;; SImode if the target mode DFmode, but only SImode if the target mode
12623 ;; Gcc is slightly more smart about handling normal two address instructions
12624 ;; so use special patterns for add and mull.
12626 (define_insn "*fop_<mode>_comm_mixed"
12627 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12628 (match_operator:MODEF 3 "binary_fp_operator"
12629 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12630 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12631 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12632 && COMMUTATIVE_ARITH_P (operands[3])
12633 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12634 "* return output_387_binary_op (insn, operands);"
12635 [(set (attr "type")
12636 (if_then_else (eq_attr "alternative" "1,2")
12637 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12638 (const_string "ssemul")
12639 (const_string "sseadd"))
12640 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12641 (const_string "fmul")
12642 (const_string "fop"))))
12643 (set_attr "isa" "*,noavx,avx")
12644 (set_attr "prefix" "orig,orig,vex")
12645 (set_attr "mode" "<MODE>")])
12647 (define_insn "*fop_<mode>_comm_sse"
12648 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12649 (match_operator:MODEF 3 "binary_fp_operator"
12650 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12651 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12652 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12653 && COMMUTATIVE_ARITH_P (operands[3])
12654 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12655 "* return output_387_binary_op (insn, operands);"
12656 [(set (attr "type")
12657 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12658 (const_string "ssemul")
12659 (const_string "sseadd")))
12660 (set_attr "isa" "noavx,avx")
12661 (set_attr "prefix" "orig,vex")
12662 (set_attr "mode" "<MODE>")])
12664 (define_insn "*fop_<mode>_comm_i387"
12665 [(set (match_operand:MODEF 0 "register_operand" "=f")
12666 (match_operator:MODEF 3 "binary_fp_operator"
12667 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12668 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12669 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12670 && COMMUTATIVE_ARITH_P (operands[3])
12671 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12672 "* return output_387_binary_op (insn, operands);"
12673 [(set (attr "type")
12674 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12675 (const_string "fmul")
12676 (const_string "fop")))
12677 (set_attr "mode" "<MODE>")])
12679 (define_insn "*fop_<mode>_1_mixed"
12680 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12681 (match_operator:MODEF 3 "binary_fp_operator"
12682 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12683 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12684 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12685 && !COMMUTATIVE_ARITH_P (operands[3])
12686 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12687 "* return output_387_binary_op (insn, operands);"
12688 [(set (attr "type")
12689 (cond [(and (eq_attr "alternative" "2,3")
12690 (match_operand:MODEF 3 "mult_operator" ""))
12691 (const_string "ssemul")
12692 (and (eq_attr "alternative" "2,3")
12693 (match_operand:MODEF 3 "div_operator" ""))
12694 (const_string "ssediv")
12695 (eq_attr "alternative" "2,3")
12696 (const_string "sseadd")
12697 (match_operand:MODEF 3 "mult_operator" "")
12698 (const_string "fmul")
12699 (match_operand:MODEF 3 "div_operator" "")
12700 (const_string "fdiv")
12702 (const_string "fop")))
12703 (set_attr "isa" "*,*,noavx,avx")
12704 (set_attr "prefix" "orig,orig,orig,vex")
12705 (set_attr "mode" "<MODE>")])
12707 (define_insn "*rcpsf2_sse"
12708 [(set (match_operand:SF 0 "register_operand" "=x")
12709 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12712 "%vrcpss\t{%1, %d0|%d0, %1}"
12713 [(set_attr "type" "sse")
12714 (set_attr "atom_sse_attr" "rcp")
12715 (set_attr "prefix" "maybe_vex")
12716 (set_attr "mode" "SF")])
12718 (define_insn "*fop_<mode>_1_sse"
12719 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12720 (match_operator:MODEF 3 "binary_fp_operator"
12721 [(match_operand:MODEF 1 "register_operand" "0,x")
12722 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12723 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12724 && !COMMUTATIVE_ARITH_P (operands[3])"
12725 "* return output_387_binary_op (insn, operands);"
12726 [(set (attr "type")
12727 (cond [(match_operand:MODEF 3 "mult_operator" "")
12728 (const_string "ssemul")
12729 (match_operand:MODEF 3 "div_operator" "")
12730 (const_string "ssediv")
12732 (const_string "sseadd")))
12733 (set_attr "isa" "noavx,avx")
12734 (set_attr "prefix" "orig,vex")
12735 (set_attr "mode" "<MODE>")])
12737 ;; This pattern is not fully shadowed by the pattern above.
12738 (define_insn "*fop_<mode>_1_i387"
12739 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12740 (match_operator:MODEF 3 "binary_fp_operator"
12741 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12742 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12743 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12744 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12745 && !COMMUTATIVE_ARITH_P (operands[3])
12746 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12747 "* return output_387_binary_op (insn, operands);"
12748 [(set (attr "type")
12749 (cond [(match_operand:MODEF 3 "mult_operator" "")
12750 (const_string "fmul")
12751 (match_operand:MODEF 3 "div_operator" "")
12752 (const_string "fdiv")
12754 (const_string "fop")))
12755 (set_attr "mode" "<MODE>")])
12757 ;; ??? Add SSE splitters for these!
12758 (define_insn "*fop_<MODEF:mode>_2_i387"
12759 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12760 (match_operator:MODEF 3 "binary_fp_operator"
12762 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12763 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12764 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12765 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12766 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12767 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12768 [(set (attr "type")
12769 (cond [(match_operand:MODEF 3 "mult_operator" "")
12770 (const_string "fmul")
12771 (match_operand:MODEF 3 "div_operator" "")
12772 (const_string "fdiv")
12774 (const_string "fop")))
12775 (set_attr "fp_int_src" "true")
12776 (set_attr "mode" "<SWI24:MODE>")])
12778 (define_insn "*fop_<MODEF:mode>_3_i387"
12779 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12780 (match_operator:MODEF 3 "binary_fp_operator"
12781 [(match_operand:MODEF 1 "register_operand" "0,0")
12783 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12784 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12785 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12786 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12787 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12788 [(set (attr "type")
12789 (cond [(match_operand:MODEF 3 "mult_operator" "")
12790 (const_string "fmul")
12791 (match_operand:MODEF 3 "div_operator" "")
12792 (const_string "fdiv")
12794 (const_string "fop")))
12795 (set_attr "fp_int_src" "true")
12796 (set_attr "mode" "<MODE>")])
12798 (define_insn "*fop_df_4_i387"
12799 [(set (match_operand:DF 0 "register_operand" "=f,f")
12800 (match_operator:DF 3 "binary_fp_operator"
12802 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12803 (match_operand:DF 2 "register_operand" "0,f")]))]
12804 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12805 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12806 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12807 "* return output_387_binary_op (insn, operands);"
12808 [(set (attr "type")
12809 (cond [(match_operand:DF 3 "mult_operator" "")
12810 (const_string "fmul")
12811 (match_operand:DF 3 "div_operator" "")
12812 (const_string "fdiv")
12814 (const_string "fop")))
12815 (set_attr "mode" "SF")])
12817 (define_insn "*fop_df_5_i387"
12818 [(set (match_operand:DF 0 "register_operand" "=f,f")
12819 (match_operator:DF 3 "binary_fp_operator"
12820 [(match_operand:DF 1 "register_operand" "0,f")
12822 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12823 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12824 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12825 "* return output_387_binary_op (insn, operands);"
12826 [(set (attr "type")
12827 (cond [(match_operand:DF 3 "mult_operator" "")
12828 (const_string "fmul")
12829 (match_operand:DF 3 "div_operator" "")
12830 (const_string "fdiv")
12832 (const_string "fop")))
12833 (set_attr "mode" "SF")])
12835 (define_insn "*fop_df_6_i387"
12836 [(set (match_operand:DF 0 "register_operand" "=f,f")
12837 (match_operator:DF 3 "binary_fp_operator"
12839 (match_operand:SF 1 "register_operand" "0,f"))
12841 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12842 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12843 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12844 "* return output_387_binary_op (insn, operands);"
12845 [(set (attr "type")
12846 (cond [(match_operand:DF 3 "mult_operator" "")
12847 (const_string "fmul")
12848 (match_operand:DF 3 "div_operator" "")
12849 (const_string "fdiv")
12851 (const_string "fop")))
12852 (set_attr "mode" "SF")])
12854 (define_insn "*fop_xf_comm_i387"
12855 [(set (match_operand:XF 0 "register_operand" "=f")
12856 (match_operator:XF 3 "binary_fp_operator"
12857 [(match_operand:XF 1 "register_operand" "%0")
12858 (match_operand:XF 2 "register_operand" "f")]))]
12860 && COMMUTATIVE_ARITH_P (operands[3])"
12861 "* return output_387_binary_op (insn, operands);"
12862 [(set (attr "type")
12863 (if_then_else (match_operand:XF 3 "mult_operator" "")
12864 (const_string "fmul")
12865 (const_string "fop")))
12866 (set_attr "mode" "XF")])
12868 (define_insn "*fop_xf_1_i387"
12869 [(set (match_operand:XF 0 "register_operand" "=f,f")
12870 (match_operator:XF 3 "binary_fp_operator"
12871 [(match_operand:XF 1 "register_operand" "0,f")
12872 (match_operand:XF 2 "register_operand" "f,0")]))]
12874 && !COMMUTATIVE_ARITH_P (operands[3])"
12875 "* return output_387_binary_op (insn, operands);"
12876 [(set (attr "type")
12877 (cond [(match_operand:XF 3 "mult_operator" "")
12878 (const_string "fmul")
12879 (match_operand:XF 3 "div_operator" "")
12880 (const_string "fdiv")
12882 (const_string "fop")))
12883 (set_attr "mode" "XF")])
12885 (define_insn "*fop_xf_2_i387"
12886 [(set (match_operand:XF 0 "register_operand" "=f,f")
12887 (match_operator:XF 3 "binary_fp_operator"
12889 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12890 (match_operand:XF 2 "register_operand" "0,0")]))]
12891 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12892 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12893 [(set (attr "type")
12894 (cond [(match_operand:XF 3 "mult_operator" "")
12895 (const_string "fmul")
12896 (match_operand:XF 3 "div_operator" "")
12897 (const_string "fdiv")
12899 (const_string "fop")))
12900 (set_attr "fp_int_src" "true")
12901 (set_attr "mode" "<MODE>")])
12903 (define_insn "*fop_xf_3_i387"
12904 [(set (match_operand:XF 0 "register_operand" "=f,f")
12905 (match_operator:XF 3 "binary_fp_operator"
12906 [(match_operand:XF 1 "register_operand" "0,0")
12908 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12909 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12910 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12911 [(set (attr "type")
12912 (cond [(match_operand:XF 3 "mult_operator" "")
12913 (const_string "fmul")
12914 (match_operand:XF 3 "div_operator" "")
12915 (const_string "fdiv")
12917 (const_string "fop")))
12918 (set_attr "fp_int_src" "true")
12919 (set_attr "mode" "<MODE>")])
12921 (define_insn "*fop_xf_4_i387"
12922 [(set (match_operand:XF 0 "register_operand" "=f,f")
12923 (match_operator:XF 3 "binary_fp_operator"
12925 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12926 (match_operand:XF 2 "register_operand" "0,f")]))]
12928 "* return output_387_binary_op (insn, operands);"
12929 [(set (attr "type")
12930 (cond [(match_operand:XF 3 "mult_operator" "")
12931 (const_string "fmul")
12932 (match_operand:XF 3 "div_operator" "")
12933 (const_string "fdiv")
12935 (const_string "fop")))
12936 (set_attr "mode" "<MODE>")])
12938 (define_insn "*fop_xf_5_i387"
12939 [(set (match_operand:XF 0 "register_operand" "=f,f")
12940 (match_operator:XF 3 "binary_fp_operator"
12941 [(match_operand:XF 1 "register_operand" "0,f")
12943 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12945 "* return output_387_binary_op (insn, operands);"
12946 [(set (attr "type")
12947 (cond [(match_operand:XF 3 "mult_operator" "")
12948 (const_string "fmul")
12949 (match_operand:XF 3 "div_operator" "")
12950 (const_string "fdiv")
12952 (const_string "fop")))
12953 (set_attr "mode" "<MODE>")])
12955 (define_insn "*fop_xf_6_i387"
12956 [(set (match_operand:XF 0 "register_operand" "=f,f")
12957 (match_operator:XF 3 "binary_fp_operator"
12959 (match_operand:MODEF 1 "register_operand" "0,f"))
12961 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12963 "* return output_387_binary_op (insn, operands);"
12964 [(set (attr "type")
12965 (cond [(match_operand:XF 3 "mult_operator" "")
12966 (const_string "fmul")
12967 (match_operand:XF 3 "div_operator" "")
12968 (const_string "fdiv")
12970 (const_string "fop")))
12971 (set_attr "mode" "<MODE>")])
12974 [(set (match_operand 0 "register_operand" "")
12975 (match_operator 3 "binary_fp_operator"
12976 [(float (match_operand:SWI24 1 "register_operand" ""))
12977 (match_operand 2 "register_operand" "")]))]
12979 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12980 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12983 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12984 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12985 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12986 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12987 GET_MODE (operands[3]),
12990 ix86_free_from_memory (GET_MODE (operands[1]));
12995 [(set (match_operand 0 "register_operand" "")
12996 (match_operator 3 "binary_fp_operator"
12997 [(match_operand 1 "register_operand" "")
12998 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13000 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13001 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13004 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13005 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13006 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13007 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13008 GET_MODE (operands[3]),
13011 ix86_free_from_memory (GET_MODE (operands[2]));
13015 ;; FPU special functions.
13017 ;; This pattern implements a no-op XFmode truncation for
13018 ;; all fancy i386 XFmode math functions.
13020 (define_insn "truncxf<mode>2_i387_noop_unspec"
13021 [(set (match_operand:MODEF 0 "register_operand" "=f")
13022 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13023 UNSPEC_TRUNC_NOOP))]
13024 "TARGET_USE_FANCY_MATH_387"
13025 "* return output_387_reg_move (insn, operands);"
13026 [(set_attr "type" "fmov")
13027 (set_attr "mode" "<MODE>")])
13029 (define_insn "sqrtxf2"
13030 [(set (match_operand:XF 0 "register_operand" "=f")
13031 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13032 "TARGET_USE_FANCY_MATH_387"
13034 [(set_attr "type" "fpspc")
13035 (set_attr "mode" "XF")
13036 (set_attr "athlon_decode" "direct")
13037 (set_attr "amdfam10_decode" "direct")
13038 (set_attr "bdver1_decode" "direct")])
13040 (define_insn "sqrt_extend<mode>xf2_i387"
13041 [(set (match_operand:XF 0 "register_operand" "=f")
13044 (match_operand:MODEF 1 "register_operand" "0"))))]
13045 "TARGET_USE_FANCY_MATH_387"
13047 [(set_attr "type" "fpspc")
13048 (set_attr "mode" "XF")
13049 (set_attr "athlon_decode" "direct")
13050 (set_attr "amdfam10_decode" "direct")
13051 (set_attr "bdver1_decode" "direct")])
13053 (define_insn "*rsqrtsf2_sse"
13054 [(set (match_operand:SF 0 "register_operand" "=x")
13055 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13058 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13059 [(set_attr "type" "sse")
13060 (set_attr "atom_sse_attr" "rcp")
13061 (set_attr "prefix" "maybe_vex")
13062 (set_attr "mode" "SF")])
13064 (define_expand "rsqrtsf2"
13065 [(set (match_operand:SF 0 "register_operand" "")
13066 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13070 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13074 (define_insn "*sqrt<mode>2_sse"
13075 [(set (match_operand:MODEF 0 "register_operand" "=x")
13077 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13078 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13079 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13080 [(set_attr "type" "sse")
13081 (set_attr "atom_sse_attr" "sqrt")
13082 (set_attr "prefix" "maybe_vex")
13083 (set_attr "mode" "<MODE>")
13084 (set_attr "athlon_decode" "*")
13085 (set_attr "amdfam10_decode" "*")
13086 (set_attr "bdver1_decode" "*")])
13088 (define_expand "sqrt<mode>2"
13089 [(set (match_operand:MODEF 0 "register_operand" "")
13091 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13092 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13093 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13095 if (<MODE>mode == SFmode
13096 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13097 && flag_finite_math_only && !flag_trapping_math
13098 && flag_unsafe_math_optimizations)
13100 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13104 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13106 rtx op0 = gen_reg_rtx (XFmode);
13107 rtx op1 = force_reg (<MODE>mode, operands[1]);
13109 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13110 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13115 (define_insn "fpremxf4_i387"
13116 [(set (match_operand:XF 0 "register_operand" "=f")
13117 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13118 (match_operand:XF 3 "register_operand" "1")]
13120 (set (match_operand:XF 1 "register_operand" "=u")
13121 (unspec:XF [(match_dup 2) (match_dup 3)]
13123 (set (reg:CCFP FPSR_REG)
13124 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13126 "TARGET_USE_FANCY_MATH_387"
13128 [(set_attr "type" "fpspc")
13129 (set_attr "mode" "XF")])
13131 (define_expand "fmodxf3"
13132 [(use (match_operand:XF 0 "register_operand" ""))
13133 (use (match_operand:XF 1 "general_operand" ""))
13134 (use (match_operand:XF 2 "general_operand" ""))]
13135 "TARGET_USE_FANCY_MATH_387"
13137 rtx label = gen_label_rtx ();
13139 rtx op1 = gen_reg_rtx (XFmode);
13140 rtx op2 = gen_reg_rtx (XFmode);
13142 emit_move_insn (op2, operands[2]);
13143 emit_move_insn (op1, operands[1]);
13145 emit_label (label);
13146 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13147 ix86_emit_fp_unordered_jump (label);
13148 LABEL_NUSES (label) = 1;
13150 emit_move_insn (operands[0], op1);
13154 (define_expand "fmod<mode>3"
13155 [(use (match_operand:MODEF 0 "register_operand" ""))
13156 (use (match_operand:MODEF 1 "general_operand" ""))
13157 (use (match_operand:MODEF 2 "general_operand" ""))]
13158 "TARGET_USE_FANCY_MATH_387"
13160 rtx (*gen_truncxf) (rtx, rtx);
13162 rtx label = gen_label_rtx ();
13164 rtx op1 = gen_reg_rtx (XFmode);
13165 rtx op2 = gen_reg_rtx (XFmode);
13167 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13168 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13170 emit_label (label);
13171 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13172 ix86_emit_fp_unordered_jump (label);
13173 LABEL_NUSES (label) = 1;
13175 /* Truncate the result properly for strict SSE math. */
13176 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13177 && !TARGET_MIX_SSE_I387)
13178 gen_truncxf = gen_truncxf<mode>2;
13180 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13182 emit_insn (gen_truncxf (operands[0], op1));
13186 (define_insn "fprem1xf4_i387"
13187 [(set (match_operand:XF 0 "register_operand" "=f")
13188 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13189 (match_operand:XF 3 "register_operand" "1")]
13191 (set (match_operand:XF 1 "register_operand" "=u")
13192 (unspec:XF [(match_dup 2) (match_dup 3)]
13194 (set (reg:CCFP FPSR_REG)
13195 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13197 "TARGET_USE_FANCY_MATH_387"
13199 [(set_attr "type" "fpspc")
13200 (set_attr "mode" "XF")])
13202 (define_expand "remainderxf3"
13203 [(use (match_operand:XF 0 "register_operand" ""))
13204 (use (match_operand:XF 1 "general_operand" ""))
13205 (use (match_operand:XF 2 "general_operand" ""))]
13206 "TARGET_USE_FANCY_MATH_387"
13208 rtx label = gen_label_rtx ();
13210 rtx op1 = gen_reg_rtx (XFmode);
13211 rtx op2 = gen_reg_rtx (XFmode);
13213 emit_move_insn (op2, operands[2]);
13214 emit_move_insn (op1, operands[1]);
13216 emit_label (label);
13217 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13218 ix86_emit_fp_unordered_jump (label);
13219 LABEL_NUSES (label) = 1;
13221 emit_move_insn (operands[0], op1);
13225 (define_expand "remainder<mode>3"
13226 [(use (match_operand:MODEF 0 "register_operand" ""))
13227 (use (match_operand:MODEF 1 "general_operand" ""))
13228 (use (match_operand:MODEF 2 "general_operand" ""))]
13229 "TARGET_USE_FANCY_MATH_387"
13231 rtx (*gen_truncxf) (rtx, rtx);
13233 rtx label = gen_label_rtx ();
13235 rtx op1 = gen_reg_rtx (XFmode);
13236 rtx op2 = gen_reg_rtx (XFmode);
13238 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13239 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13241 emit_label (label);
13243 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13244 ix86_emit_fp_unordered_jump (label);
13245 LABEL_NUSES (label) = 1;
13247 /* Truncate the result properly for strict SSE math. */
13248 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13249 && !TARGET_MIX_SSE_I387)
13250 gen_truncxf = gen_truncxf<mode>2;
13252 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13254 emit_insn (gen_truncxf (operands[0], op1));
13258 (define_insn "*sinxf2_i387"
13259 [(set (match_operand:XF 0 "register_operand" "=f")
13260 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13261 "TARGET_USE_FANCY_MATH_387
13262 && flag_unsafe_math_optimizations"
13264 [(set_attr "type" "fpspc")
13265 (set_attr "mode" "XF")])
13267 (define_insn "*sin_extend<mode>xf2_i387"
13268 [(set (match_operand:XF 0 "register_operand" "=f")
13269 (unspec:XF [(float_extend:XF
13270 (match_operand:MODEF 1 "register_operand" "0"))]
13272 "TARGET_USE_FANCY_MATH_387
13273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13274 || TARGET_MIX_SSE_I387)
13275 && flag_unsafe_math_optimizations"
13277 [(set_attr "type" "fpspc")
13278 (set_attr "mode" "XF")])
13280 (define_insn "*cosxf2_i387"
13281 [(set (match_operand:XF 0 "register_operand" "=f")
13282 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13283 "TARGET_USE_FANCY_MATH_387
13284 && flag_unsafe_math_optimizations"
13286 [(set_attr "type" "fpspc")
13287 (set_attr "mode" "XF")])
13289 (define_insn "*cos_extend<mode>xf2_i387"
13290 [(set (match_operand:XF 0 "register_operand" "=f")
13291 (unspec:XF [(float_extend:XF
13292 (match_operand:MODEF 1 "register_operand" "0"))]
13294 "TARGET_USE_FANCY_MATH_387
13295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13296 || TARGET_MIX_SSE_I387)
13297 && flag_unsafe_math_optimizations"
13299 [(set_attr "type" "fpspc")
13300 (set_attr "mode" "XF")])
13302 ;; When sincos pattern is defined, sin and cos builtin functions will be
13303 ;; expanded to sincos pattern with one of its outputs left unused.
13304 ;; CSE pass will figure out if two sincos patterns can be combined,
13305 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13306 ;; depending on the unused output.
13308 (define_insn "sincosxf3"
13309 [(set (match_operand:XF 0 "register_operand" "=f")
13310 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13311 UNSPEC_SINCOS_COS))
13312 (set (match_operand:XF 1 "register_operand" "=u")
13313 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13314 "TARGET_USE_FANCY_MATH_387
13315 && flag_unsafe_math_optimizations"
13317 [(set_attr "type" "fpspc")
13318 (set_attr "mode" "XF")])
13321 [(set (match_operand:XF 0 "register_operand" "")
13322 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13323 UNSPEC_SINCOS_COS))
13324 (set (match_operand:XF 1 "register_operand" "")
13325 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13326 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13327 && can_create_pseudo_p ()"
13328 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13331 [(set (match_operand:XF 0 "register_operand" "")
13332 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13333 UNSPEC_SINCOS_COS))
13334 (set (match_operand:XF 1 "register_operand" "")
13335 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13336 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13337 && can_create_pseudo_p ()"
13338 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13340 (define_insn "sincos_extend<mode>xf3_i387"
13341 [(set (match_operand:XF 0 "register_operand" "=f")
13342 (unspec:XF [(float_extend:XF
13343 (match_operand:MODEF 2 "register_operand" "0"))]
13344 UNSPEC_SINCOS_COS))
13345 (set (match_operand:XF 1 "register_operand" "=u")
13346 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13347 "TARGET_USE_FANCY_MATH_387
13348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13349 || TARGET_MIX_SSE_I387)
13350 && flag_unsafe_math_optimizations"
13352 [(set_attr "type" "fpspc")
13353 (set_attr "mode" "XF")])
13356 [(set (match_operand:XF 0 "register_operand" "")
13357 (unspec:XF [(float_extend:XF
13358 (match_operand:MODEF 2 "register_operand" ""))]
13359 UNSPEC_SINCOS_COS))
13360 (set (match_operand:XF 1 "register_operand" "")
13361 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13362 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13363 && can_create_pseudo_p ()"
13364 [(set (match_dup 1)
13365 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13368 [(set (match_operand:XF 0 "register_operand" "")
13369 (unspec:XF [(float_extend:XF
13370 (match_operand:MODEF 2 "register_operand" ""))]
13371 UNSPEC_SINCOS_COS))
13372 (set (match_operand:XF 1 "register_operand" "")
13373 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13374 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13375 && can_create_pseudo_p ()"
13376 [(set (match_dup 0)
13377 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13379 (define_expand "sincos<mode>3"
13380 [(use (match_operand:MODEF 0 "register_operand" ""))
13381 (use (match_operand:MODEF 1 "register_operand" ""))
13382 (use (match_operand:MODEF 2 "register_operand" ""))]
13383 "TARGET_USE_FANCY_MATH_387
13384 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13385 || TARGET_MIX_SSE_I387)
13386 && flag_unsafe_math_optimizations"
13388 rtx op0 = gen_reg_rtx (XFmode);
13389 rtx op1 = gen_reg_rtx (XFmode);
13391 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13392 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13393 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13397 (define_insn "fptanxf4_i387"
13398 [(set (match_operand:XF 0 "register_operand" "=f")
13399 (match_operand:XF 3 "const_double_operand" "F"))
13400 (set (match_operand:XF 1 "register_operand" "=u")
13401 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13403 "TARGET_USE_FANCY_MATH_387
13404 && flag_unsafe_math_optimizations
13405 && standard_80387_constant_p (operands[3]) == 2"
13407 [(set_attr "type" "fpspc")
13408 (set_attr "mode" "XF")])
13410 (define_insn "fptan_extend<mode>xf4_i387"
13411 [(set (match_operand:MODEF 0 "register_operand" "=f")
13412 (match_operand:MODEF 3 "const_double_operand" "F"))
13413 (set (match_operand:XF 1 "register_operand" "=u")
13414 (unspec:XF [(float_extend:XF
13415 (match_operand:MODEF 2 "register_operand" "0"))]
13417 "TARGET_USE_FANCY_MATH_387
13418 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13419 || TARGET_MIX_SSE_I387)
13420 && flag_unsafe_math_optimizations
13421 && standard_80387_constant_p (operands[3]) == 2"
13423 [(set_attr "type" "fpspc")
13424 (set_attr "mode" "XF")])
13426 (define_expand "tanxf2"
13427 [(use (match_operand:XF 0 "register_operand" ""))
13428 (use (match_operand:XF 1 "register_operand" ""))]
13429 "TARGET_USE_FANCY_MATH_387
13430 && flag_unsafe_math_optimizations"
13432 rtx one = gen_reg_rtx (XFmode);
13433 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13435 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13439 (define_expand "tan<mode>2"
13440 [(use (match_operand:MODEF 0 "register_operand" ""))
13441 (use (match_operand:MODEF 1 "register_operand" ""))]
13442 "TARGET_USE_FANCY_MATH_387
13443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13444 || TARGET_MIX_SSE_I387)
13445 && flag_unsafe_math_optimizations"
13447 rtx op0 = gen_reg_rtx (XFmode);
13449 rtx one = gen_reg_rtx (<MODE>mode);
13450 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13452 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13453 operands[1], op2));
13454 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13458 (define_insn "*fpatanxf3_i387"
13459 [(set (match_operand:XF 0 "register_operand" "=f")
13460 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13461 (match_operand:XF 2 "register_operand" "u")]
13463 (clobber (match_scratch:XF 3 "=2"))]
13464 "TARGET_USE_FANCY_MATH_387
13465 && flag_unsafe_math_optimizations"
13467 [(set_attr "type" "fpspc")
13468 (set_attr "mode" "XF")])
13470 (define_insn "fpatan_extend<mode>xf3_i387"
13471 [(set (match_operand:XF 0 "register_operand" "=f")
13472 (unspec:XF [(float_extend:XF
13473 (match_operand:MODEF 1 "register_operand" "0"))
13475 (match_operand:MODEF 2 "register_operand" "u"))]
13477 (clobber (match_scratch:XF 3 "=2"))]
13478 "TARGET_USE_FANCY_MATH_387
13479 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13480 || TARGET_MIX_SSE_I387)
13481 && flag_unsafe_math_optimizations"
13483 [(set_attr "type" "fpspc")
13484 (set_attr "mode" "XF")])
13486 (define_expand "atan2xf3"
13487 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13488 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13489 (match_operand:XF 1 "register_operand" "")]
13491 (clobber (match_scratch:XF 3 ""))])]
13492 "TARGET_USE_FANCY_MATH_387
13493 && flag_unsafe_math_optimizations")
13495 (define_expand "atan2<mode>3"
13496 [(use (match_operand:MODEF 0 "register_operand" ""))
13497 (use (match_operand:MODEF 1 "register_operand" ""))
13498 (use (match_operand:MODEF 2 "register_operand" ""))]
13499 "TARGET_USE_FANCY_MATH_387
13500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13501 || TARGET_MIX_SSE_I387)
13502 && flag_unsafe_math_optimizations"
13504 rtx op0 = gen_reg_rtx (XFmode);
13506 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13507 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13511 (define_expand "atanxf2"
13512 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13513 (unspec:XF [(match_dup 2)
13514 (match_operand:XF 1 "register_operand" "")]
13516 (clobber (match_scratch:XF 3 ""))])]
13517 "TARGET_USE_FANCY_MATH_387
13518 && flag_unsafe_math_optimizations"
13520 operands[2] = gen_reg_rtx (XFmode);
13521 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13524 (define_expand "atan<mode>2"
13525 [(use (match_operand:MODEF 0 "register_operand" ""))
13526 (use (match_operand:MODEF 1 "register_operand" ""))]
13527 "TARGET_USE_FANCY_MATH_387
13528 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13529 || TARGET_MIX_SSE_I387)
13530 && flag_unsafe_math_optimizations"
13532 rtx op0 = gen_reg_rtx (XFmode);
13534 rtx op2 = gen_reg_rtx (<MODE>mode);
13535 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13537 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13538 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13542 (define_expand "asinxf2"
13543 [(set (match_dup 2)
13544 (mult:XF (match_operand:XF 1 "register_operand" "")
13546 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13547 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13548 (parallel [(set (match_operand:XF 0 "register_operand" "")
13549 (unspec:XF [(match_dup 5) (match_dup 1)]
13551 (clobber (match_scratch:XF 6 ""))])]
13552 "TARGET_USE_FANCY_MATH_387
13553 && flag_unsafe_math_optimizations"
13557 if (optimize_insn_for_size_p ())
13560 for (i = 2; i < 6; i++)
13561 operands[i] = gen_reg_rtx (XFmode);
13563 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13566 (define_expand "asin<mode>2"
13567 [(use (match_operand:MODEF 0 "register_operand" ""))
13568 (use (match_operand:MODEF 1 "general_operand" ""))]
13569 "TARGET_USE_FANCY_MATH_387
13570 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13571 || TARGET_MIX_SSE_I387)
13572 && flag_unsafe_math_optimizations"
13574 rtx op0 = gen_reg_rtx (XFmode);
13575 rtx op1 = gen_reg_rtx (XFmode);
13577 if (optimize_insn_for_size_p ())
13580 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13581 emit_insn (gen_asinxf2 (op0, op1));
13582 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13586 (define_expand "acosxf2"
13587 [(set (match_dup 2)
13588 (mult:XF (match_operand:XF 1 "register_operand" "")
13590 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13591 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13592 (parallel [(set (match_operand:XF 0 "register_operand" "")
13593 (unspec:XF [(match_dup 1) (match_dup 5)]
13595 (clobber (match_scratch:XF 6 ""))])]
13596 "TARGET_USE_FANCY_MATH_387
13597 && flag_unsafe_math_optimizations"
13601 if (optimize_insn_for_size_p ())
13604 for (i = 2; i < 6; i++)
13605 operands[i] = gen_reg_rtx (XFmode);
13607 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13610 (define_expand "acos<mode>2"
13611 [(use (match_operand:MODEF 0 "register_operand" ""))
13612 (use (match_operand:MODEF 1 "general_operand" ""))]
13613 "TARGET_USE_FANCY_MATH_387
13614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13615 || TARGET_MIX_SSE_I387)
13616 && flag_unsafe_math_optimizations"
13618 rtx op0 = gen_reg_rtx (XFmode);
13619 rtx op1 = gen_reg_rtx (XFmode);
13621 if (optimize_insn_for_size_p ())
13624 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13625 emit_insn (gen_acosxf2 (op0, op1));
13626 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13630 (define_insn "fyl2xxf3_i387"
13631 [(set (match_operand:XF 0 "register_operand" "=f")
13632 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13633 (match_operand:XF 2 "register_operand" "u")]
13635 (clobber (match_scratch:XF 3 "=2"))]
13636 "TARGET_USE_FANCY_MATH_387
13637 && flag_unsafe_math_optimizations"
13639 [(set_attr "type" "fpspc")
13640 (set_attr "mode" "XF")])
13642 (define_insn "fyl2x_extend<mode>xf3_i387"
13643 [(set (match_operand:XF 0 "register_operand" "=f")
13644 (unspec:XF [(float_extend:XF
13645 (match_operand:MODEF 1 "register_operand" "0"))
13646 (match_operand:XF 2 "register_operand" "u")]
13648 (clobber (match_scratch:XF 3 "=2"))]
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 [(set_attr "type" "fpspc")
13655 (set_attr "mode" "XF")])
13657 (define_expand "logxf2"
13658 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13659 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13660 (match_dup 2)] UNSPEC_FYL2X))
13661 (clobber (match_scratch:XF 3 ""))])]
13662 "TARGET_USE_FANCY_MATH_387
13663 && flag_unsafe_math_optimizations"
13665 operands[2] = gen_reg_rtx (XFmode);
13666 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13669 (define_expand "log<mode>2"
13670 [(use (match_operand:MODEF 0 "register_operand" ""))
13671 (use (match_operand:MODEF 1 "register_operand" ""))]
13672 "TARGET_USE_FANCY_MATH_387
13673 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13674 || TARGET_MIX_SSE_I387)
13675 && flag_unsafe_math_optimizations"
13677 rtx op0 = gen_reg_rtx (XFmode);
13679 rtx op2 = gen_reg_rtx (XFmode);
13680 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13682 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13683 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13687 (define_expand "log10xf2"
13688 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13689 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13690 (match_dup 2)] UNSPEC_FYL2X))
13691 (clobber (match_scratch:XF 3 ""))])]
13692 "TARGET_USE_FANCY_MATH_387
13693 && flag_unsafe_math_optimizations"
13695 operands[2] = gen_reg_rtx (XFmode);
13696 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13699 (define_expand "log10<mode>2"
13700 [(use (match_operand:MODEF 0 "register_operand" ""))
13701 (use (match_operand:MODEF 1 "register_operand" ""))]
13702 "TARGET_USE_FANCY_MATH_387
13703 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13704 || TARGET_MIX_SSE_I387)
13705 && flag_unsafe_math_optimizations"
13707 rtx op0 = gen_reg_rtx (XFmode);
13709 rtx op2 = gen_reg_rtx (XFmode);
13710 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13712 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13713 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13717 (define_expand "log2xf2"
13718 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13719 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13720 (match_dup 2)] UNSPEC_FYL2X))
13721 (clobber (match_scratch:XF 3 ""))])]
13722 "TARGET_USE_FANCY_MATH_387
13723 && flag_unsafe_math_optimizations"
13725 operands[2] = gen_reg_rtx (XFmode);
13726 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13729 (define_expand "log2<mode>2"
13730 [(use (match_operand:MODEF 0 "register_operand" ""))
13731 (use (match_operand:MODEF 1 "register_operand" ""))]
13732 "TARGET_USE_FANCY_MATH_387
13733 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13734 || TARGET_MIX_SSE_I387)
13735 && flag_unsafe_math_optimizations"
13737 rtx op0 = gen_reg_rtx (XFmode);
13739 rtx op2 = gen_reg_rtx (XFmode);
13740 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13742 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13747 (define_insn "fyl2xp1xf3_i387"
13748 [(set (match_operand:XF 0 "register_operand" "=f")
13749 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13750 (match_operand:XF 2 "register_operand" "u")]
13752 (clobber (match_scratch:XF 3 "=2"))]
13753 "TARGET_USE_FANCY_MATH_387
13754 && flag_unsafe_math_optimizations"
13756 [(set_attr "type" "fpspc")
13757 (set_attr "mode" "XF")])
13759 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13760 [(set (match_operand:XF 0 "register_operand" "=f")
13761 (unspec:XF [(float_extend:XF
13762 (match_operand:MODEF 1 "register_operand" "0"))
13763 (match_operand:XF 2 "register_operand" "u")]
13765 (clobber (match_scratch:XF 3 "=2"))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13768 || TARGET_MIX_SSE_I387)
13769 && flag_unsafe_math_optimizations"
13771 [(set_attr "type" "fpspc")
13772 (set_attr "mode" "XF")])
13774 (define_expand "log1pxf2"
13775 [(use (match_operand:XF 0 "register_operand" ""))
13776 (use (match_operand:XF 1 "register_operand" ""))]
13777 "TARGET_USE_FANCY_MATH_387
13778 && flag_unsafe_math_optimizations"
13780 if (optimize_insn_for_size_p ())
13783 ix86_emit_i387_log1p (operands[0], operands[1]);
13787 (define_expand "log1p<mode>2"
13788 [(use (match_operand:MODEF 0 "register_operand" ""))
13789 (use (match_operand:MODEF 1 "register_operand" ""))]
13790 "TARGET_USE_FANCY_MATH_387
13791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13792 || TARGET_MIX_SSE_I387)
13793 && flag_unsafe_math_optimizations"
13797 if (optimize_insn_for_size_p ())
13800 op0 = gen_reg_rtx (XFmode);
13802 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13804 ix86_emit_i387_log1p (op0, operands[1]);
13805 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13809 (define_insn "fxtractxf3_i387"
13810 [(set (match_operand:XF 0 "register_operand" "=f")
13811 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13812 UNSPEC_XTRACT_FRACT))
13813 (set (match_operand:XF 1 "register_operand" "=u")
13814 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13815 "TARGET_USE_FANCY_MATH_387
13816 && flag_unsafe_math_optimizations"
13818 [(set_attr "type" "fpspc")
13819 (set_attr "mode" "XF")])
13821 (define_insn "fxtract_extend<mode>xf3_i387"
13822 [(set (match_operand:XF 0 "register_operand" "=f")
13823 (unspec:XF [(float_extend:XF
13824 (match_operand:MODEF 2 "register_operand" "0"))]
13825 UNSPEC_XTRACT_FRACT))
13826 (set (match_operand:XF 1 "register_operand" "=u")
13827 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13828 "TARGET_USE_FANCY_MATH_387
13829 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13830 || TARGET_MIX_SSE_I387)
13831 && flag_unsafe_math_optimizations"
13833 [(set_attr "type" "fpspc")
13834 (set_attr "mode" "XF")])
13836 (define_expand "logbxf2"
13837 [(parallel [(set (match_dup 2)
13838 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13839 UNSPEC_XTRACT_FRACT))
13840 (set (match_operand:XF 0 "register_operand" "")
13841 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13842 "TARGET_USE_FANCY_MATH_387
13843 && flag_unsafe_math_optimizations"
13844 "operands[2] = gen_reg_rtx (XFmode);")
13846 (define_expand "logb<mode>2"
13847 [(use (match_operand:MODEF 0 "register_operand" ""))
13848 (use (match_operand:MODEF 1 "register_operand" ""))]
13849 "TARGET_USE_FANCY_MATH_387
13850 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13851 || TARGET_MIX_SSE_I387)
13852 && flag_unsafe_math_optimizations"
13854 rtx op0 = gen_reg_rtx (XFmode);
13855 rtx op1 = gen_reg_rtx (XFmode);
13857 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13858 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13862 (define_expand "ilogbxf2"
13863 [(use (match_operand:SI 0 "register_operand" ""))
13864 (use (match_operand:XF 1 "register_operand" ""))]
13865 "TARGET_USE_FANCY_MATH_387
13866 && flag_unsafe_math_optimizations"
13870 if (optimize_insn_for_size_p ())
13873 op0 = gen_reg_rtx (XFmode);
13874 op1 = gen_reg_rtx (XFmode);
13876 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13877 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13881 (define_expand "ilogb<mode>2"
13882 [(use (match_operand:SI 0 "register_operand" ""))
13883 (use (match_operand:MODEF 1 "register_operand" ""))]
13884 "TARGET_USE_FANCY_MATH_387
13885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13886 || TARGET_MIX_SSE_I387)
13887 && flag_unsafe_math_optimizations"
13891 if (optimize_insn_for_size_p ())
13894 op0 = gen_reg_rtx (XFmode);
13895 op1 = gen_reg_rtx (XFmode);
13897 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13898 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13902 (define_insn "*f2xm1xf2_i387"
13903 [(set (match_operand:XF 0 "register_operand" "=f")
13904 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13906 "TARGET_USE_FANCY_MATH_387
13907 && flag_unsafe_math_optimizations"
13909 [(set_attr "type" "fpspc")
13910 (set_attr "mode" "XF")])
13912 (define_insn "*fscalexf4_i387"
13913 [(set (match_operand:XF 0 "register_operand" "=f")
13914 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13915 (match_operand:XF 3 "register_operand" "1")]
13916 UNSPEC_FSCALE_FRACT))
13917 (set (match_operand:XF 1 "register_operand" "=u")
13918 (unspec:XF [(match_dup 2) (match_dup 3)]
13919 UNSPEC_FSCALE_EXP))]
13920 "TARGET_USE_FANCY_MATH_387
13921 && flag_unsafe_math_optimizations"
13923 [(set_attr "type" "fpspc")
13924 (set_attr "mode" "XF")])
13926 (define_expand "expNcorexf3"
13927 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13928 (match_operand:XF 2 "register_operand" "")))
13929 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13930 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13931 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13932 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13933 (parallel [(set (match_operand:XF 0 "register_operand" "")
13934 (unspec:XF [(match_dup 8) (match_dup 4)]
13935 UNSPEC_FSCALE_FRACT))
13937 (unspec:XF [(match_dup 8) (match_dup 4)]
13938 UNSPEC_FSCALE_EXP))])]
13939 "TARGET_USE_FANCY_MATH_387
13940 && flag_unsafe_math_optimizations"
13944 if (optimize_insn_for_size_p ())
13947 for (i = 3; i < 10; i++)
13948 operands[i] = gen_reg_rtx (XFmode);
13950 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13953 (define_expand "expxf2"
13954 [(use (match_operand:XF 0 "register_operand" ""))
13955 (use (match_operand:XF 1 "register_operand" ""))]
13956 "TARGET_USE_FANCY_MATH_387
13957 && flag_unsafe_math_optimizations"
13961 if (optimize_insn_for_size_p ())
13964 op2 = gen_reg_rtx (XFmode);
13965 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13967 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13971 (define_expand "exp<mode>2"
13972 [(use (match_operand:MODEF 0 "register_operand" ""))
13973 (use (match_operand:MODEF 1 "general_operand" ""))]
13974 "TARGET_USE_FANCY_MATH_387
13975 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13976 || TARGET_MIX_SSE_I387)
13977 && flag_unsafe_math_optimizations"
13981 if (optimize_insn_for_size_p ())
13984 op0 = gen_reg_rtx (XFmode);
13985 op1 = gen_reg_rtx (XFmode);
13987 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13988 emit_insn (gen_expxf2 (op0, op1));
13989 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13993 (define_expand "exp10xf2"
13994 [(use (match_operand:XF 0 "register_operand" ""))
13995 (use (match_operand:XF 1 "register_operand" ""))]
13996 "TARGET_USE_FANCY_MATH_387
13997 && flag_unsafe_math_optimizations"
14001 if (optimize_insn_for_size_p ())
14004 op2 = gen_reg_rtx (XFmode);
14005 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14007 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14011 (define_expand "exp10<mode>2"
14012 [(use (match_operand:MODEF 0 "register_operand" ""))
14013 (use (match_operand:MODEF 1 "general_operand" ""))]
14014 "TARGET_USE_FANCY_MATH_387
14015 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14016 || TARGET_MIX_SSE_I387)
14017 && flag_unsafe_math_optimizations"
14021 if (optimize_insn_for_size_p ())
14024 op0 = gen_reg_rtx (XFmode);
14025 op1 = gen_reg_rtx (XFmode);
14027 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14028 emit_insn (gen_exp10xf2 (op0, op1));
14029 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14033 (define_expand "exp2xf2"
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, CONST1_RTX (XFmode)); /* fld1 */
14047 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14051 (define_expand "exp2<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_exp2xf2 (op0, op1));
14069 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14073 (define_expand "expm1xf2"
14074 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14076 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14077 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14078 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14079 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14080 (parallel [(set (match_dup 7)
14081 (unspec:XF [(match_dup 6) (match_dup 4)]
14082 UNSPEC_FSCALE_FRACT))
14084 (unspec:XF [(match_dup 6) (match_dup 4)]
14085 UNSPEC_FSCALE_EXP))])
14086 (parallel [(set (match_dup 10)
14087 (unspec:XF [(match_dup 9) (match_dup 8)]
14088 UNSPEC_FSCALE_FRACT))
14089 (set (match_dup 11)
14090 (unspec:XF [(match_dup 9) (match_dup 8)]
14091 UNSPEC_FSCALE_EXP))])
14092 (set (match_dup 12) (minus:XF (match_dup 10)
14093 (float_extend:XF (match_dup 13))))
14094 (set (match_operand:XF 0 "register_operand" "")
14095 (plus:XF (match_dup 12) (match_dup 7)))]
14096 "TARGET_USE_FANCY_MATH_387
14097 && flag_unsafe_math_optimizations"
14101 if (optimize_insn_for_size_p ())
14104 for (i = 2; i < 13; i++)
14105 operands[i] = gen_reg_rtx (XFmode);
14108 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14110 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14113 (define_expand "expm1<mode>2"
14114 [(use (match_operand:MODEF 0 "register_operand" ""))
14115 (use (match_operand:MODEF 1 "general_operand" ""))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118 || TARGET_MIX_SSE_I387)
14119 && flag_unsafe_math_optimizations"
14123 if (optimize_insn_for_size_p ())
14126 op0 = gen_reg_rtx (XFmode);
14127 op1 = gen_reg_rtx (XFmode);
14129 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14130 emit_insn (gen_expm1xf2 (op0, op1));
14131 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14135 (define_expand "ldexpxf3"
14136 [(set (match_dup 3)
14137 (float:XF (match_operand:SI 2 "register_operand" "")))
14138 (parallel [(set (match_operand:XF 0 " register_operand" "")
14139 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14141 UNSPEC_FSCALE_FRACT))
14143 (unspec:XF [(match_dup 1) (match_dup 3)]
14144 UNSPEC_FSCALE_EXP))])]
14145 "TARGET_USE_FANCY_MATH_387
14146 && flag_unsafe_math_optimizations"
14148 if (optimize_insn_for_size_p ())
14151 operands[3] = gen_reg_rtx (XFmode);
14152 operands[4] = gen_reg_rtx (XFmode);
14155 (define_expand "ldexp<mode>3"
14156 [(use (match_operand:MODEF 0 "register_operand" ""))
14157 (use (match_operand:MODEF 1 "general_operand" ""))
14158 (use (match_operand:SI 2 "register_operand" ""))]
14159 "TARGET_USE_FANCY_MATH_387
14160 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14161 || TARGET_MIX_SSE_I387)
14162 && flag_unsafe_math_optimizations"
14166 if (optimize_insn_for_size_p ())
14169 op0 = gen_reg_rtx (XFmode);
14170 op1 = gen_reg_rtx (XFmode);
14172 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14173 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14174 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14178 (define_expand "scalbxf3"
14179 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14180 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14181 (match_operand:XF 2 "register_operand" "")]
14182 UNSPEC_FSCALE_FRACT))
14184 (unspec:XF [(match_dup 1) (match_dup 2)]
14185 UNSPEC_FSCALE_EXP))])]
14186 "TARGET_USE_FANCY_MATH_387
14187 && flag_unsafe_math_optimizations"
14189 if (optimize_insn_for_size_p ())
14192 operands[3] = gen_reg_rtx (XFmode);
14195 (define_expand "scalb<mode>3"
14196 [(use (match_operand:MODEF 0 "register_operand" ""))
14197 (use (match_operand:MODEF 1 "general_operand" ""))
14198 (use (match_operand:MODEF 2 "general_operand" ""))]
14199 "TARGET_USE_FANCY_MATH_387
14200 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14201 || TARGET_MIX_SSE_I387)
14202 && flag_unsafe_math_optimizations"
14206 if (optimize_insn_for_size_p ())
14209 op0 = gen_reg_rtx (XFmode);
14210 op1 = gen_reg_rtx (XFmode);
14211 op2 = gen_reg_rtx (XFmode);
14213 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14214 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14215 emit_insn (gen_scalbxf3 (op0, op1, op2));
14216 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14220 (define_expand "significandxf2"
14221 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14222 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14223 UNSPEC_XTRACT_FRACT))
14225 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14226 "TARGET_USE_FANCY_MATH_387
14227 && flag_unsafe_math_optimizations"
14228 "operands[2] = gen_reg_rtx (XFmode);")
14230 (define_expand "significand<mode>2"
14231 [(use (match_operand:MODEF 0 "register_operand" ""))
14232 (use (match_operand:MODEF 1 "register_operand" ""))]
14233 "TARGET_USE_FANCY_MATH_387
14234 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14235 || TARGET_MIX_SSE_I387)
14236 && flag_unsafe_math_optimizations"
14238 rtx op0 = gen_reg_rtx (XFmode);
14239 rtx op1 = gen_reg_rtx (XFmode);
14241 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14242 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14247 (define_insn "sse4_1_round<mode>2"
14248 [(set (match_operand:MODEF 0 "register_operand" "=x")
14249 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14250 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14253 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14254 [(set_attr "type" "ssecvt")
14255 (set_attr "prefix_extra" "1")
14256 (set_attr "prefix" "maybe_vex")
14257 (set_attr "mode" "<MODE>")])
14259 (define_insn "rintxf2"
14260 [(set (match_operand:XF 0 "register_operand" "=f")
14261 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14263 "TARGET_USE_FANCY_MATH_387
14264 && flag_unsafe_math_optimizations"
14266 [(set_attr "type" "fpspc")
14267 (set_attr "mode" "XF")])
14269 (define_expand "rint<mode>2"
14270 [(use (match_operand:MODEF 0 "register_operand" ""))
14271 (use (match_operand:MODEF 1 "register_operand" ""))]
14272 "(TARGET_USE_FANCY_MATH_387
14273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14274 || TARGET_MIX_SSE_I387)
14275 && flag_unsafe_math_optimizations)
14276 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14277 && !flag_trapping_math)"
14279 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14280 && !flag_trapping_math)
14282 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14285 emit_insn (gen_sse4_1_round<mode>2
14286 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14288 ix86_expand_rint (operand0, operand1);
14292 rtx op0 = gen_reg_rtx (XFmode);
14293 rtx op1 = gen_reg_rtx (XFmode);
14295 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14296 emit_insn (gen_rintxf2 (op0, op1));
14298 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14303 (define_expand "round<mode>2"
14304 [(match_operand:MODEF 0 "register_operand" "")
14305 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14306 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14307 && !flag_trapping_math && !flag_rounding_math"
14309 if (optimize_insn_for_size_p ())
14311 if (TARGET_64BIT || (<MODE>mode != DFmode))
14312 ix86_expand_round (operand0, operand1);
14314 ix86_expand_rounddf_32 (operand0, operand1);
14318 (define_insn_and_split "*fistdi2_1"
14319 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14320 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14322 "TARGET_USE_FANCY_MATH_387
14323 && can_create_pseudo_p ()"
14328 if (memory_operand (operands[0], VOIDmode))
14329 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14332 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14333 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14338 [(set_attr "type" "fpspc")
14339 (set_attr "mode" "DI")])
14341 (define_insn "fistdi2"
14342 [(set (match_operand:DI 0 "memory_operand" "=m")
14343 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14345 (clobber (match_scratch:XF 2 "=&1f"))]
14346 "TARGET_USE_FANCY_MATH_387"
14347 "* return output_fix_trunc (insn, operands, false);"
14348 [(set_attr "type" "fpspc")
14349 (set_attr "mode" "DI")])
14351 (define_insn "fistdi2_with_temp"
14352 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14353 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14355 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14356 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14357 "TARGET_USE_FANCY_MATH_387"
14359 [(set_attr "type" "fpspc")
14360 (set_attr "mode" "DI")])
14363 [(set (match_operand:DI 0 "register_operand" "")
14364 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14366 (clobber (match_operand:DI 2 "memory_operand" ""))
14367 (clobber (match_scratch 3 ""))]
14369 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14370 (clobber (match_dup 3))])
14371 (set (match_dup 0) (match_dup 2))])
14374 [(set (match_operand:DI 0 "memory_operand" "")
14375 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14377 (clobber (match_operand:DI 2 "memory_operand" ""))
14378 (clobber (match_scratch 3 ""))]
14380 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14381 (clobber (match_dup 3))])])
14383 (define_insn_and_split "*fist<mode>2_1"
14384 [(set (match_operand:SWI24 0 "register_operand" "")
14385 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14387 "TARGET_USE_FANCY_MATH_387
14388 && can_create_pseudo_p ()"
14393 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14394 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14398 [(set_attr "type" "fpspc")
14399 (set_attr "mode" "<MODE>")])
14401 (define_insn "fist<mode>2"
14402 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14403 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14405 "TARGET_USE_FANCY_MATH_387"
14406 "* return output_fix_trunc (insn, operands, false);"
14407 [(set_attr "type" "fpspc")
14408 (set_attr "mode" "<MODE>")])
14410 (define_insn "fist<mode>2_with_temp"
14411 [(set (match_operand:SWI24 0 "register_operand" "=r")
14412 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14414 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14415 "TARGET_USE_FANCY_MATH_387"
14417 [(set_attr "type" "fpspc")
14418 (set_attr "mode" "<MODE>")])
14421 [(set (match_operand:SWI24 0 "register_operand" "")
14422 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14424 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14426 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14427 (set (match_dup 0) (match_dup 2))])
14430 [(set (match_operand:SWI24 0 "memory_operand" "")
14431 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14433 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14435 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14437 (define_expand "lrintxf<mode>2"
14438 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14439 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14441 "TARGET_USE_FANCY_MATH_387")
14443 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14444 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14445 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14446 UNSPEC_FIX_NOTRUNC))]
14447 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14448 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14450 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14451 [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14452 (match_operand:MODEF 1 "register_operand" "")]
14453 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14454 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14455 && !flag_trapping_math && !flag_rounding_math"
14457 if (optimize_insn_for_size_p ())
14459 ix86_expand_lround (operand0, operand1);
14463 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14464 (define_insn_and_split "frndintxf2_floor"
14465 [(set (match_operand:XF 0 "register_operand" "")
14466 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14467 UNSPEC_FRNDINT_FLOOR))
14468 (clobber (reg:CC FLAGS_REG))]
14469 "TARGET_USE_FANCY_MATH_387
14470 && flag_unsafe_math_optimizations
14471 && can_create_pseudo_p ()"
14476 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14478 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14479 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14481 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14482 operands[2], operands[3]));
14485 [(set_attr "type" "frndint")
14486 (set_attr "i387_cw" "floor")
14487 (set_attr "mode" "XF")])
14489 (define_insn "frndintxf2_floor_i387"
14490 [(set (match_operand:XF 0 "register_operand" "=f")
14491 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14492 UNSPEC_FRNDINT_FLOOR))
14493 (use (match_operand:HI 2 "memory_operand" "m"))
14494 (use (match_operand:HI 3 "memory_operand" "m"))]
14495 "TARGET_USE_FANCY_MATH_387
14496 && flag_unsafe_math_optimizations"
14497 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14498 [(set_attr "type" "frndint")
14499 (set_attr "i387_cw" "floor")
14500 (set_attr "mode" "XF")])
14502 (define_expand "floorxf2"
14503 [(use (match_operand:XF 0 "register_operand" ""))
14504 (use (match_operand:XF 1 "register_operand" ""))]
14505 "TARGET_USE_FANCY_MATH_387
14506 && flag_unsafe_math_optimizations"
14508 if (optimize_insn_for_size_p ())
14510 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14514 (define_expand "floor<mode>2"
14515 [(use (match_operand:MODEF 0 "register_operand" ""))
14516 (use (match_operand:MODEF 1 "register_operand" ""))]
14517 "(TARGET_USE_FANCY_MATH_387
14518 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14519 || TARGET_MIX_SSE_I387)
14520 && flag_unsafe_math_optimizations)
14521 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14522 && !flag_trapping_math)"
14524 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14525 && !flag_trapping_math
14526 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14528 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14531 emit_insn (gen_sse4_1_round<mode>2
14532 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14533 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14534 ix86_expand_floorceil (operand0, operand1, true);
14536 ix86_expand_floorceildf_32 (operand0, operand1, true);
14542 if (optimize_insn_for_size_p ())
14545 op0 = gen_reg_rtx (XFmode);
14546 op1 = gen_reg_rtx (XFmode);
14547 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14548 emit_insn (gen_frndintxf2_floor (op0, op1));
14550 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14555 (define_insn_and_split "*fist<mode>2_floor_1"
14556 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14557 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14558 UNSPEC_FIST_FLOOR))
14559 (clobber (reg:CC FLAGS_REG))]
14560 "TARGET_USE_FANCY_MATH_387
14561 && flag_unsafe_math_optimizations
14562 && can_create_pseudo_p ()"
14567 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14569 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14570 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14571 if (memory_operand (operands[0], VOIDmode))
14572 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14573 operands[2], operands[3]));
14576 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14577 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14578 operands[2], operands[3],
14583 [(set_attr "type" "fistp")
14584 (set_attr "i387_cw" "floor")
14585 (set_attr "mode" "<MODE>")])
14587 (define_insn "fistdi2_floor"
14588 [(set (match_operand:DI 0 "memory_operand" "=m")
14589 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14590 UNSPEC_FIST_FLOOR))
14591 (use (match_operand:HI 2 "memory_operand" "m"))
14592 (use (match_operand:HI 3 "memory_operand" "m"))
14593 (clobber (match_scratch:XF 4 "=&1f"))]
14594 "TARGET_USE_FANCY_MATH_387
14595 && flag_unsafe_math_optimizations"
14596 "* return output_fix_trunc (insn, operands, false);"
14597 [(set_attr "type" "fistp")
14598 (set_attr "i387_cw" "floor")
14599 (set_attr "mode" "DI")])
14601 (define_insn "fistdi2_floor_with_temp"
14602 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14603 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14604 UNSPEC_FIST_FLOOR))
14605 (use (match_operand:HI 2 "memory_operand" "m,m"))
14606 (use (match_operand:HI 3 "memory_operand" "m,m"))
14607 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14608 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14609 "TARGET_USE_FANCY_MATH_387
14610 && flag_unsafe_math_optimizations"
14612 [(set_attr "type" "fistp")
14613 (set_attr "i387_cw" "floor")
14614 (set_attr "mode" "DI")])
14617 [(set (match_operand:DI 0 "register_operand" "")
14618 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14619 UNSPEC_FIST_FLOOR))
14620 (use (match_operand:HI 2 "memory_operand" ""))
14621 (use (match_operand:HI 3 "memory_operand" ""))
14622 (clobber (match_operand:DI 4 "memory_operand" ""))
14623 (clobber (match_scratch 5 ""))]
14625 [(parallel [(set (match_dup 4)
14626 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14627 (use (match_dup 2))
14628 (use (match_dup 3))
14629 (clobber (match_dup 5))])
14630 (set (match_dup 0) (match_dup 4))])
14633 [(set (match_operand:DI 0 "memory_operand" "")
14634 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14635 UNSPEC_FIST_FLOOR))
14636 (use (match_operand:HI 2 "memory_operand" ""))
14637 (use (match_operand:HI 3 "memory_operand" ""))
14638 (clobber (match_operand:DI 4 "memory_operand" ""))
14639 (clobber (match_scratch 5 ""))]
14641 [(parallel [(set (match_dup 0)
14642 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14643 (use (match_dup 2))
14644 (use (match_dup 3))
14645 (clobber (match_dup 5))])])
14647 (define_insn "fist<mode>2_floor"
14648 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14649 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14650 UNSPEC_FIST_FLOOR))
14651 (use (match_operand:HI 2 "memory_operand" "m"))
14652 (use (match_operand:HI 3 "memory_operand" "m"))]
14653 "TARGET_USE_FANCY_MATH_387
14654 && flag_unsafe_math_optimizations"
14655 "* return output_fix_trunc (insn, operands, false);"
14656 [(set_attr "type" "fistp")
14657 (set_attr "i387_cw" "floor")
14658 (set_attr "mode" "<MODE>")])
14660 (define_insn "fist<mode>2_floor_with_temp"
14661 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14662 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14663 UNSPEC_FIST_FLOOR))
14664 (use (match_operand:HI 2 "memory_operand" "m,m"))
14665 (use (match_operand:HI 3 "memory_operand" "m,m"))
14666 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14667 "TARGET_USE_FANCY_MATH_387
14668 && flag_unsafe_math_optimizations"
14670 [(set_attr "type" "fistp")
14671 (set_attr "i387_cw" "floor")
14672 (set_attr "mode" "<MODE>")])
14675 [(set (match_operand:SWI24 0 "register_operand" "")
14676 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14677 UNSPEC_FIST_FLOOR))
14678 (use (match_operand:HI 2 "memory_operand" ""))
14679 (use (match_operand:HI 3 "memory_operand" ""))
14680 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14682 [(parallel [(set (match_dup 4)
14683 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14684 (use (match_dup 2))
14685 (use (match_dup 3))])
14686 (set (match_dup 0) (match_dup 4))])
14689 [(set (match_operand:SWI24 0 "memory_operand" "")
14690 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14691 UNSPEC_FIST_FLOOR))
14692 (use (match_operand:HI 2 "memory_operand" ""))
14693 (use (match_operand:HI 3 "memory_operand" ""))
14694 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14696 [(parallel [(set (match_dup 0)
14697 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14698 (use (match_dup 2))
14699 (use (match_dup 3))])])
14701 (define_expand "lfloorxf<mode>2"
14702 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14703 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14704 UNSPEC_FIST_FLOOR))
14705 (clobber (reg:CC FLAGS_REG))])]
14706 "TARGET_USE_FANCY_MATH_387
14707 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14708 && flag_unsafe_math_optimizations")
14710 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14711 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14712 (match_operand:MODEF 1 "register_operand" "")]
14713 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14714 && !flag_trapping_math"
14716 if (TARGET_64BIT && optimize_insn_for_size_p ())
14718 ix86_expand_lfloorceil (operand0, operand1, true);
14722 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14723 (define_insn_and_split "frndintxf2_ceil"
14724 [(set (match_operand:XF 0 "register_operand" "")
14725 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14726 UNSPEC_FRNDINT_CEIL))
14727 (clobber (reg:CC FLAGS_REG))]
14728 "TARGET_USE_FANCY_MATH_387
14729 && flag_unsafe_math_optimizations
14730 && can_create_pseudo_p ()"
14735 ix86_optimize_mode_switching[I387_CEIL] = 1;
14737 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14738 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14740 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14741 operands[2], operands[3]));
14744 [(set_attr "type" "frndint")
14745 (set_attr "i387_cw" "ceil")
14746 (set_attr "mode" "XF")])
14748 (define_insn "frndintxf2_ceil_i387"
14749 [(set (match_operand:XF 0 "register_operand" "=f")
14750 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14751 UNSPEC_FRNDINT_CEIL))
14752 (use (match_operand:HI 2 "memory_operand" "m"))
14753 (use (match_operand:HI 3 "memory_operand" "m"))]
14754 "TARGET_USE_FANCY_MATH_387
14755 && flag_unsafe_math_optimizations"
14756 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14757 [(set_attr "type" "frndint")
14758 (set_attr "i387_cw" "ceil")
14759 (set_attr "mode" "XF")])
14761 (define_expand "ceilxf2"
14762 [(use (match_operand:XF 0 "register_operand" ""))
14763 (use (match_operand:XF 1 "register_operand" ""))]
14764 "TARGET_USE_FANCY_MATH_387
14765 && flag_unsafe_math_optimizations"
14767 if (optimize_insn_for_size_p ())
14769 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14773 (define_expand "ceil<mode>2"
14774 [(use (match_operand:MODEF 0 "register_operand" ""))
14775 (use (match_operand:MODEF 1 "register_operand" ""))]
14776 "(TARGET_USE_FANCY_MATH_387
14777 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14778 || TARGET_MIX_SSE_I387)
14779 && flag_unsafe_math_optimizations)
14780 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14781 && !flag_trapping_math)"
14783 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14784 && !flag_trapping_math
14785 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14788 emit_insn (gen_sse4_1_round<mode>2
14789 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14790 else if (optimize_insn_for_size_p ())
14792 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14793 ix86_expand_floorceil (operand0, operand1, false);
14795 ix86_expand_floorceildf_32 (operand0, operand1, false);
14801 if (optimize_insn_for_size_p ())
14804 op0 = gen_reg_rtx (XFmode);
14805 op1 = gen_reg_rtx (XFmode);
14806 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14807 emit_insn (gen_frndintxf2_ceil (op0, op1));
14809 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14814 (define_insn_and_split "*fist<mode>2_ceil_1"
14815 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14816 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14818 (clobber (reg:CC FLAGS_REG))]
14819 "TARGET_USE_FANCY_MATH_387
14820 && flag_unsafe_math_optimizations
14821 && can_create_pseudo_p ()"
14826 ix86_optimize_mode_switching[I387_CEIL] = 1;
14828 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14829 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14830 if (memory_operand (operands[0], VOIDmode))
14831 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14832 operands[2], operands[3]));
14835 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14836 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14837 operands[2], operands[3],
14842 [(set_attr "type" "fistp")
14843 (set_attr "i387_cw" "ceil")
14844 (set_attr "mode" "<MODE>")])
14846 (define_insn "fistdi2_ceil"
14847 [(set (match_operand:DI 0 "memory_operand" "=m")
14848 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14850 (use (match_operand:HI 2 "memory_operand" "m"))
14851 (use (match_operand:HI 3 "memory_operand" "m"))
14852 (clobber (match_scratch:XF 4 "=&1f"))]
14853 "TARGET_USE_FANCY_MATH_387
14854 && flag_unsafe_math_optimizations"
14855 "* return output_fix_trunc (insn, operands, false);"
14856 [(set_attr "type" "fistp")
14857 (set_attr "i387_cw" "ceil")
14858 (set_attr "mode" "DI")])
14860 (define_insn "fistdi2_ceil_with_temp"
14861 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14862 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14864 (use (match_operand:HI 2 "memory_operand" "m,m"))
14865 (use (match_operand:HI 3 "memory_operand" "m,m"))
14866 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14867 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14868 "TARGET_USE_FANCY_MATH_387
14869 && flag_unsafe_math_optimizations"
14871 [(set_attr "type" "fistp")
14872 (set_attr "i387_cw" "ceil")
14873 (set_attr "mode" "DI")])
14876 [(set (match_operand:DI 0 "register_operand" "")
14877 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14879 (use (match_operand:HI 2 "memory_operand" ""))
14880 (use (match_operand:HI 3 "memory_operand" ""))
14881 (clobber (match_operand:DI 4 "memory_operand" ""))
14882 (clobber (match_scratch 5 ""))]
14884 [(parallel [(set (match_dup 4)
14885 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14886 (use (match_dup 2))
14887 (use (match_dup 3))
14888 (clobber (match_dup 5))])
14889 (set (match_dup 0) (match_dup 4))])
14892 [(set (match_operand:DI 0 "memory_operand" "")
14893 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14895 (use (match_operand:HI 2 "memory_operand" ""))
14896 (use (match_operand:HI 3 "memory_operand" ""))
14897 (clobber (match_operand:DI 4 "memory_operand" ""))
14898 (clobber (match_scratch 5 ""))]
14900 [(parallel [(set (match_dup 0)
14901 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14902 (use (match_dup 2))
14903 (use (match_dup 3))
14904 (clobber (match_dup 5))])])
14906 (define_insn "fist<mode>2_ceil"
14907 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14908 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14910 (use (match_operand:HI 2 "memory_operand" "m"))
14911 (use (match_operand:HI 3 "memory_operand" "m"))]
14912 "TARGET_USE_FANCY_MATH_387
14913 && flag_unsafe_math_optimizations"
14914 "* return output_fix_trunc (insn, operands, false);"
14915 [(set_attr "type" "fistp")
14916 (set_attr "i387_cw" "ceil")
14917 (set_attr "mode" "<MODE>")])
14919 (define_insn "fist<mode>2_ceil_with_temp"
14920 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14921 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14923 (use (match_operand:HI 2 "memory_operand" "m,m"))
14924 (use (match_operand:HI 3 "memory_operand" "m,m"))
14925 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14926 "TARGET_USE_FANCY_MATH_387
14927 && flag_unsafe_math_optimizations"
14929 [(set_attr "type" "fistp")
14930 (set_attr "i387_cw" "ceil")
14931 (set_attr "mode" "<MODE>")])
14934 [(set (match_operand:SWI24 0 "register_operand" "")
14935 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14937 (use (match_operand:HI 2 "memory_operand" ""))
14938 (use (match_operand:HI 3 "memory_operand" ""))
14939 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14941 [(parallel [(set (match_dup 4)
14942 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
14943 (use (match_dup 2))
14944 (use (match_dup 3))])
14945 (set (match_dup 0) (match_dup 4))])
14948 [(set (match_operand:SWI24 0 "memory_operand" "")
14949 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14951 (use (match_operand:HI 2 "memory_operand" ""))
14952 (use (match_operand:HI 3 "memory_operand" ""))
14953 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14955 [(parallel [(set (match_dup 0)
14956 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
14957 (use (match_dup 2))
14958 (use (match_dup 3))])])
14960 (define_expand "lceilxf<mode>2"
14961 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14962 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14964 (clobber (reg:CC FLAGS_REG))])]
14965 "TARGET_USE_FANCY_MATH_387
14966 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14967 && flag_unsafe_math_optimizations")
14969 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14970 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14971 (match_operand:MODEF 1 "register_operand" "")]
14972 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14973 && !flag_trapping_math"
14975 ix86_expand_lfloorceil (operand0, operand1, false);
14979 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14980 (define_insn_and_split "frndintxf2_trunc"
14981 [(set (match_operand:XF 0 "register_operand" "")
14982 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14983 UNSPEC_FRNDINT_TRUNC))
14984 (clobber (reg:CC FLAGS_REG))]
14985 "TARGET_USE_FANCY_MATH_387
14986 && flag_unsafe_math_optimizations
14987 && can_create_pseudo_p ()"
14992 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14994 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14995 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14997 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14998 operands[2], operands[3]));
15001 [(set_attr "type" "frndint")
15002 (set_attr "i387_cw" "trunc")
15003 (set_attr "mode" "XF")])
15005 (define_insn "frndintxf2_trunc_i387"
15006 [(set (match_operand:XF 0 "register_operand" "=f")
15007 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15008 UNSPEC_FRNDINT_TRUNC))
15009 (use (match_operand:HI 2 "memory_operand" "m"))
15010 (use (match_operand:HI 3 "memory_operand" "m"))]
15011 "TARGET_USE_FANCY_MATH_387
15012 && flag_unsafe_math_optimizations"
15013 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15014 [(set_attr "type" "frndint")
15015 (set_attr "i387_cw" "trunc")
15016 (set_attr "mode" "XF")])
15018 (define_expand "btruncxf2"
15019 [(use (match_operand:XF 0 "register_operand" ""))
15020 (use (match_operand:XF 1 "register_operand" ""))]
15021 "TARGET_USE_FANCY_MATH_387
15022 && flag_unsafe_math_optimizations"
15024 if (optimize_insn_for_size_p ())
15026 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15030 (define_expand "btrunc<mode>2"
15031 [(use (match_operand:MODEF 0 "register_operand" ""))
15032 (use (match_operand:MODEF 1 "register_operand" ""))]
15033 "(TARGET_USE_FANCY_MATH_387
15034 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15035 || TARGET_MIX_SSE_I387)
15036 && flag_unsafe_math_optimizations)
15037 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15038 && !flag_trapping_math)"
15040 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15041 && !flag_trapping_math
15042 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15045 emit_insn (gen_sse4_1_round<mode>2
15046 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15047 else if (optimize_insn_for_size_p ())
15049 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15050 ix86_expand_trunc (operand0, operand1);
15052 ix86_expand_truncdf_32 (operand0, operand1);
15058 if (optimize_insn_for_size_p ())
15061 op0 = gen_reg_rtx (XFmode);
15062 op1 = gen_reg_rtx (XFmode);
15063 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15064 emit_insn (gen_frndintxf2_trunc (op0, op1));
15066 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15071 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15072 (define_insn_and_split "frndintxf2_mask_pm"
15073 [(set (match_operand:XF 0 "register_operand" "")
15074 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15075 UNSPEC_FRNDINT_MASK_PM))
15076 (clobber (reg:CC FLAGS_REG))]
15077 "TARGET_USE_FANCY_MATH_387
15078 && flag_unsafe_math_optimizations
15079 && can_create_pseudo_p ()"
15084 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15086 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15087 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15089 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15090 operands[2], operands[3]));
15093 [(set_attr "type" "frndint")
15094 (set_attr "i387_cw" "mask_pm")
15095 (set_attr "mode" "XF")])
15097 (define_insn "frndintxf2_mask_pm_i387"
15098 [(set (match_operand:XF 0 "register_operand" "=f")
15099 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15100 UNSPEC_FRNDINT_MASK_PM))
15101 (use (match_operand:HI 2 "memory_operand" "m"))
15102 (use (match_operand:HI 3 "memory_operand" "m"))]
15103 "TARGET_USE_FANCY_MATH_387
15104 && flag_unsafe_math_optimizations"
15105 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15106 [(set_attr "type" "frndint")
15107 (set_attr "i387_cw" "mask_pm")
15108 (set_attr "mode" "XF")])
15110 (define_expand "nearbyintxf2"
15111 [(use (match_operand:XF 0 "register_operand" ""))
15112 (use (match_operand:XF 1 "register_operand" ""))]
15113 "TARGET_USE_FANCY_MATH_387
15114 && flag_unsafe_math_optimizations"
15116 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15120 (define_expand "nearbyint<mode>2"
15121 [(use (match_operand:MODEF 0 "register_operand" ""))
15122 (use (match_operand:MODEF 1 "register_operand" ""))]
15123 "TARGET_USE_FANCY_MATH_387
15124 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15125 || TARGET_MIX_SSE_I387)
15126 && flag_unsafe_math_optimizations"
15128 rtx op0 = gen_reg_rtx (XFmode);
15129 rtx op1 = gen_reg_rtx (XFmode);
15131 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15132 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15134 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15138 (define_insn "fxam<mode>2_i387"
15139 [(set (match_operand:HI 0 "register_operand" "=a")
15141 [(match_operand:X87MODEF 1 "register_operand" "f")]
15143 "TARGET_USE_FANCY_MATH_387"
15144 "fxam\n\tfnstsw\t%0"
15145 [(set_attr "type" "multi")
15146 (set_attr "length" "4")
15147 (set_attr "unit" "i387")
15148 (set_attr "mode" "<MODE>")])
15150 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15151 [(set (match_operand:HI 0 "register_operand" "")
15153 [(match_operand:MODEF 1 "memory_operand" "")]
15155 "TARGET_USE_FANCY_MATH_387
15156 && can_create_pseudo_p ()"
15159 [(set (match_dup 2)(match_dup 1))
15161 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15163 operands[2] = gen_reg_rtx (<MODE>mode);
15165 MEM_VOLATILE_P (operands[1]) = 1;
15167 [(set_attr "type" "multi")
15168 (set_attr "unit" "i387")
15169 (set_attr "mode" "<MODE>")])
15171 (define_expand "isinfxf2"
15172 [(use (match_operand:SI 0 "register_operand" ""))
15173 (use (match_operand:XF 1 "register_operand" ""))]
15174 "TARGET_USE_FANCY_MATH_387
15175 && TARGET_C99_FUNCTIONS"
15177 rtx mask = GEN_INT (0x45);
15178 rtx val = GEN_INT (0x05);
15182 rtx scratch = gen_reg_rtx (HImode);
15183 rtx res = gen_reg_rtx (QImode);
15185 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15187 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15188 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15189 cond = gen_rtx_fmt_ee (EQ, QImode,
15190 gen_rtx_REG (CCmode, FLAGS_REG),
15192 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15193 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15197 (define_expand "isinf<mode>2"
15198 [(use (match_operand:SI 0 "register_operand" ""))
15199 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15200 "TARGET_USE_FANCY_MATH_387
15201 && TARGET_C99_FUNCTIONS
15202 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15204 rtx mask = GEN_INT (0x45);
15205 rtx val = GEN_INT (0x05);
15209 rtx scratch = gen_reg_rtx (HImode);
15210 rtx res = gen_reg_rtx (QImode);
15212 /* Remove excess precision by forcing value through memory. */
15213 if (memory_operand (operands[1], VOIDmode))
15214 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15217 enum ix86_stack_slot slot = (virtuals_instantiated
15220 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15222 emit_move_insn (temp, operands[1]);
15223 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15226 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15227 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15228 cond = gen_rtx_fmt_ee (EQ, QImode,
15229 gen_rtx_REG (CCmode, FLAGS_REG),
15231 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15232 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15236 (define_expand "signbitxf2"
15237 [(use (match_operand:SI 0 "register_operand" ""))
15238 (use (match_operand:XF 1 "register_operand" ""))]
15239 "TARGET_USE_FANCY_MATH_387"
15241 rtx scratch = gen_reg_rtx (HImode);
15243 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15244 emit_insn (gen_andsi3 (operands[0],
15245 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15249 (define_insn "movmsk_df"
15250 [(set (match_operand:SI 0 "register_operand" "=r")
15252 [(match_operand:DF 1 "register_operand" "x")]
15254 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15255 "%vmovmskpd\t{%1, %0|%0, %1}"
15256 [(set_attr "type" "ssemov")
15257 (set_attr "prefix" "maybe_vex")
15258 (set_attr "mode" "DF")])
15260 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15261 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15262 (define_expand "signbitdf2"
15263 [(use (match_operand:SI 0 "register_operand" ""))
15264 (use (match_operand:DF 1 "register_operand" ""))]
15265 "TARGET_USE_FANCY_MATH_387
15266 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15268 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15270 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15271 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15275 rtx scratch = gen_reg_rtx (HImode);
15277 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15278 emit_insn (gen_andsi3 (operands[0],
15279 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15284 (define_expand "signbitsf2"
15285 [(use (match_operand:SI 0 "register_operand" ""))
15286 (use (match_operand:SF 1 "register_operand" ""))]
15287 "TARGET_USE_FANCY_MATH_387
15288 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15290 rtx scratch = gen_reg_rtx (HImode);
15292 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15293 emit_insn (gen_andsi3 (operands[0],
15294 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15298 ;; Block operation instructions
15301 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15304 [(set_attr "length" "1")
15305 (set_attr "length_immediate" "0")
15306 (set_attr "modrm" "0")])
15308 (define_expand "movmem<mode>"
15309 [(use (match_operand:BLK 0 "memory_operand" ""))
15310 (use (match_operand:BLK 1 "memory_operand" ""))
15311 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15312 (use (match_operand:SWI48 3 "const_int_operand" ""))
15313 (use (match_operand:SI 4 "const_int_operand" ""))
15314 (use (match_operand:SI 5 "const_int_operand" ""))]
15317 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15318 operands[4], operands[5]))
15324 ;; Most CPUs don't like single string operations
15325 ;; Handle this case here to simplify previous expander.
15327 (define_expand "strmov"
15328 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15329 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15330 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15331 (clobber (reg:CC FLAGS_REG))])
15332 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15333 (clobber (reg:CC FLAGS_REG))])]
15336 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15338 /* If .md ever supports :P for Pmode, these can be directly
15339 in the pattern above. */
15340 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15341 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15343 /* Can't use this if the user has appropriated esi or edi. */
15344 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15345 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15347 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15348 operands[2], operands[3],
15349 operands[5], operands[6]));
15353 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15356 (define_expand "strmov_singleop"
15357 [(parallel [(set (match_operand 1 "memory_operand" "")
15358 (match_operand 3 "memory_operand" ""))
15359 (set (match_operand 0 "register_operand" "")
15360 (match_operand 4 "" ""))
15361 (set (match_operand 2 "register_operand" "")
15362 (match_operand 5 "" ""))])]
15364 "ix86_current_function_needs_cld = 1;")
15366 (define_insn "*strmovdi_rex_1"
15367 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15368 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15369 (set (match_operand:DI 0 "register_operand" "=D")
15370 (plus:DI (match_dup 2)
15372 (set (match_operand:DI 1 "register_operand" "=S")
15373 (plus:DI (match_dup 3)
15377 [(set_attr "type" "str")
15378 (set_attr "memory" "both")
15379 (set_attr "mode" "DI")])
15381 (define_insn "*strmovsi_1"
15382 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15383 (mem:SI (match_operand:P 3 "register_operand" "1")))
15384 (set (match_operand:P 0 "register_operand" "=D")
15385 (plus:P (match_dup 2)
15387 (set (match_operand:P 1 "register_operand" "=S")
15388 (plus:P (match_dup 3)
15392 [(set_attr "type" "str")
15393 (set_attr "memory" "both")
15394 (set_attr "mode" "SI")])
15396 (define_insn "*strmovhi_1"
15397 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15398 (mem:HI (match_operand:P 3 "register_operand" "1")))
15399 (set (match_operand:P 0 "register_operand" "=D")
15400 (plus:P (match_dup 2)
15402 (set (match_operand:P 1 "register_operand" "=S")
15403 (plus:P (match_dup 3)
15407 [(set_attr "type" "str")
15408 (set_attr "memory" "both")
15409 (set_attr "mode" "HI")])
15411 (define_insn "*strmovqi_1"
15412 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15413 (mem:QI (match_operand:P 3 "register_operand" "1")))
15414 (set (match_operand:P 0 "register_operand" "=D")
15415 (plus:P (match_dup 2)
15417 (set (match_operand:P 1 "register_operand" "=S")
15418 (plus:P (match_dup 3)
15422 [(set_attr "type" "str")
15423 (set_attr "memory" "both")
15424 (set (attr "prefix_rex")
15426 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15428 (const_string "*")))
15429 (set_attr "mode" "QI")])
15431 (define_expand "rep_mov"
15432 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15433 (set (match_operand 0 "register_operand" "")
15434 (match_operand 5 "" ""))
15435 (set (match_operand 2 "register_operand" "")
15436 (match_operand 6 "" ""))
15437 (set (match_operand 1 "memory_operand" "")
15438 (match_operand 3 "memory_operand" ""))
15439 (use (match_dup 4))])]
15441 "ix86_current_function_needs_cld = 1;")
15443 (define_insn "*rep_movdi_rex64"
15444 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15445 (set (match_operand:DI 0 "register_operand" "=D")
15446 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15448 (match_operand:DI 3 "register_operand" "0")))
15449 (set (match_operand:DI 1 "register_operand" "=S")
15450 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15451 (match_operand:DI 4 "register_operand" "1")))
15452 (set (mem:BLK (match_dup 3))
15453 (mem:BLK (match_dup 4)))
15454 (use (match_dup 5))]
15457 [(set_attr "type" "str")
15458 (set_attr "prefix_rep" "1")
15459 (set_attr "memory" "both")
15460 (set_attr "mode" "DI")])
15462 (define_insn "*rep_movsi"
15463 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15464 (set (match_operand:P 0 "register_operand" "=D")
15465 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15467 (match_operand:P 3 "register_operand" "0")))
15468 (set (match_operand:P 1 "register_operand" "=S")
15469 (plus:P (ashift:P (match_dup 5) (const_int 2))
15470 (match_operand:P 4 "register_operand" "1")))
15471 (set (mem:BLK (match_dup 3))
15472 (mem:BLK (match_dup 4)))
15473 (use (match_dup 5))]
15475 "rep{%;} movs{l|d}"
15476 [(set_attr "type" "str")
15477 (set_attr "prefix_rep" "1")
15478 (set_attr "memory" "both")
15479 (set_attr "mode" "SI")])
15481 (define_insn "*rep_movqi"
15482 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15483 (set (match_operand:P 0 "register_operand" "=D")
15484 (plus:P (match_operand:P 3 "register_operand" "0")
15485 (match_operand:P 5 "register_operand" "2")))
15486 (set (match_operand:P 1 "register_operand" "=S")
15487 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15488 (set (mem:BLK (match_dup 3))
15489 (mem:BLK (match_dup 4)))
15490 (use (match_dup 5))]
15493 [(set_attr "type" "str")
15494 (set_attr "prefix_rep" "1")
15495 (set_attr "memory" "both")
15496 (set_attr "mode" "QI")])
15498 (define_expand "setmem<mode>"
15499 [(use (match_operand:BLK 0 "memory_operand" ""))
15500 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15501 (use (match_operand:QI 2 "nonmemory_operand" ""))
15502 (use (match_operand 3 "const_int_operand" ""))
15503 (use (match_operand:SI 4 "const_int_operand" ""))
15504 (use (match_operand:SI 5 "const_int_operand" ""))]
15507 if (ix86_expand_setmem (operands[0], operands[1],
15508 operands[2], operands[3],
15509 operands[4], operands[5]))
15515 ;; Most CPUs don't like single string operations
15516 ;; Handle this case here to simplify previous expander.
15518 (define_expand "strset"
15519 [(set (match_operand 1 "memory_operand" "")
15520 (match_operand 2 "register_operand" ""))
15521 (parallel [(set (match_operand 0 "register_operand" "")
15523 (clobber (reg:CC FLAGS_REG))])]
15526 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15527 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15529 /* If .md ever supports :P for Pmode, this can be directly
15530 in the pattern above. */
15531 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15532 GEN_INT (GET_MODE_SIZE (GET_MODE
15534 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15536 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15542 (define_expand "strset_singleop"
15543 [(parallel [(set (match_operand 1 "memory_operand" "")
15544 (match_operand 2 "register_operand" ""))
15545 (set (match_operand 0 "register_operand" "")
15546 (match_operand 3 "" ""))])]
15548 "ix86_current_function_needs_cld = 1;")
15550 (define_insn "*strsetdi_rex_1"
15551 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15552 (match_operand:DI 2 "register_operand" "a"))
15553 (set (match_operand:DI 0 "register_operand" "=D")
15554 (plus:DI (match_dup 1)
15558 [(set_attr "type" "str")
15559 (set_attr "memory" "store")
15560 (set_attr "mode" "DI")])
15562 (define_insn "*strsetsi_1"
15563 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15564 (match_operand:SI 2 "register_operand" "a"))
15565 (set (match_operand:P 0 "register_operand" "=D")
15566 (plus:P (match_dup 1)
15570 [(set_attr "type" "str")
15571 (set_attr "memory" "store")
15572 (set_attr "mode" "SI")])
15574 (define_insn "*strsethi_1"
15575 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15576 (match_operand:HI 2 "register_operand" "a"))
15577 (set (match_operand:P 0 "register_operand" "=D")
15578 (plus:P (match_dup 1)
15582 [(set_attr "type" "str")
15583 (set_attr "memory" "store")
15584 (set_attr "mode" "HI")])
15586 (define_insn "*strsetqi_1"
15587 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15588 (match_operand:QI 2 "register_operand" "a"))
15589 (set (match_operand:P 0 "register_operand" "=D")
15590 (plus:P (match_dup 1)
15594 [(set_attr "type" "str")
15595 (set_attr "memory" "store")
15596 (set (attr "prefix_rex")
15598 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15600 (const_string "*")))
15601 (set_attr "mode" "QI")])
15603 (define_expand "rep_stos"
15604 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15605 (set (match_operand 0 "register_operand" "")
15606 (match_operand 4 "" ""))
15607 (set (match_operand 2 "memory_operand" "") (const_int 0))
15608 (use (match_operand 3 "register_operand" ""))
15609 (use (match_dup 1))])]
15611 "ix86_current_function_needs_cld = 1;")
15613 (define_insn "*rep_stosdi_rex64"
15614 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15615 (set (match_operand:DI 0 "register_operand" "=D")
15616 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15618 (match_operand:DI 3 "register_operand" "0")))
15619 (set (mem:BLK (match_dup 3))
15621 (use (match_operand:DI 2 "register_operand" "a"))
15622 (use (match_dup 4))]
15625 [(set_attr "type" "str")
15626 (set_attr "prefix_rep" "1")
15627 (set_attr "memory" "store")
15628 (set_attr "mode" "DI")])
15630 (define_insn "*rep_stossi"
15631 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15632 (set (match_operand:P 0 "register_operand" "=D")
15633 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15635 (match_operand:P 3 "register_operand" "0")))
15636 (set (mem:BLK (match_dup 3))
15638 (use (match_operand:SI 2 "register_operand" "a"))
15639 (use (match_dup 4))]
15641 "rep{%;} stos{l|d}"
15642 [(set_attr "type" "str")
15643 (set_attr "prefix_rep" "1")
15644 (set_attr "memory" "store")
15645 (set_attr "mode" "SI")])
15647 (define_insn "*rep_stosqi"
15648 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15649 (set (match_operand:P 0 "register_operand" "=D")
15650 (plus:P (match_operand:P 3 "register_operand" "0")
15651 (match_operand:P 4 "register_operand" "1")))
15652 (set (mem:BLK (match_dup 3))
15654 (use (match_operand:QI 2 "register_operand" "a"))
15655 (use (match_dup 4))]
15658 [(set_attr "type" "str")
15659 (set_attr "prefix_rep" "1")
15660 (set_attr "memory" "store")
15661 (set (attr "prefix_rex")
15663 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15665 (const_string "*")))
15666 (set_attr "mode" "QI")])
15668 (define_expand "cmpstrnsi"
15669 [(set (match_operand:SI 0 "register_operand" "")
15670 (compare:SI (match_operand:BLK 1 "general_operand" "")
15671 (match_operand:BLK 2 "general_operand" "")))
15672 (use (match_operand 3 "general_operand" ""))
15673 (use (match_operand 4 "immediate_operand" ""))]
15676 rtx addr1, addr2, out, outlow, count, countreg, align;
15678 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15681 /* Can't use this if the user has appropriated esi or edi. */
15682 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15687 out = gen_reg_rtx (SImode);
15689 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15690 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15691 if (addr1 != XEXP (operands[1], 0))
15692 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15693 if (addr2 != XEXP (operands[2], 0))
15694 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15696 count = operands[3];
15697 countreg = ix86_zero_extend_to_Pmode (count);
15699 /* %%% Iff we are testing strict equality, we can use known alignment
15700 to good advantage. This may be possible with combine, particularly
15701 once cc0 is dead. */
15702 align = operands[4];
15704 if (CONST_INT_P (count))
15706 if (INTVAL (count) == 0)
15708 emit_move_insn (operands[0], const0_rtx);
15711 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15712 operands[1], operands[2]));
15716 rtx (*gen_cmp) (rtx, rtx);
15718 gen_cmp = (TARGET_64BIT
15719 ? gen_cmpdi_1 : gen_cmpsi_1);
15721 emit_insn (gen_cmp (countreg, countreg));
15722 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15723 operands[1], operands[2]));
15726 outlow = gen_lowpart (QImode, out);
15727 emit_insn (gen_cmpintqi (outlow));
15728 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15730 if (operands[0] != out)
15731 emit_move_insn (operands[0], out);
15736 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15738 (define_expand "cmpintqi"
15739 [(set (match_dup 1)
15740 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15742 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15743 (parallel [(set (match_operand:QI 0 "register_operand" "")
15744 (minus:QI (match_dup 1)
15746 (clobber (reg:CC FLAGS_REG))])]
15749 operands[1] = gen_reg_rtx (QImode);
15750 operands[2] = gen_reg_rtx (QImode);
15753 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15754 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15756 (define_expand "cmpstrnqi_nz_1"
15757 [(parallel [(set (reg:CC FLAGS_REG)
15758 (compare:CC (match_operand 4 "memory_operand" "")
15759 (match_operand 5 "memory_operand" "")))
15760 (use (match_operand 2 "register_operand" ""))
15761 (use (match_operand:SI 3 "immediate_operand" ""))
15762 (clobber (match_operand 0 "register_operand" ""))
15763 (clobber (match_operand 1 "register_operand" ""))
15764 (clobber (match_dup 2))])]
15766 "ix86_current_function_needs_cld = 1;")
15768 (define_insn "*cmpstrnqi_nz_1"
15769 [(set (reg:CC FLAGS_REG)
15770 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15771 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15772 (use (match_operand:P 6 "register_operand" "2"))
15773 (use (match_operand:SI 3 "immediate_operand" "i"))
15774 (clobber (match_operand:P 0 "register_operand" "=S"))
15775 (clobber (match_operand:P 1 "register_operand" "=D"))
15776 (clobber (match_operand:P 2 "register_operand" "=c"))]
15779 [(set_attr "type" "str")
15780 (set_attr "mode" "QI")
15781 (set (attr "prefix_rex")
15783 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15785 (const_string "*")))
15786 (set_attr "prefix_rep" "1")])
15788 ;; The same, but the count is not known to not be zero.
15790 (define_expand "cmpstrnqi_1"
15791 [(parallel [(set (reg:CC FLAGS_REG)
15792 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15794 (compare:CC (match_operand 4 "memory_operand" "")
15795 (match_operand 5 "memory_operand" ""))
15797 (use (match_operand:SI 3 "immediate_operand" ""))
15798 (use (reg:CC FLAGS_REG))
15799 (clobber (match_operand 0 "register_operand" ""))
15800 (clobber (match_operand 1 "register_operand" ""))
15801 (clobber (match_dup 2))])]
15803 "ix86_current_function_needs_cld = 1;")
15805 (define_insn "*cmpstrnqi_1"
15806 [(set (reg:CC FLAGS_REG)
15807 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15809 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15810 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15812 (use (match_operand:SI 3 "immediate_operand" "i"))
15813 (use (reg:CC FLAGS_REG))
15814 (clobber (match_operand:P 0 "register_operand" "=S"))
15815 (clobber (match_operand:P 1 "register_operand" "=D"))
15816 (clobber (match_operand:P 2 "register_operand" "=c"))]
15819 [(set_attr "type" "str")
15820 (set_attr "mode" "QI")
15821 (set (attr "prefix_rex")
15823 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15825 (const_string "*")))
15826 (set_attr "prefix_rep" "1")])
15828 (define_expand "strlen<mode>"
15829 [(set (match_operand:P 0 "register_operand" "")
15830 (unspec:P [(match_operand:BLK 1 "general_operand" "")
15831 (match_operand:QI 2 "immediate_operand" "")
15832 (match_operand 3 "immediate_operand" "")]
15836 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15842 (define_expand "strlenqi_1"
15843 [(parallel [(set (match_operand 0 "register_operand" "")
15844 (match_operand 2 "" ""))
15845 (clobber (match_operand 1 "register_operand" ""))
15846 (clobber (reg:CC FLAGS_REG))])]
15848 "ix86_current_function_needs_cld = 1;")
15850 (define_insn "*strlenqi_1"
15851 [(set (match_operand:P 0 "register_operand" "=&c")
15852 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15853 (match_operand:QI 2 "register_operand" "a")
15854 (match_operand:P 3 "immediate_operand" "i")
15855 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15856 (clobber (match_operand:P 1 "register_operand" "=D"))
15857 (clobber (reg:CC FLAGS_REG))]
15860 [(set_attr "type" "str")
15861 (set_attr "mode" "QI")
15862 (set (attr "prefix_rex")
15864 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15866 (const_string "*")))
15867 (set_attr "prefix_rep" "1")])
15869 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15870 ;; handled in combine, but it is not currently up to the task.
15871 ;; When used for their truth value, the cmpstrn* expanders generate
15880 ;; The intermediate three instructions are unnecessary.
15882 ;; This one handles cmpstrn*_nz_1...
15885 (set (reg:CC FLAGS_REG)
15886 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15887 (mem:BLK (match_operand 5 "register_operand" ""))))
15888 (use (match_operand 6 "register_operand" ""))
15889 (use (match_operand:SI 3 "immediate_operand" ""))
15890 (clobber (match_operand 0 "register_operand" ""))
15891 (clobber (match_operand 1 "register_operand" ""))
15892 (clobber (match_operand 2 "register_operand" ""))])
15893 (set (match_operand:QI 7 "register_operand" "")
15894 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15895 (set (match_operand:QI 8 "register_operand" "")
15896 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15897 (set (reg FLAGS_REG)
15898 (compare (match_dup 7) (match_dup 8)))
15900 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15902 (set (reg:CC FLAGS_REG)
15903 (compare:CC (mem:BLK (match_dup 4))
15904 (mem:BLK (match_dup 5))))
15905 (use (match_dup 6))
15906 (use (match_dup 3))
15907 (clobber (match_dup 0))
15908 (clobber (match_dup 1))
15909 (clobber (match_dup 2))])])
15911 ;; ...and this one handles cmpstrn*_1.
15914 (set (reg:CC FLAGS_REG)
15915 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15917 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15918 (mem:BLK (match_operand 5 "register_operand" "")))
15920 (use (match_operand:SI 3 "immediate_operand" ""))
15921 (use (reg:CC FLAGS_REG))
15922 (clobber (match_operand 0 "register_operand" ""))
15923 (clobber (match_operand 1 "register_operand" ""))
15924 (clobber (match_operand 2 "register_operand" ""))])
15925 (set (match_operand:QI 7 "register_operand" "")
15926 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15927 (set (match_operand:QI 8 "register_operand" "")
15928 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15929 (set (reg FLAGS_REG)
15930 (compare (match_dup 7) (match_dup 8)))
15932 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15934 (set (reg:CC FLAGS_REG)
15935 (if_then_else:CC (ne (match_dup 6)
15937 (compare:CC (mem:BLK (match_dup 4))
15938 (mem:BLK (match_dup 5)))
15940 (use (match_dup 3))
15941 (use (reg:CC FLAGS_REG))
15942 (clobber (match_dup 0))
15943 (clobber (match_dup 1))
15944 (clobber (match_dup 2))])])
15946 ;; Conditional move instructions.
15948 (define_expand "mov<mode>cc"
15949 [(set (match_operand:SWIM 0 "register_operand" "")
15950 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15951 (match_operand:SWIM 2 "<general_operand>" "")
15952 (match_operand:SWIM 3 "<general_operand>" "")))]
15954 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15956 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15957 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15958 ;; So just document what we're doing explicitly.
15960 (define_expand "x86_mov<mode>cc_0_m1"
15962 [(set (match_operand:SWI48 0 "register_operand" "")
15963 (if_then_else:SWI48
15964 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15965 [(match_operand 1 "flags_reg_operand" "")
15969 (clobber (reg:CC FLAGS_REG))])])
15971 (define_insn "*x86_mov<mode>cc_0_m1"
15972 [(set (match_operand:SWI48 0 "register_operand" "=r")
15973 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15974 [(reg FLAGS_REG) (const_int 0)])
15977 (clobber (reg:CC FLAGS_REG))]
15979 "sbb{<imodesuffix>}\t%0, %0"
15980 ; Since we don't have the proper number of operands for an alu insn,
15981 ; fill in all the blanks.
15982 [(set_attr "type" "alu")
15983 (set_attr "use_carry" "1")
15984 (set_attr "pent_pair" "pu")
15985 (set_attr "memory" "none")
15986 (set_attr "imm_disp" "false")
15987 (set_attr "mode" "<MODE>")
15988 (set_attr "length_immediate" "0")])
15990 (define_insn "*x86_mov<mode>cc_0_m1_se"
15991 [(set (match_operand:SWI48 0 "register_operand" "=r")
15992 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15993 [(reg FLAGS_REG) (const_int 0)])
15996 (clobber (reg:CC FLAGS_REG))]
15998 "sbb{<imodesuffix>}\t%0, %0"
15999 [(set_attr "type" "alu")
16000 (set_attr "use_carry" "1")
16001 (set_attr "pent_pair" "pu")
16002 (set_attr "memory" "none")
16003 (set_attr "imm_disp" "false")
16004 (set_attr "mode" "<MODE>")
16005 (set_attr "length_immediate" "0")])
16007 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16008 [(set (match_operand:SWI48 0 "register_operand" "=r")
16009 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16010 [(reg FLAGS_REG) (const_int 0)])))]
16012 "sbb{<imodesuffix>}\t%0, %0"
16013 [(set_attr "type" "alu")
16014 (set_attr "use_carry" "1")
16015 (set_attr "pent_pair" "pu")
16016 (set_attr "memory" "none")
16017 (set_attr "imm_disp" "false")
16018 (set_attr "mode" "<MODE>")
16019 (set_attr "length_immediate" "0")])
16021 (define_insn "*mov<mode>cc_noc"
16022 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16023 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16024 [(reg FLAGS_REG) (const_int 0)])
16025 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16026 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16027 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16029 cmov%O2%C1\t{%2, %0|%0, %2}
16030 cmov%O2%c1\t{%3, %0|%0, %3}"
16031 [(set_attr "type" "icmov")
16032 (set_attr "mode" "<MODE>")])
16034 (define_insn_and_split "*movqicc_noc"
16035 [(set (match_operand:QI 0 "register_operand" "=r,r")
16036 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16037 [(match_operand 4 "flags_reg_operand" "")
16039 (match_operand:QI 2 "register_operand" "r,0")
16040 (match_operand:QI 3 "register_operand" "0,r")))]
16041 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16043 "&& reload_completed"
16044 [(set (match_dup 0)
16045 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16048 "operands[0] = gen_lowpart (SImode, operands[0]);
16049 operands[2] = gen_lowpart (SImode, operands[2]);
16050 operands[3] = gen_lowpart (SImode, operands[3]);"
16051 [(set_attr "type" "icmov")
16052 (set_attr "mode" "SI")])
16054 (define_expand "mov<mode>cc"
16055 [(set (match_operand:X87MODEF 0 "register_operand" "")
16056 (if_then_else:X87MODEF
16057 (match_operand 1 "ix86_fp_comparison_operator" "")
16058 (match_operand:X87MODEF 2 "register_operand" "")
16059 (match_operand:X87MODEF 3 "register_operand" "")))]
16060 "(TARGET_80387 && TARGET_CMOVE)
16061 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16062 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16064 (define_insn "*movxfcc_1"
16065 [(set (match_operand:XF 0 "register_operand" "=f,f")
16066 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16067 [(reg FLAGS_REG) (const_int 0)])
16068 (match_operand:XF 2 "register_operand" "f,0")
16069 (match_operand:XF 3 "register_operand" "0,f")))]
16070 "TARGET_80387 && TARGET_CMOVE"
16072 fcmov%F1\t{%2, %0|%0, %2}
16073 fcmov%f1\t{%3, %0|%0, %3}"
16074 [(set_attr "type" "fcmov")
16075 (set_attr "mode" "XF")])
16077 (define_insn "*movdfcc_1_rex64"
16078 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16079 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16080 [(reg FLAGS_REG) (const_int 0)])
16081 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16082 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16083 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16084 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16086 fcmov%F1\t{%2, %0|%0, %2}
16087 fcmov%f1\t{%3, %0|%0, %3}
16088 cmov%O2%C1\t{%2, %0|%0, %2}
16089 cmov%O2%c1\t{%3, %0|%0, %3}"
16090 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16091 (set_attr "mode" "DF,DF,DI,DI")])
16093 (define_insn "*movdfcc_1"
16094 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16095 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16096 [(reg FLAGS_REG) (const_int 0)])
16097 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16098 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16099 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16100 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16102 fcmov%F1\t{%2, %0|%0, %2}
16103 fcmov%f1\t{%3, %0|%0, %3}
16106 [(set_attr "type" "fcmov,fcmov,multi,multi")
16107 (set_attr "mode" "DF,DF,DI,DI")])
16110 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16111 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16112 [(match_operand 4 "flags_reg_operand" "")
16114 (match_operand:DF 2 "nonimmediate_operand" "")
16115 (match_operand:DF 3 "nonimmediate_operand" "")))]
16116 "!TARGET_64BIT && reload_completed"
16117 [(set (match_dup 2)
16118 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16122 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16126 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16127 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16130 (define_insn "*movsfcc_1_387"
16131 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16132 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16133 [(reg FLAGS_REG) (const_int 0)])
16134 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16135 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16136 "TARGET_80387 && TARGET_CMOVE
16137 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16139 fcmov%F1\t{%2, %0|%0, %2}
16140 fcmov%f1\t{%3, %0|%0, %3}
16141 cmov%O2%C1\t{%2, %0|%0, %2}
16142 cmov%O2%c1\t{%3, %0|%0, %3}"
16143 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16144 (set_attr "mode" "SF,SF,SI,SI")])
16146 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16147 ;; the scalar versions to have only XMM registers as operands.
16149 ;; XOP conditional move
16150 (define_insn "*xop_pcmov_<mode>"
16151 [(set (match_operand:MODEF 0 "register_operand" "=x")
16152 (if_then_else:MODEF
16153 (match_operand:MODEF 1 "register_operand" "x")
16154 (match_operand:MODEF 2 "register_operand" "x")
16155 (match_operand:MODEF 3 "register_operand" "x")))]
16157 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16158 [(set_attr "type" "sse4arg")])
16160 ;; These versions of the min/max patterns are intentionally ignorant of
16161 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16162 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16163 ;; are undefined in this condition, we're certain this is correct.
16165 (define_insn "<code><mode>3"
16166 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16168 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16169 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16170 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16172 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16173 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16174 [(set_attr "isa" "noavx,avx")
16175 (set_attr "prefix" "orig,vex")
16176 (set_attr "type" "sseadd")
16177 (set_attr "mode" "<MODE>")])
16179 ;; These versions of the min/max patterns implement exactly the operations
16180 ;; min = (op1 < op2 ? op1 : op2)
16181 ;; max = (!(op1 < op2) ? op1 : op2)
16182 ;; Their operands are not commutative, and thus they may be used in the
16183 ;; presence of -0.0 and NaN.
16185 (define_insn "*ieee_smin<mode>3"
16186 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16188 [(match_operand:MODEF 1 "register_operand" "0,x")
16189 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16191 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16193 min<ssemodesuffix>\t{%2, %0|%0, %2}
16194 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16195 [(set_attr "isa" "noavx,avx")
16196 (set_attr "prefix" "orig,vex")
16197 (set_attr "type" "sseadd")
16198 (set_attr "mode" "<MODE>")])
16200 (define_insn "*ieee_smax<mode>3"
16201 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16203 [(match_operand:MODEF 1 "register_operand" "0,x")
16204 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16206 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16208 max<ssemodesuffix>\t{%2, %0|%0, %2}
16209 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16210 [(set_attr "isa" "noavx,avx")
16211 (set_attr "prefix" "orig,vex")
16212 (set_attr "type" "sseadd")
16213 (set_attr "mode" "<MODE>")])
16215 ;; Make two stack loads independent:
16217 ;; fld %st(0) -> fld bb
16218 ;; fmul bb fmul %st(1), %st
16220 ;; Actually we only match the last two instructions for simplicity.
16222 [(set (match_operand 0 "fp_register_operand" "")
16223 (match_operand 1 "fp_register_operand" ""))
16225 (match_operator 2 "binary_fp_operator"
16227 (match_operand 3 "memory_operand" "")]))]
16228 "REGNO (operands[0]) != REGNO (operands[1])"
16229 [(set (match_dup 0) (match_dup 3))
16230 (set (match_dup 0) (match_dup 4))]
16232 ;; The % modifier is not operational anymore in peephole2's, so we have to
16233 ;; swap the operands manually in the case of addition and multiplication.
16234 "if (COMMUTATIVE_ARITH_P (operands[2]))
16235 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16236 GET_MODE (operands[2]),
16237 operands[0], operands[1]);
16239 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16240 GET_MODE (operands[2]),
16241 operands[1], operands[0]);")
16243 ;; Conditional addition patterns
16244 (define_expand "add<mode>cc"
16245 [(match_operand:SWI 0 "register_operand" "")
16246 (match_operand 1 "ordered_comparison_operator" "")
16247 (match_operand:SWI 2 "register_operand" "")
16248 (match_operand:SWI 3 "const_int_operand" "")]
16250 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16252 ;; Misc patterns (?)
16254 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16255 ;; Otherwise there will be nothing to keep
16257 ;; [(set (reg ebp) (reg esp))]
16258 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16259 ;; (clobber (eflags)]
16260 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16262 ;; in proper program order.
16264 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16265 [(set (match_operand:P 0 "register_operand" "=r,r")
16266 (plus:P (match_operand:P 1 "register_operand" "0,r")
16267 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16268 (clobber (reg:CC FLAGS_REG))
16269 (clobber (mem:BLK (scratch)))]
16272 switch (get_attr_type (insn))
16275 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16278 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16279 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16280 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16282 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16285 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16286 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16289 [(set (attr "type")
16290 (cond [(and (eq_attr "alternative" "0")
16291 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16292 (const_string "alu")
16293 (match_operand:<MODE> 2 "const0_operand" "")
16294 (const_string "imov")
16296 (const_string "lea")))
16297 (set (attr "length_immediate")
16298 (cond [(eq_attr "type" "imov")
16300 (and (eq_attr "type" "alu")
16301 (match_operand 2 "const128_operand" ""))
16304 (const_string "*")))
16305 (set_attr "mode" "<MODE>")])
16307 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16308 [(set (match_operand:P 0 "register_operand" "=r")
16309 (minus:P (match_operand:P 1 "register_operand" "0")
16310 (match_operand:P 2 "register_operand" "r")))
16311 (clobber (reg:CC FLAGS_REG))
16312 (clobber (mem:BLK (scratch)))]
16314 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16315 [(set_attr "type" "alu")
16316 (set_attr "mode" "<MODE>")])
16318 (define_insn "allocate_stack_worker_probe_<mode>"
16319 [(set (match_operand:P 0 "register_operand" "=a")
16320 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16321 UNSPECV_STACK_PROBE))
16322 (clobber (reg:CC FLAGS_REG))]
16323 "ix86_target_stack_probe ()"
16324 "call\t___chkstk_ms"
16325 [(set_attr "type" "multi")
16326 (set_attr "length" "5")])
16328 (define_expand "allocate_stack"
16329 [(match_operand 0 "register_operand" "")
16330 (match_operand 1 "general_operand" "")]
16331 "ix86_target_stack_probe ()"
16335 #ifndef CHECK_STACK_LIMIT
16336 #define CHECK_STACK_LIMIT 0
16339 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16340 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16342 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16343 stack_pointer_rtx, 0, OPTAB_DIRECT);
16344 if (x != stack_pointer_rtx)
16345 emit_move_insn (stack_pointer_rtx, x);
16349 x = copy_to_mode_reg (Pmode, operands[1]);
16351 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16353 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16354 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16355 stack_pointer_rtx, 0, OPTAB_DIRECT);
16356 if (x != stack_pointer_rtx)
16357 emit_move_insn (stack_pointer_rtx, x);
16360 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16364 ;; Use IOR for stack probes, this is shorter.
16365 (define_expand "probe_stack"
16366 [(match_operand 0 "memory_operand" "")]
16369 rtx (*gen_ior3) (rtx, rtx, rtx);
16371 gen_ior3 = (GET_MODE (operands[0]) == DImode
16372 ? gen_iordi3 : gen_iorsi3);
16374 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16378 (define_insn "adjust_stack_and_probe<mode>"
16379 [(set (match_operand:P 0 "register_operand" "=r")
16380 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16381 UNSPECV_PROBE_STACK_RANGE))
16382 (set (reg:P SP_REG)
16383 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16384 (clobber (reg:CC FLAGS_REG))
16385 (clobber (mem:BLK (scratch)))]
16387 "* return output_adjust_stack_and_probe (operands[0]);"
16388 [(set_attr "type" "multi")])
16390 (define_insn "probe_stack_range<mode>"
16391 [(set (match_operand:P 0 "register_operand" "=r")
16392 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16393 (match_operand:P 2 "const_int_operand" "n")]
16394 UNSPECV_PROBE_STACK_RANGE))
16395 (clobber (reg:CC FLAGS_REG))]
16397 "* return output_probe_stack_range (operands[0], operands[2]);"
16398 [(set_attr "type" "multi")])
16400 (define_expand "builtin_setjmp_receiver"
16401 [(label_ref (match_operand 0 "" ""))]
16402 "!TARGET_64BIT && flag_pic"
16408 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16409 rtx label_rtx = gen_label_rtx ();
16410 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16411 xops[0] = xops[1] = picreg;
16412 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16413 ix86_expand_binary_operator (MINUS, SImode, xops);
16417 emit_insn (gen_set_got (pic_offset_table_rtx));
16421 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16424 [(set (match_operand 0 "register_operand" "")
16425 (match_operator 3 "promotable_binary_operator"
16426 [(match_operand 1 "register_operand" "")
16427 (match_operand 2 "aligned_operand" "")]))
16428 (clobber (reg:CC FLAGS_REG))]
16429 "! TARGET_PARTIAL_REG_STALL && reload_completed
16430 && ((GET_MODE (operands[0]) == HImode
16431 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16432 /* ??? next two lines just !satisfies_constraint_K (...) */
16433 || !CONST_INT_P (operands[2])
16434 || satisfies_constraint_K (operands[2])))
16435 || (GET_MODE (operands[0]) == QImode
16436 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16437 [(parallel [(set (match_dup 0)
16438 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16439 (clobber (reg:CC FLAGS_REG))])]
16440 "operands[0] = gen_lowpart (SImode, operands[0]);
16441 operands[1] = gen_lowpart (SImode, operands[1]);
16442 if (GET_CODE (operands[3]) != ASHIFT)
16443 operands[2] = gen_lowpart (SImode, operands[2]);
16444 PUT_MODE (operands[3], SImode);")
16446 ; Promote the QImode tests, as i386 has encoding of the AND
16447 ; instruction with 32-bit sign-extended immediate and thus the
16448 ; instruction size is unchanged, except in the %eax case for
16449 ; which it is increased by one byte, hence the ! optimize_size.
16451 [(set (match_operand 0 "flags_reg_operand" "")
16452 (match_operator 2 "compare_operator"
16453 [(and (match_operand 3 "aligned_operand" "")
16454 (match_operand 4 "const_int_operand" ""))
16456 (set (match_operand 1 "register_operand" "")
16457 (and (match_dup 3) (match_dup 4)))]
16458 "! TARGET_PARTIAL_REG_STALL && reload_completed
16459 && optimize_insn_for_speed_p ()
16460 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16461 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16462 /* Ensure that the operand will remain sign-extended immediate. */
16463 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16464 [(parallel [(set (match_dup 0)
16465 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16468 (and:SI (match_dup 3) (match_dup 4)))])]
16471 = gen_int_mode (INTVAL (operands[4])
16472 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16473 operands[1] = gen_lowpart (SImode, operands[1]);
16474 operands[3] = gen_lowpart (SImode, operands[3]);
16477 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16478 ; the TEST instruction with 32-bit sign-extended immediate and thus
16479 ; the instruction size would at least double, which is not what we
16480 ; want even with ! optimize_size.
16482 [(set (match_operand 0 "flags_reg_operand" "")
16483 (match_operator 1 "compare_operator"
16484 [(and (match_operand:HI 2 "aligned_operand" "")
16485 (match_operand:HI 3 "const_int_operand" ""))
16487 "! TARGET_PARTIAL_REG_STALL && reload_completed
16488 && ! TARGET_FAST_PREFIX
16489 && optimize_insn_for_speed_p ()
16490 /* Ensure that the operand will remain sign-extended immediate. */
16491 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16492 [(set (match_dup 0)
16493 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16497 = gen_int_mode (INTVAL (operands[3])
16498 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16499 operands[2] = gen_lowpart (SImode, operands[2]);
16503 [(set (match_operand 0 "register_operand" "")
16504 (neg (match_operand 1 "register_operand" "")))
16505 (clobber (reg:CC FLAGS_REG))]
16506 "! TARGET_PARTIAL_REG_STALL && reload_completed
16507 && (GET_MODE (operands[0]) == HImode
16508 || (GET_MODE (operands[0]) == QImode
16509 && (TARGET_PROMOTE_QImode
16510 || optimize_insn_for_size_p ())))"
16511 [(parallel [(set (match_dup 0)
16512 (neg:SI (match_dup 1)))
16513 (clobber (reg:CC FLAGS_REG))])]
16514 "operands[0] = gen_lowpart (SImode, operands[0]);
16515 operands[1] = gen_lowpart (SImode, operands[1]);")
16518 [(set (match_operand 0 "register_operand" "")
16519 (not (match_operand 1 "register_operand" "")))]
16520 "! TARGET_PARTIAL_REG_STALL && reload_completed
16521 && (GET_MODE (operands[0]) == HImode
16522 || (GET_MODE (operands[0]) == QImode
16523 && (TARGET_PROMOTE_QImode
16524 || optimize_insn_for_size_p ())))"
16525 [(set (match_dup 0)
16526 (not:SI (match_dup 1)))]
16527 "operands[0] = gen_lowpart (SImode, operands[0]);
16528 operands[1] = gen_lowpart (SImode, operands[1]);")
16531 [(set (match_operand 0 "register_operand" "")
16532 (if_then_else (match_operator 1 "ordered_comparison_operator"
16533 [(reg FLAGS_REG) (const_int 0)])
16534 (match_operand 2 "register_operand" "")
16535 (match_operand 3 "register_operand" "")))]
16536 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16537 && (GET_MODE (operands[0]) == HImode
16538 || (GET_MODE (operands[0]) == QImode
16539 && (TARGET_PROMOTE_QImode
16540 || optimize_insn_for_size_p ())))"
16541 [(set (match_dup 0)
16542 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16543 "operands[0] = gen_lowpart (SImode, operands[0]);
16544 operands[2] = gen_lowpart (SImode, operands[2]);
16545 operands[3] = gen_lowpart (SImode, operands[3]);")
16547 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16548 ;; transform a complex memory operation into two memory to register operations.
16550 ;; Don't push memory operands
16552 [(set (match_operand:SWI 0 "push_operand" "")
16553 (match_operand:SWI 1 "memory_operand" ""))
16554 (match_scratch:SWI 2 "<r>")]
16555 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16556 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16557 [(set (match_dup 2) (match_dup 1))
16558 (set (match_dup 0) (match_dup 2))])
16560 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16563 [(set (match_operand:SF 0 "push_operand" "")
16564 (match_operand:SF 1 "memory_operand" ""))
16565 (match_scratch:SF 2 "r")]
16566 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16567 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16568 [(set (match_dup 2) (match_dup 1))
16569 (set (match_dup 0) (match_dup 2))])
16571 ;; Don't move an immediate directly to memory when the instruction
16574 [(match_scratch:SWI124 1 "<r>")
16575 (set (match_operand:SWI124 0 "memory_operand" "")
16577 "optimize_insn_for_speed_p ()
16578 && !TARGET_USE_MOV0
16579 && TARGET_SPLIT_LONG_MOVES
16580 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16581 && peep2_regno_dead_p (0, FLAGS_REG)"
16582 [(parallel [(set (match_dup 2) (const_int 0))
16583 (clobber (reg:CC FLAGS_REG))])
16584 (set (match_dup 0) (match_dup 1))]
16585 "operands[2] = gen_lowpart (SImode, operands[1]);")
16588 [(match_scratch:SWI124 2 "<r>")
16589 (set (match_operand:SWI124 0 "memory_operand" "")
16590 (match_operand:SWI124 1 "immediate_operand" ""))]
16591 "optimize_insn_for_speed_p ()
16592 && TARGET_SPLIT_LONG_MOVES
16593 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16594 [(set (match_dup 2) (match_dup 1))
16595 (set (match_dup 0) (match_dup 2))])
16597 ;; Don't compare memory with zero, load and use a test instead.
16599 [(set (match_operand 0 "flags_reg_operand" "")
16600 (match_operator 1 "compare_operator"
16601 [(match_operand:SI 2 "memory_operand" "")
16603 (match_scratch:SI 3 "r")]
16604 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16605 [(set (match_dup 3) (match_dup 2))
16606 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16608 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16609 ;; Don't split NOTs with a displacement operand, because resulting XOR
16610 ;; will not be pairable anyway.
16612 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16613 ;; represented using a modRM byte. The XOR replacement is long decoded,
16614 ;; so this split helps here as well.
16616 ;; Note: Can't do this as a regular split because we can't get proper
16617 ;; lifetime information then.
16620 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16621 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16622 "optimize_insn_for_speed_p ()
16623 && ((TARGET_NOT_UNPAIRABLE
16624 && (!MEM_P (operands[0])
16625 || !memory_displacement_operand (operands[0], <MODE>mode)))
16626 || (TARGET_NOT_VECTORMODE
16627 && long_memory_operand (operands[0], <MODE>mode)))
16628 && peep2_regno_dead_p (0, FLAGS_REG)"
16629 [(parallel [(set (match_dup 0)
16630 (xor:SWI124 (match_dup 1) (const_int -1)))
16631 (clobber (reg:CC FLAGS_REG))])])
16633 ;; Non pairable "test imm, reg" instructions can be translated to
16634 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16635 ;; byte opcode instead of two, have a short form for byte operands),
16636 ;; so do it for other CPUs as well. Given that the value was dead,
16637 ;; this should not create any new dependencies. Pass on the sub-word
16638 ;; versions if we're concerned about partial register stalls.
16641 [(set (match_operand 0 "flags_reg_operand" "")
16642 (match_operator 1 "compare_operator"
16643 [(and:SI (match_operand:SI 2 "register_operand" "")
16644 (match_operand:SI 3 "immediate_operand" ""))
16646 "ix86_match_ccmode (insn, CCNOmode)
16647 && (true_regnum (operands[2]) != AX_REG
16648 || satisfies_constraint_K (operands[3]))
16649 && peep2_reg_dead_p (1, operands[2])"
16651 [(set (match_dup 0)
16652 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16655 (and:SI (match_dup 2) (match_dup 3)))])])
16657 ;; We don't need to handle HImode case, because it will be promoted to SImode
16658 ;; on ! TARGET_PARTIAL_REG_STALL
16661 [(set (match_operand 0 "flags_reg_operand" "")
16662 (match_operator 1 "compare_operator"
16663 [(and:QI (match_operand:QI 2 "register_operand" "")
16664 (match_operand:QI 3 "immediate_operand" ""))
16666 "! TARGET_PARTIAL_REG_STALL
16667 && ix86_match_ccmode (insn, CCNOmode)
16668 && true_regnum (operands[2]) != AX_REG
16669 && peep2_reg_dead_p (1, operands[2])"
16671 [(set (match_dup 0)
16672 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16675 (and:QI (match_dup 2) (match_dup 3)))])])
16678 [(set (match_operand 0 "flags_reg_operand" "")
16679 (match_operator 1 "compare_operator"
16682 (match_operand 2 "ext_register_operand" "")
16685 (match_operand 3 "const_int_operand" ""))
16687 "! TARGET_PARTIAL_REG_STALL
16688 && ix86_match_ccmode (insn, CCNOmode)
16689 && true_regnum (operands[2]) != AX_REG
16690 && peep2_reg_dead_p (1, operands[2])"
16691 [(parallel [(set (match_dup 0)
16700 (set (zero_extract:SI (match_dup 2)
16708 (match_dup 3)))])])
16710 ;; Don't do logical operations with memory inputs.
16712 [(match_scratch:SI 2 "r")
16713 (parallel [(set (match_operand:SI 0 "register_operand" "")
16714 (match_operator:SI 3 "arith_or_logical_operator"
16716 (match_operand:SI 1 "memory_operand" "")]))
16717 (clobber (reg:CC FLAGS_REG))])]
16718 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16719 [(set (match_dup 2) (match_dup 1))
16720 (parallel [(set (match_dup 0)
16721 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16722 (clobber (reg:CC FLAGS_REG))])])
16725 [(match_scratch:SI 2 "r")
16726 (parallel [(set (match_operand:SI 0 "register_operand" "")
16727 (match_operator:SI 3 "arith_or_logical_operator"
16728 [(match_operand:SI 1 "memory_operand" "")
16730 (clobber (reg:CC FLAGS_REG))])]
16731 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16732 [(set (match_dup 2) (match_dup 1))
16733 (parallel [(set (match_dup 0)
16734 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16735 (clobber (reg:CC FLAGS_REG))])])
16737 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16738 ;; refers to the destination of the load!
16741 [(set (match_operand:SI 0 "register_operand" "")
16742 (match_operand:SI 1 "register_operand" ""))
16743 (parallel [(set (match_dup 0)
16744 (match_operator:SI 3 "commutative_operator"
16746 (match_operand:SI 2 "memory_operand" "")]))
16747 (clobber (reg:CC FLAGS_REG))])]
16748 "REGNO (operands[0]) != REGNO (operands[1])
16749 && GENERAL_REGNO_P (REGNO (operands[0]))
16750 && GENERAL_REGNO_P (REGNO (operands[1]))"
16751 [(set (match_dup 0) (match_dup 4))
16752 (parallel [(set (match_dup 0)
16753 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16754 (clobber (reg:CC FLAGS_REG))])]
16755 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16758 [(set (match_operand 0 "register_operand" "")
16759 (match_operand 1 "register_operand" ""))
16761 (match_operator 3 "commutative_operator"
16763 (match_operand 2 "memory_operand" "")]))]
16764 "REGNO (operands[0]) != REGNO (operands[1])
16765 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16766 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16767 [(set (match_dup 0) (match_dup 2))
16769 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16771 ; Don't do logical operations with memory outputs
16773 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16774 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16775 ; the same decoder scheduling characteristics as the original.
16778 [(match_scratch:SI 2 "r")
16779 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16780 (match_operator:SI 3 "arith_or_logical_operator"
16782 (match_operand:SI 1 "nonmemory_operand" "")]))
16783 (clobber (reg:CC FLAGS_REG))])]
16784 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16785 /* Do not split stack checking probes. */
16786 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16787 [(set (match_dup 2) (match_dup 0))
16788 (parallel [(set (match_dup 2)
16789 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16790 (clobber (reg:CC FLAGS_REG))])
16791 (set (match_dup 0) (match_dup 2))])
16794 [(match_scratch:SI 2 "r")
16795 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16796 (match_operator:SI 3 "arith_or_logical_operator"
16797 [(match_operand:SI 1 "nonmemory_operand" "")
16799 (clobber (reg:CC FLAGS_REG))])]
16800 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16801 /* Do not split stack checking probes. */
16802 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16803 [(set (match_dup 2) (match_dup 0))
16804 (parallel [(set (match_dup 2)
16805 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16806 (clobber (reg:CC FLAGS_REG))])
16807 (set (match_dup 0) (match_dup 2))])
16809 ;; Attempt to use arith or logical operations with memory outputs with
16810 ;; setting of flags.
16812 [(set (match_operand:SWI 0 "register_operand" "")
16813 (match_operand:SWI 1 "memory_operand" ""))
16814 (parallel [(set (match_dup 0)
16815 (match_operator:SWI 3 "plusminuslogic_operator"
16817 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16818 (clobber (reg:CC FLAGS_REG))])
16819 (set (match_dup 1) (match_dup 0))
16820 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16821 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16822 && peep2_reg_dead_p (4, operands[0])
16823 && !reg_overlap_mentioned_p (operands[0], operands[1])
16824 && ix86_match_ccmode (peep2_next_insn (3),
16825 (GET_CODE (operands[3]) == PLUS
16826 || GET_CODE (operands[3]) == MINUS)
16827 ? CCGOCmode : CCNOmode)"
16828 [(parallel [(set (match_dup 4) (match_dup 5))
16829 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16830 (match_dup 2)]))])]
16831 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16832 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16833 copy_rtx (operands[1]),
16834 copy_rtx (operands[2]));
16835 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16836 operands[5], const0_rtx);")
16839 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16840 (match_operator:SWI 2 "plusminuslogic_operator"
16842 (match_operand:SWI 1 "memory_operand" "")]))
16843 (clobber (reg:CC FLAGS_REG))])
16844 (set (match_dup 1) (match_dup 0))
16845 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16846 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16847 && GET_CODE (operands[2]) != MINUS
16848 && peep2_reg_dead_p (3, operands[0])
16849 && !reg_overlap_mentioned_p (operands[0], operands[1])
16850 && ix86_match_ccmode (peep2_next_insn (2),
16851 GET_CODE (operands[2]) == PLUS
16852 ? CCGOCmode : CCNOmode)"
16853 [(parallel [(set (match_dup 3) (match_dup 4))
16854 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16855 (match_dup 0)]))])]
16856 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16857 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16858 copy_rtx (operands[1]),
16859 copy_rtx (operands[0]));
16860 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16861 operands[4], const0_rtx);")
16864 [(set (match_operand:SWI12 0 "register_operand" "")
16865 (match_operand:SWI12 1 "memory_operand" ""))
16866 (parallel [(set (match_operand:SI 4 "register_operand" "")
16867 (match_operator:SI 3 "plusminuslogic_operator"
16869 (match_operand:SI 2 "nonmemory_operand" "")]))
16870 (clobber (reg:CC FLAGS_REG))])
16871 (set (match_dup 1) (match_dup 0))
16872 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16873 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16874 && REG_P (operands[0]) && REG_P (operands[4])
16875 && REGNO (operands[0]) == REGNO (operands[4])
16876 && peep2_reg_dead_p (4, operands[0])
16877 && !reg_overlap_mentioned_p (operands[0], operands[1])
16878 && ix86_match_ccmode (peep2_next_insn (3),
16879 (GET_CODE (operands[3]) == PLUS
16880 || GET_CODE (operands[3]) == MINUS)
16881 ? CCGOCmode : CCNOmode)"
16882 [(parallel [(set (match_dup 4) (match_dup 5))
16883 (set (match_dup 1) (match_dup 6))])]
16884 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16885 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16886 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16887 copy_rtx (operands[1]), operands[2]);
16888 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16889 operands[5], const0_rtx);
16890 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16891 copy_rtx (operands[1]),
16892 copy_rtx (operands[2]));")
16894 ;; Attempt to always use XOR for zeroing registers.
16896 [(set (match_operand 0 "register_operand" "")
16897 (match_operand 1 "const0_operand" ""))]
16898 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16899 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16900 && GENERAL_REG_P (operands[0])
16901 && peep2_regno_dead_p (0, FLAGS_REG)"
16902 [(parallel [(set (match_dup 0) (const_int 0))
16903 (clobber (reg:CC FLAGS_REG))])]
16904 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16907 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16909 "(GET_MODE (operands[0]) == QImode
16910 || GET_MODE (operands[0]) == HImode)
16911 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16912 && peep2_regno_dead_p (0, FLAGS_REG)"
16913 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16914 (clobber (reg:CC FLAGS_REG))])])
16916 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16918 [(set (match_operand:SWI248 0 "register_operand" "")
16920 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16921 && peep2_regno_dead_p (0, FLAGS_REG)"
16922 [(parallel [(set (match_dup 0) (const_int -1))
16923 (clobber (reg:CC FLAGS_REG))])]
16925 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16926 operands[0] = gen_lowpart (SImode, operands[0]);
16929 ;; Attempt to convert simple lea to add/shift.
16930 ;; These can be created by move expanders.
16933 [(set (match_operand:SWI48 0 "register_operand" "")
16934 (plus:SWI48 (match_dup 0)
16935 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16936 "peep2_regno_dead_p (0, FLAGS_REG)"
16937 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16938 (clobber (reg:CC FLAGS_REG))])])
16941 [(set (match_operand:SI 0 "register_operand" "")
16942 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16943 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16945 && peep2_regno_dead_p (0, FLAGS_REG)
16946 && REGNO (operands[0]) == REGNO (operands[1])"
16947 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16948 (clobber (reg:CC FLAGS_REG))])]
16949 "operands[2] = gen_lowpart (SImode, operands[2]);")
16952 [(set (match_operand:SWI48 0 "register_operand" "")
16953 (mult:SWI48 (match_dup 0)
16954 (match_operand:SWI48 1 "const_int_operand" "")))]
16955 "exact_log2 (INTVAL (operands[1])) >= 0
16956 && peep2_regno_dead_p (0, FLAGS_REG)"
16957 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16958 (clobber (reg:CC FLAGS_REG))])]
16959 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16962 [(set (match_operand:SI 0 "register_operand" "")
16963 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16964 (match_operand:DI 2 "const_int_operand" "")) 0))]
16966 && exact_log2 (INTVAL (operands[2])) >= 0
16967 && REGNO (operands[0]) == REGNO (operands[1])
16968 && peep2_regno_dead_p (0, FLAGS_REG)"
16969 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16970 (clobber (reg:CC FLAGS_REG))])]
16971 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16973 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16974 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16975 ;; On many CPUs it is also faster, since special hardware to avoid esp
16976 ;; dependencies is present.
16978 ;; While some of these conversions may be done using splitters, we use
16979 ;; peepholes in order to allow combine_stack_adjustments pass to see
16980 ;; nonobfuscated RTL.
16982 ;; Convert prologue esp subtractions to push.
16983 ;; We need register to push. In order to keep verify_flow_info happy we have
16985 ;; - use scratch and clobber it in order to avoid dependencies
16986 ;; - use already live register
16987 ;; We can't use the second way right now, since there is no reliable way how to
16988 ;; verify that given register is live. First choice will also most likely in
16989 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16990 ;; call clobbered registers are dead. We may want to use base pointer as an
16991 ;; alternative when no register is available later.
16994 [(match_scratch:P 1 "r")
16995 (parallel [(set (reg:P SP_REG)
16996 (plus:P (reg:P SP_REG)
16997 (match_operand:P 0 "const_int_operand" "")))
16998 (clobber (reg:CC FLAGS_REG))
16999 (clobber (mem:BLK (scratch)))])]
17000 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17001 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17002 [(clobber (match_dup 1))
17003 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17004 (clobber (mem:BLK (scratch)))])])
17007 [(match_scratch:P 1 "r")
17008 (parallel [(set (reg:P SP_REG)
17009 (plus:P (reg:P SP_REG)
17010 (match_operand:P 0 "const_int_operand" "")))
17011 (clobber (reg:CC FLAGS_REG))
17012 (clobber (mem:BLK (scratch)))])]
17013 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17014 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17015 [(clobber (match_dup 1))
17016 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17017 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17018 (clobber (mem:BLK (scratch)))])])
17020 ;; Convert esp subtractions to push.
17022 [(match_scratch:P 1 "r")
17023 (parallel [(set (reg:P SP_REG)
17024 (plus:P (reg:P SP_REG)
17025 (match_operand:P 0 "const_int_operand" "")))
17026 (clobber (reg:CC FLAGS_REG))])]
17027 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17028 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17029 [(clobber (match_dup 1))
17030 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17033 [(match_scratch:P 1 "r")
17034 (parallel [(set (reg:P SP_REG)
17035 (plus:P (reg:P SP_REG)
17036 (match_operand:P 0 "const_int_operand" "")))
17037 (clobber (reg:CC FLAGS_REG))])]
17038 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17039 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17040 [(clobber (match_dup 1))
17041 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17042 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17044 ;; Convert epilogue deallocator to pop.
17046 [(match_scratch:P 1 "r")
17047 (parallel [(set (reg:P SP_REG)
17048 (plus:P (reg:P SP_REG)
17049 (match_operand:P 0 "const_int_operand" "")))
17050 (clobber (reg:CC FLAGS_REG))
17051 (clobber (mem:BLK (scratch)))])]
17052 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17053 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17054 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17055 (clobber (mem:BLK (scratch)))])])
17057 ;; Two pops case is tricky, since pop causes dependency
17058 ;; on destination register. We use two registers if available.
17060 [(match_scratch:P 1 "r")
17061 (match_scratch:P 2 "r")
17062 (parallel [(set (reg:P SP_REG)
17063 (plus:P (reg:P SP_REG)
17064 (match_operand:P 0 "const_int_operand" "")))
17065 (clobber (reg:CC FLAGS_REG))
17066 (clobber (mem:BLK (scratch)))])]
17067 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17068 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17069 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17070 (clobber (mem:BLK (scratch)))])
17071 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
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 "optimize_insn_for_size_p ()
17081 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17082 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17083 (clobber (mem:BLK (scratch)))])
17084 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17086 ;; Convert esp additions to pop.
17088 [(match_scratch:P 1 "r")
17089 (parallel [(set (reg:P SP_REG)
17090 (plus:P (reg:P SP_REG)
17091 (match_operand:P 0 "const_int_operand" "")))
17092 (clobber (reg:CC FLAGS_REG))])]
17093 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17094 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17096 ;; Two pops case is tricky, since pop causes dependency
17097 ;; on destination register. We use two registers if available.
17099 [(match_scratch:P 1 "r")
17100 (match_scratch:P 2 "r")
17101 (parallel [(set (reg:P SP_REG)
17102 (plus:P (reg:P SP_REG)
17103 (match_operand:P 0 "const_int_operand" "")))
17104 (clobber (reg:CC FLAGS_REG))])]
17105 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17106 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17107 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17110 [(match_scratch:P 1 "r")
17111 (parallel [(set (reg:P SP_REG)
17112 (plus:P (reg:P SP_REG)
17113 (match_operand:P 0 "const_int_operand" "")))
17114 (clobber (reg:CC FLAGS_REG))])]
17115 "optimize_insn_for_size_p ()
17116 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17117 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17118 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17120 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17121 ;; required and register dies. Similarly for 128 to -128.
17123 [(set (match_operand 0 "flags_reg_operand" "")
17124 (match_operator 1 "compare_operator"
17125 [(match_operand 2 "register_operand" "")
17126 (match_operand 3 "const_int_operand" "")]))]
17127 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17128 && incdec_operand (operands[3], GET_MODE (operands[3])))
17129 || (!TARGET_FUSE_CMP_AND_BRANCH
17130 && INTVAL (operands[3]) == 128))
17131 && ix86_match_ccmode (insn, CCGCmode)
17132 && peep2_reg_dead_p (1, operands[2])"
17133 [(parallel [(set (match_dup 0)
17134 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17135 (clobber (match_dup 2))])])
17137 ;; Convert imul by three, five and nine into lea
17140 [(set (match_operand:SWI48 0 "register_operand" "")
17141 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17142 (match_operand:SWI48 2 "const359_operand" "")))
17143 (clobber (reg:CC FLAGS_REG))])]
17144 "!TARGET_PARTIAL_REG_STALL
17145 || <MODE>mode == SImode
17146 || optimize_function_for_size_p (cfun)"
17147 [(set (match_dup 0)
17148 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17150 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17154 [(set (match_operand:SWI48 0 "register_operand" "")
17155 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17156 (match_operand:SWI48 2 "const359_operand" "")))
17157 (clobber (reg:CC FLAGS_REG))])]
17158 "optimize_insn_for_speed_p ()
17159 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17160 [(set (match_dup 0) (match_dup 1))
17162 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17164 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17166 ;; imul $32bit_imm, mem, reg is vector decoded, while
17167 ;; imul $32bit_imm, reg, reg is direct decoded.
17169 [(match_scratch:SWI48 3 "r")
17170 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17171 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17172 (match_operand:SWI48 2 "immediate_operand" "")))
17173 (clobber (reg:CC FLAGS_REG))])]
17174 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17175 && !satisfies_constraint_K (operands[2])"
17176 [(set (match_dup 3) (match_dup 1))
17177 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17178 (clobber (reg:CC FLAGS_REG))])])
17181 [(match_scratch:SI 3 "r")
17182 (parallel [(set (match_operand:DI 0 "register_operand" "")
17184 (mult:SI (match_operand:SI 1 "memory_operand" "")
17185 (match_operand:SI 2 "immediate_operand" ""))))
17186 (clobber (reg:CC FLAGS_REG))])]
17188 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17189 && !satisfies_constraint_K (operands[2])"
17190 [(set (match_dup 3) (match_dup 1))
17191 (parallel [(set (match_dup 0)
17192 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17193 (clobber (reg:CC FLAGS_REG))])])
17195 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17196 ;; Convert it into imul reg, reg
17197 ;; It would be better to force assembler to encode instruction using long
17198 ;; immediate, but there is apparently no way to do so.
17200 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17202 (match_operand:SWI248 1 "nonimmediate_operand" "")
17203 (match_operand:SWI248 2 "const_int_operand" "")))
17204 (clobber (reg:CC FLAGS_REG))])
17205 (match_scratch:SWI248 3 "r")]
17206 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17207 && satisfies_constraint_K (operands[2])"
17208 [(set (match_dup 3) (match_dup 2))
17209 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17210 (clobber (reg:CC FLAGS_REG))])]
17212 if (!rtx_equal_p (operands[0], operands[1]))
17213 emit_move_insn (operands[0], operands[1]);
17216 ;; After splitting up read-modify operations, array accesses with memory
17217 ;; operands might end up in form:
17219 ;; movl 4(%esp), %edx
17221 ;; instead of pre-splitting:
17223 ;; addl 4(%esp), %eax
17225 ;; movl 4(%esp), %edx
17226 ;; leal (%edx,%eax,4), %eax
17229 [(match_scratch:P 5 "r")
17230 (parallel [(set (match_operand 0 "register_operand" "")
17231 (ashift (match_operand 1 "register_operand" "")
17232 (match_operand 2 "const_int_operand" "")))
17233 (clobber (reg:CC FLAGS_REG))])
17234 (parallel [(set (match_operand 3 "register_operand" "")
17235 (plus (match_dup 0)
17236 (match_operand 4 "x86_64_general_operand" "")))
17237 (clobber (reg:CC FLAGS_REG))])]
17238 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17239 /* Validate MODE for lea. */
17240 && ((!TARGET_PARTIAL_REG_STALL
17241 && (GET_MODE (operands[0]) == QImode
17242 || GET_MODE (operands[0]) == HImode))
17243 || GET_MODE (operands[0]) == SImode
17244 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17245 && (rtx_equal_p (operands[0], operands[3])
17246 || peep2_reg_dead_p (2, operands[0]))
17247 /* We reorder load and the shift. */
17248 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17249 [(set (match_dup 5) (match_dup 4))
17250 (set (match_dup 0) (match_dup 1))]
17252 enum machine_mode op1mode = GET_MODE (operands[1]);
17253 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17254 int scale = 1 << INTVAL (operands[2]);
17255 rtx index = gen_lowpart (Pmode, operands[1]);
17256 rtx base = gen_lowpart (Pmode, operands[5]);
17257 rtx dest = gen_lowpart (mode, operands[3]);
17259 operands[1] = gen_rtx_PLUS (Pmode, base,
17260 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17261 operands[5] = base;
17263 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17264 if (op1mode != Pmode)
17265 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17266 operands[0] = dest;
17269 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17270 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17271 ;; caught for use by garbage collectors and the like. Using an insn that
17272 ;; maps to SIGILL makes it more likely the program will rightfully die.
17273 ;; Keeping with tradition, "6" is in honor of #UD.
17274 (define_insn "trap"
17275 [(trap_if (const_int 1) (const_int 6))]
17277 { return ASM_SHORT "0x0b0f"; }
17278 [(set_attr "length" "2")])
17280 (define_expand "prefetch"
17281 [(prefetch (match_operand 0 "address_operand" "")
17282 (match_operand:SI 1 "const_int_operand" "")
17283 (match_operand:SI 2 "const_int_operand" ""))]
17284 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17286 int rw = INTVAL (operands[1]);
17287 int locality = INTVAL (operands[2]);
17289 gcc_assert (rw == 0 || rw == 1);
17290 gcc_assert (locality >= 0 && locality <= 3);
17291 gcc_assert (GET_MODE (operands[0]) == Pmode
17292 || GET_MODE (operands[0]) == VOIDmode);
17294 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17295 supported by SSE counterpart or the SSE prefetch is not available
17296 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17298 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17299 operands[2] = GEN_INT (3);
17301 operands[1] = const0_rtx;
17304 (define_insn "*prefetch_sse_<mode>"
17305 [(prefetch (match_operand:P 0 "address_operand" "p")
17307 (match_operand:SI 1 "const_int_operand" ""))]
17308 "TARGET_PREFETCH_SSE"
17310 static const char * const patterns[4] = {
17311 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17314 int locality = INTVAL (operands[1]);
17315 gcc_assert (locality >= 0 && locality <= 3);
17317 return patterns[locality];
17319 [(set_attr "type" "sse")
17320 (set_attr "atom_sse_attr" "prefetch")
17321 (set (attr "length_address")
17322 (symbol_ref "memory_address_length (operands[0])"))
17323 (set_attr "memory" "none")])
17325 (define_insn "*prefetch_3dnow_<mode>"
17326 [(prefetch (match_operand:P 0 "address_operand" "p")
17327 (match_operand:SI 1 "const_int_operand" "n")
17331 if (INTVAL (operands[1]) == 0)
17332 return "prefetch\t%a0";
17334 return "prefetchw\t%a0";
17336 [(set_attr "type" "mmx")
17337 (set (attr "length_address")
17338 (symbol_ref "memory_address_length (operands[0])"))
17339 (set_attr "memory" "none")])
17341 (define_expand "stack_protect_set"
17342 [(match_operand 0 "memory_operand" "")
17343 (match_operand 1 "memory_operand" "")]
17346 rtx (*insn)(rtx, rtx);
17348 #ifdef TARGET_THREAD_SSP_OFFSET
17349 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17350 insn = (TARGET_64BIT
17351 ? gen_stack_tls_protect_set_di
17352 : gen_stack_tls_protect_set_si);
17354 insn = (TARGET_64BIT
17355 ? gen_stack_protect_set_di
17356 : gen_stack_protect_set_si);
17359 emit_insn (insn (operands[0], operands[1]));
17363 (define_insn "stack_protect_set_<mode>"
17364 [(set (match_operand:P 0 "memory_operand" "=m")
17365 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17366 (set (match_scratch:P 2 "=&r") (const_int 0))
17367 (clobber (reg:CC FLAGS_REG))]
17369 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17370 [(set_attr "type" "multi")])
17372 (define_insn "stack_tls_protect_set_<mode>"
17373 [(set (match_operand:P 0 "memory_operand" "=m")
17374 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17375 UNSPEC_SP_TLS_SET))
17376 (set (match_scratch:P 2 "=&r") (const_int 0))
17377 (clobber (reg:CC FLAGS_REG))]
17379 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17380 [(set_attr "type" "multi")])
17382 (define_expand "stack_protect_test"
17383 [(match_operand 0 "memory_operand" "")
17384 (match_operand 1 "memory_operand" "")
17385 (match_operand 2 "" "")]
17388 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17390 rtx (*insn)(rtx, rtx, rtx);
17392 #ifdef TARGET_THREAD_SSP_OFFSET
17393 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17394 insn = (TARGET_64BIT
17395 ? gen_stack_tls_protect_test_di
17396 : gen_stack_tls_protect_test_si);
17398 insn = (TARGET_64BIT
17399 ? gen_stack_protect_test_di
17400 : gen_stack_protect_test_si);
17403 emit_insn (insn (flags, operands[0], operands[1]));
17405 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17406 flags, const0_rtx, operands[2]));
17410 (define_insn "stack_protect_test_<mode>"
17411 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17412 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17413 (match_operand:P 2 "memory_operand" "m")]
17415 (clobber (match_scratch:P 3 "=&r"))]
17417 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17418 [(set_attr "type" "multi")])
17420 (define_insn "stack_tls_protect_test_<mode>"
17421 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17422 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17423 (match_operand:P 2 "const_int_operand" "i")]
17424 UNSPEC_SP_TLS_TEST))
17425 (clobber (match_scratch:P 3 "=r"))]
17427 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17428 [(set_attr "type" "multi")])
17430 (define_insn "sse4_2_crc32<mode>"
17431 [(set (match_operand:SI 0 "register_operand" "=r")
17433 [(match_operand:SI 1 "register_operand" "0")
17434 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17436 "TARGET_SSE4_2 || TARGET_CRC32"
17437 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17438 [(set_attr "type" "sselog1")
17439 (set_attr "prefix_rep" "1")
17440 (set_attr "prefix_extra" "1")
17441 (set (attr "prefix_data16")
17442 (if_then_else (match_operand:HI 2 "" "")
17444 (const_string "*")))
17445 (set (attr "prefix_rex")
17446 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17448 (const_string "*")))
17449 (set_attr "mode" "SI")])
17451 (define_insn "sse4_2_crc32di"
17452 [(set (match_operand:DI 0 "register_operand" "=r")
17454 [(match_operand:DI 1 "register_operand" "0")
17455 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17457 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17458 "crc32{q}\t{%2, %0|%0, %2}"
17459 [(set_attr "type" "sselog1")
17460 (set_attr "prefix_rep" "1")
17461 (set_attr "prefix_extra" "1")
17462 (set_attr "mode" "DI")])
17464 (define_expand "rdpmc"
17465 [(match_operand:DI 0 "register_operand" "")
17466 (match_operand:SI 1 "register_operand" "")]
17469 rtx reg = gen_reg_rtx (DImode);
17472 /* Force operand 1 into ECX. */
17473 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17474 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17475 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17480 rtvec vec = rtvec_alloc (2);
17481 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17482 rtx upper = gen_reg_rtx (DImode);
17483 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17484 gen_rtvec (1, const0_rtx),
17486 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17487 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17489 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17490 NULL, 1, OPTAB_DIRECT);
17491 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17495 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17496 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17500 (define_insn "*rdpmc"
17501 [(set (match_operand:DI 0 "register_operand" "=A")
17502 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17506 [(set_attr "type" "other")
17507 (set_attr "length" "2")])
17509 (define_insn "*rdpmc_rex64"
17510 [(set (match_operand:DI 0 "register_operand" "=a")
17511 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17513 (set (match_operand:DI 1 "register_operand" "=d")
17514 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17517 [(set_attr "type" "other")
17518 (set_attr "length" "2")])
17520 (define_expand "rdtsc"
17521 [(set (match_operand:DI 0 "register_operand" "")
17522 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17527 rtvec vec = rtvec_alloc (2);
17528 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17529 rtx upper = gen_reg_rtx (DImode);
17530 rtx lower = gen_reg_rtx (DImode);
17531 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17532 gen_rtvec (1, const0_rtx),
17534 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17535 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17537 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17538 NULL, 1, OPTAB_DIRECT);
17539 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17541 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17546 (define_insn "*rdtsc"
17547 [(set (match_operand:DI 0 "register_operand" "=A")
17548 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17551 [(set_attr "type" "other")
17552 (set_attr "length" "2")])
17554 (define_insn "*rdtsc_rex64"
17555 [(set (match_operand:DI 0 "register_operand" "=a")
17556 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17557 (set (match_operand:DI 1 "register_operand" "=d")
17558 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17561 [(set_attr "type" "other")
17562 (set_attr "length" "2")])
17564 (define_expand "rdtscp"
17565 [(match_operand:DI 0 "register_operand" "")
17566 (match_operand:SI 1 "memory_operand" "")]
17569 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17570 gen_rtvec (1, const0_rtx),
17572 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17573 gen_rtvec (1, const0_rtx),
17575 rtx reg = gen_reg_rtx (DImode);
17576 rtx tmp = gen_reg_rtx (SImode);
17580 rtvec vec = rtvec_alloc (3);
17581 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17582 rtx upper = gen_reg_rtx (DImode);
17583 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17584 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17585 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17587 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17588 NULL, 1, OPTAB_DIRECT);
17589 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17594 rtvec vec = rtvec_alloc (2);
17595 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17596 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17597 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17600 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17601 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17605 (define_insn "*rdtscp"
17606 [(set (match_operand:DI 0 "register_operand" "=A")
17607 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17608 (set (match_operand:SI 1 "register_operand" "=c")
17609 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17612 [(set_attr "type" "other")
17613 (set_attr "length" "3")])
17615 (define_insn "*rdtscp_rex64"
17616 [(set (match_operand:DI 0 "register_operand" "=a")
17617 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17618 (set (match_operand:DI 1 "register_operand" "=d")
17619 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17620 (set (match_operand:SI 2 "register_operand" "=c")
17621 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17624 [(set_attr "type" "other")
17625 (set_attr "length" "3")])
17627 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17629 ;; LWP instructions
17631 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17633 (define_expand "lwp_llwpcb"
17634 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17635 UNSPECV_LLWP_INTRINSIC)]
17638 (define_insn "*lwp_llwpcb<mode>1"
17639 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17640 UNSPECV_LLWP_INTRINSIC)]
17643 [(set_attr "type" "lwp")
17644 (set_attr "mode" "<MODE>")
17645 (set_attr "length" "5")])
17647 (define_expand "lwp_slwpcb"
17648 [(set (match_operand 0 "register_operand" "=r")
17649 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17654 insn = (TARGET_64BIT
17656 : gen_lwp_slwpcbsi);
17658 emit_insn (insn (operands[0]));
17662 (define_insn "lwp_slwpcb<mode>"
17663 [(set (match_operand:P 0 "register_operand" "=r")
17664 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17667 [(set_attr "type" "lwp")
17668 (set_attr "mode" "<MODE>")
17669 (set_attr "length" "5")])
17671 (define_expand "lwp_lwpval<mode>3"
17672 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17673 (match_operand:SI 2 "nonimmediate_operand" "rm")
17674 (match_operand:SI 3 "const_int_operand" "i")]
17675 UNSPECV_LWPVAL_INTRINSIC)]
17677 "/* Avoid unused variable warning. */
17680 (define_insn "*lwp_lwpval<mode>3_1"
17681 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17682 (match_operand:SI 1 "nonimmediate_operand" "rm")
17683 (match_operand:SI 2 "const_int_operand" "i")]
17684 UNSPECV_LWPVAL_INTRINSIC)]
17686 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17687 [(set_attr "type" "lwp")
17688 (set_attr "mode" "<MODE>")
17689 (set (attr "length")
17690 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17692 (define_expand "lwp_lwpins<mode>3"
17693 [(set (reg:CCC FLAGS_REG)
17694 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17695 (match_operand:SI 2 "nonimmediate_operand" "rm")
17696 (match_operand:SI 3 "const_int_operand" "i")]
17697 UNSPECV_LWPINS_INTRINSIC))
17698 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17699 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17702 (define_insn "*lwp_lwpins<mode>3_1"
17703 [(set (reg:CCC FLAGS_REG)
17704 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17705 (match_operand:SI 1 "nonimmediate_operand" "rm")
17706 (match_operand:SI 2 "const_int_operand" "i")]
17707 UNSPECV_LWPINS_INTRINSIC))]
17709 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17710 [(set_attr "type" "lwp")
17711 (set_attr "mode" "<MODE>")
17712 (set (attr "length")
17713 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17715 (define_insn "rdfsbase<mode>"
17716 [(set (match_operand:SWI48 0 "register_operand" "=r")
17717 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17718 "TARGET_64BIT && TARGET_FSGSBASE"
17720 [(set_attr "type" "other")
17721 (set_attr "prefix_extra" "2")])
17723 (define_insn "rdgsbase<mode>"
17724 [(set (match_operand:SWI48 0 "register_operand" "=r")
17725 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17726 "TARGET_64BIT && TARGET_FSGSBASE"
17728 [(set_attr "type" "other")
17729 (set_attr "prefix_extra" "2")])
17731 (define_insn "wrfsbase<mode>"
17732 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17734 "TARGET_64BIT && TARGET_FSGSBASE"
17736 [(set_attr "type" "other")
17737 (set_attr "prefix_extra" "2")])
17739 (define_insn "wrgsbase<mode>"
17740 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17742 "TARGET_64BIT && TARGET_FSGSBASE"
17744 [(set_attr "type" "other")
17745 (set_attr "prefix_extra" "2")])
17747 (define_insn "rdrand<mode>_1"
17748 [(set (match_operand:SWI248 0 "register_operand" "=r")
17749 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17750 (set (reg:CCC FLAGS_REG)
17751 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17754 [(set_attr "type" "other")
17755 (set_attr "prefix_extra" "1")])
17757 (define_expand "pause"
17758 [(set (match_dup 0)
17759 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17762 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17763 MEM_VOLATILE_P (operands[0]) = 1;
17766 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17767 ;; They have the same encoding.
17768 (define_insn "*pause"
17769 [(set (match_operand:BLK 0 "" "")
17770 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17773 [(set_attr "length" "2")
17774 (set_attr "memory" "unknown")])
17778 (include "sync.md")