1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
99 ;; Other random patterns
108 UNSPEC_LD_MPIC ; load_macho_picbase
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_CALL_NEEDS_VZEROUPPER
114 ;; For SSE/MMX support:
132 UNSPEC_MS_TO_SYSV_CALL
134 ;; Generic math support
136 UNSPEC_IEEE_MIN ; not commutative
137 UNSPEC_IEEE_MAX ; not commutative
139 ;; x87 Floating point
155 UNSPEC_FRNDINT_MASK_PM
159 ;; x87 Double output FP
191 ;; For SSE4.1 support
201 ;; For SSE4.2 support
208 UNSPEC_XOP_UNSIGNED_CMP
219 UNSPEC_AESKEYGENASSIST
221 ;; For PCLMUL support
237 ;; For RDRAND support
241 (define_c_enum "unspecv" [
244 UNSPECV_PROBE_STACK_RANGE
264 UNSPECV_LLWP_INTRINSIC
265 UNSPECV_SLWP_INTRINSIC
266 UNSPECV_LWPVAL_INTRINSIC
267 UNSPECV_LWPINS_INTRINSIC
272 UNSPECV_SPLIT_STACK_RETURN
275 ;; Constants to represent rounding modes in the ROUND instruction
284 ;; Constants to represent pcomtrue/pcomfalse variants
294 ;; Constants used in the XOP pperm instruction
296 [(PPERM_SRC 0x00) /* copy source */
297 (PPERM_INVERT 0x20) /* invert source */
298 (PPERM_REVERSE 0x40) /* bit reverse source */
299 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
300 (PPERM_ZERO 0x80) /* all 0's */
301 (PPERM_ONES 0xa0) /* all 1's */
302 (PPERM_SIGN 0xc0) /* propagate sign bit */
303 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
304 (PPERM_SRC1 0x00) /* use first source byte */
305 (PPERM_SRC2 0x10) /* use second source byte */
308 ;; Registers by name.
361 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
364 ;; In C guard expressions, put expressions which may be compile-time
365 ;; constants first. This allows for better optimization. For
366 ;; example, write "TARGET_64BIT && reload_completed", not
367 ;; "reload_completed && TARGET_64BIT".
371 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
372 atom,generic64,amdfam10,bdver1,btver1"
373 (const (symbol_ref "ix86_schedule")))
375 ;; A basic instruction type. Refinements due to arguments to be
376 ;; provided in other attributes.
379 alu,alu1,negnot,imov,imovx,lea,
380 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
381 icmp,test,ibr,setcc,icmov,
382 push,pop,call,callv,leave,
384 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
385 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
387 ssemuladd,sse4arg,lwp,
388 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
389 (const_string "other"))
391 ;; Main data type used by the insn
393 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
394 (const_string "unknown"))
396 ;; The CPU unit operations uses.
397 (define_attr "unit" "integer,i387,sse,mmx,unknown"
398 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
399 (const_string "i387")
400 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
401 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
402 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
404 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
406 (eq_attr "type" "other")
407 (const_string "unknown")]
408 (const_string "integer")))
410 ;; The (bounding maximum) length of an instruction immediate.
411 (define_attr "length_immediate" ""
412 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
415 (eq_attr "unit" "i387,sse,mmx")
417 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
419 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
420 (eq_attr "type" "imov,test")
421 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
422 (eq_attr "type" "call")
423 (if_then_else (match_operand 0 "constant_call_address_operand" "")
426 (eq_attr "type" "callv")
427 (if_then_else (match_operand 1 "constant_call_address_operand" "")
430 ;; We don't know the size before shorten_branches. Expect
431 ;; the instruction to fit for better scheduling.
432 (eq_attr "type" "ibr")
435 (symbol_ref "/* Update immediate_length and other attributes! */
436 gcc_unreachable (),1")))
438 ;; The (bounding maximum) length of an instruction address.
439 (define_attr "length_address" ""
440 (cond [(eq_attr "type" "str,other,multi,fxch")
442 (and (eq_attr "type" "call")
443 (match_operand 0 "constant_call_address_operand" ""))
445 (and (eq_attr "type" "callv")
446 (match_operand 1 "constant_call_address_operand" ""))
449 (symbol_ref "ix86_attr_length_address_default (insn)")))
451 ;; Set when length prefix is used.
452 (define_attr "prefix_data16" ""
453 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
455 (eq_attr "mode" "HI")
457 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
462 ;; Set when string REP prefix is used.
463 (define_attr "prefix_rep" ""
464 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
466 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
471 ;; Set when 0f opcode prefix is used.
472 (define_attr "prefix_0f" ""
474 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
475 (eq_attr "unit" "sse,mmx"))
479 ;; Set when REX opcode prefix is used.
480 (define_attr "prefix_rex" ""
481 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
483 (and (eq_attr "mode" "DI")
484 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
485 (eq_attr "unit" "!mmx")))
487 (and (eq_attr "mode" "QI")
488 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
491 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
494 (and (eq_attr "type" "imovx")
495 (match_operand:QI 1 "ext_QIreg_operand" ""))
500 ;; There are also additional prefixes in 3DNOW, SSSE3.
501 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
502 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
503 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
504 (define_attr "prefix_extra" ""
505 (cond [(eq_attr "type" "ssemuladd,sse4arg")
507 (eq_attr "type" "sseiadd1,ssecvt1")
512 ;; Prefix used: original, VEX or maybe VEX.
513 (define_attr "prefix" "orig,vex,maybe_vex"
514 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
516 (const_string "orig")))
518 ;; VEX W bit is used.
519 (define_attr "prefix_vex_w" "" (const_int 0))
521 ;; The length of VEX prefix
522 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
523 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
524 ;; still prefix_0f 1, with prefix_extra 1.
525 (define_attr "length_vex" ""
526 (if_then_else (and (eq_attr "prefix_0f" "1")
527 (eq_attr "prefix_extra" "0"))
528 (if_then_else (eq_attr "prefix_vex_w" "1")
529 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
530 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
531 (if_then_else (eq_attr "prefix_vex_w" "1")
532 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
533 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
535 ;; Set when modrm byte is used.
536 (define_attr "modrm" ""
537 (cond [(eq_attr "type" "str,leave")
539 (eq_attr "unit" "i387")
541 (and (eq_attr "type" "incdec")
542 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
543 (ior (match_operand:SI 1 "register_operand" "")
544 (match_operand:HI 1 "register_operand" ""))))
546 (and (eq_attr "type" "push")
547 (not (match_operand 1 "memory_operand" "")))
549 (and (eq_attr "type" "pop")
550 (not (match_operand 0 "memory_operand" "")))
552 (and (eq_attr "type" "imov")
553 (and (not (eq_attr "mode" "DI"))
554 (ior (and (match_operand 0 "register_operand" "")
555 (match_operand 1 "immediate_operand" ""))
556 (ior (and (match_operand 0 "ax_reg_operand" "")
557 (match_operand 1 "memory_displacement_only_operand" ""))
558 (and (match_operand 0 "memory_displacement_only_operand" "")
559 (match_operand 1 "ax_reg_operand" ""))))))
561 (and (eq_attr "type" "call")
562 (match_operand 0 "constant_call_address_operand" ""))
564 (and (eq_attr "type" "callv")
565 (match_operand 1 "constant_call_address_operand" ""))
567 (and (eq_attr "type" "alu,alu1,icmp,test")
568 (match_operand 0 "ax_reg_operand" ""))
569 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
573 ;; The (bounding maximum) length of an instruction in bytes.
574 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
575 ;; Later we may want to split them and compute proper length as for
577 (define_attr "length" ""
578 (cond [(eq_attr "type" "other,multi,fistp,frndint")
580 (eq_attr "type" "fcmp")
582 (eq_attr "unit" "i387")
584 (plus (attr "prefix_data16")
585 (attr "length_address")))
586 (ior (eq_attr "prefix" "vex")
587 (and (eq_attr "prefix" "maybe_vex")
588 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
589 (plus (attr "length_vex")
590 (plus (attr "length_immediate")
592 (attr "length_address"))))]
593 (plus (plus (attr "modrm")
594 (plus (attr "prefix_0f")
595 (plus (attr "prefix_rex")
596 (plus (attr "prefix_extra")
598 (plus (attr "prefix_rep")
599 (plus (attr "prefix_data16")
600 (plus (attr "length_immediate")
601 (attr "length_address")))))))
603 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
604 ;; `store' if there is a simple memory reference therein, or `unknown'
605 ;; if the instruction is complex.
607 (define_attr "memory" "none,load,store,both,unknown"
608 (cond [(eq_attr "type" "other,multi,str,lwp")
609 (const_string "unknown")
610 (eq_attr "type" "lea,fcmov,fpspc")
611 (const_string "none")
612 (eq_attr "type" "fistp,leave")
613 (const_string "both")
614 (eq_attr "type" "frndint")
615 (const_string "load")
616 (eq_attr "type" "push")
617 (if_then_else (match_operand 1 "memory_operand" "")
618 (const_string "both")
619 (const_string "store"))
620 (eq_attr "type" "pop")
621 (if_then_else (match_operand 0 "memory_operand" "")
622 (const_string "both")
623 (const_string "load"))
624 (eq_attr "type" "setcc")
625 (if_then_else (match_operand 0 "memory_operand" "")
626 (const_string "store")
627 (const_string "none"))
628 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
629 (if_then_else (ior (match_operand 0 "memory_operand" "")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "load")
632 (const_string "none"))
633 (eq_attr "type" "ibr")
634 (if_then_else (match_operand 0 "memory_operand" "")
635 (const_string "load")
636 (const_string "none"))
637 (eq_attr "type" "call")
638 (if_then_else (match_operand 0 "constant_call_address_operand" "")
639 (const_string "none")
640 (const_string "load"))
641 (eq_attr "type" "callv")
642 (if_then_else (match_operand 1 "constant_call_address_operand" "")
643 (const_string "none")
644 (const_string "load"))
645 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
646 (match_operand 1 "memory_operand" ""))
647 (const_string "both")
648 (and (match_operand 0 "memory_operand" "")
649 (match_operand 1 "memory_operand" ""))
650 (const_string "both")
651 (match_operand 0 "memory_operand" "")
652 (const_string "store")
653 (match_operand 1 "memory_operand" "")
654 (const_string "load")
656 "!alu1,negnot,ishift1,
657 imov,imovx,icmp,test,bitmanip,
659 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
660 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
661 (match_operand 2 "memory_operand" ""))
662 (const_string "load")
663 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
664 (match_operand 3 "memory_operand" ""))
665 (const_string "load")
667 (const_string "none")))
669 ;; Indicates if an instruction has both an immediate and a displacement.
671 (define_attr "imm_disp" "false,true,unknown"
672 (cond [(eq_attr "type" "other,multi")
673 (const_string "unknown")
674 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
675 (and (match_operand 0 "memory_displacement_operand" "")
676 (match_operand 1 "immediate_operand" "")))
677 (const_string "true")
678 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
679 (and (match_operand 0 "memory_displacement_operand" "")
680 (match_operand 2 "immediate_operand" "")))
681 (const_string "true")
683 (const_string "false")))
685 ;; Indicates if an FP operation has an integer source.
687 (define_attr "fp_int_src" "false,true"
688 (const_string "false"))
690 ;; Defines rounding mode of an FP operation.
692 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
693 (const_string "any"))
695 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
696 (define_attr "use_carry" "0,1" (const_string "0"))
698 ;; Define attribute to indicate unaligned ssemov insns
699 (define_attr "movu" "0,1" (const_string "0"))
701 ;; Used to control the "enabled" attribute on a per-instruction basis.
702 (define_attr "isa" "base,noavx,avx"
703 (const_string "base"))
705 (define_attr "enabled" ""
706 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
707 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
711 ;; Describe a user's asm statement.
712 (define_asm_attributes
713 [(set_attr "length" "128")
714 (set_attr "type" "multi")])
716 (define_code_iterator plusminus [plus minus])
718 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
720 ;; Base name for define_insn
721 (define_code_attr plusminus_insn
722 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
723 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
725 ;; Base name for insn mnemonic.
726 (define_code_attr plusminus_mnemonic
727 [(plus "add") (ss_plus "adds") (us_plus "addus")
728 (minus "sub") (ss_minus "subs") (us_minus "subus")])
729 (define_code_attr plusminus_carry_mnemonic
730 [(plus "adc") (minus "sbb")])
732 ;; Mark commutative operators as such in constraints.
733 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
734 (minus "") (ss_minus "") (us_minus "")])
736 ;; Mapping of signed max and min
737 (define_code_iterator smaxmin [smax smin])
739 ;; Mapping of unsigned max and min
740 (define_code_iterator umaxmin [umax umin])
742 ;; Base name for integer and FP insn mnemonic
743 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
744 (umax "maxu") (umin "minu")])
745 (define_code_attr maxmin_float [(smax "max") (smin "min")])
747 ;; Mapping of logic operators
748 (define_code_iterator any_logic [and ior xor])
749 (define_code_iterator any_or [ior xor])
751 ;; Base name for insn mnemonic.
752 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
754 ;; Mapping of shift-right operators
755 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
757 ;; Base name for define_insn
758 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
760 ;; Base name for insn mnemonic.
761 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
763 ;; Mapping of rotate operators
764 (define_code_iterator any_rotate [rotate rotatert])
766 ;; Base name for define_insn
767 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
769 ;; Base name for insn mnemonic.
770 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
772 ;; Mapping of abs neg operators
773 (define_code_iterator absneg [abs neg])
775 ;; Base name for x87 insn mnemonic.
776 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
778 ;; Used in signed and unsigned widening multiplications.
779 (define_code_iterator any_extend [sign_extend zero_extend])
781 ;; Various insn prefixes for signed and unsigned operations.
782 (define_code_attr u [(sign_extend "") (zero_extend "u")
783 (div "") (udiv "u")])
784 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
786 ;; Used in signed and unsigned divisions.
787 (define_code_iterator any_div [div udiv])
789 ;; Instruction prefix for signed and unsigned operations.
790 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
791 (div "i") (udiv "")])
793 ;; All integer modes.
794 (define_mode_iterator SWI1248x [QI HI SI DI])
796 ;; All integer modes without QImode.
797 (define_mode_iterator SWI248x [HI SI DI])
799 ;; All integer modes without QImode and HImode.
800 (define_mode_iterator SWI48x [SI DI])
802 ;; All integer modes without SImode and DImode.
803 (define_mode_iterator SWI12 [QI HI])
805 ;; All integer modes without DImode.
806 (define_mode_iterator SWI124 [QI HI SI])
808 ;; All integer modes without QImode and DImode.
809 (define_mode_iterator SWI24 [HI SI])
811 ;; Single word integer modes.
812 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
814 ;; Single word integer modes without QImode.
815 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
817 ;; Single word integer modes without QImode and HImode.
818 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
820 ;; All math-dependant single and double word integer modes.
821 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
822 (HI "TARGET_HIMODE_MATH")
823 SI DI (TI "TARGET_64BIT")])
825 ;; Math-dependant single word integer modes.
826 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
827 (HI "TARGET_HIMODE_MATH")
828 SI (DI "TARGET_64BIT")])
830 ;; Math-dependant integer modes without DImode.
831 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
832 (HI "TARGET_HIMODE_MATH")
835 ;; Math-dependant single word integer modes without QImode.
836 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
837 SI (DI "TARGET_64BIT")])
839 ;; Double word integer modes.
840 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
841 (TI "TARGET_64BIT")])
843 ;; Double word integer modes as mode attribute.
844 (define_mode_attr DWI [(SI "DI") (DI "TI")])
845 (define_mode_attr dwi [(SI "di") (DI "ti")])
847 ;; Half mode for double word integer modes.
848 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
849 (DI "TARGET_64BIT")])
851 ;; Instruction suffix for integer modes.
852 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
854 ;; Pointer size prefix for integer modes (Intel asm dialect)
855 (define_mode_attr iptrsize [(QI "BYTE")
860 ;; Register class for integer modes.
861 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
863 ;; Immediate operand constraint for integer modes.
864 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "iF") (DI "e")])
872 ;; Immediate operand constraint for shifts.
873 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
875 ;; General operand predicate for integer modes.
876 (define_mode_attr general_operand
877 [(QI "general_operand")
878 (HI "general_operand")
879 (SI "general_operand")
880 (DI "x86_64_general_operand")
881 (TI "x86_64_general_operand")])
883 ;; General sign/zero extend operand predicate for integer modes.
884 (define_mode_attr general_szext_operand
885 [(QI "general_operand")
886 (HI "general_operand")
887 (SI "general_operand")
888 (DI "x86_64_szext_general_operand")])
890 ;; Immediate operand predicate for integer modes.
891 (define_mode_attr immediate_operand
892 [(QI "immediate_operand")
893 (HI "immediate_operand")
894 (SI "immediate_operand")
895 (DI "x86_64_immediate_operand")])
897 ;; Nonmemory operand predicate for integer modes.
898 (define_mode_attr nonmemory_operand
899 [(QI "nonmemory_operand")
900 (HI "nonmemory_operand")
901 (SI "nonmemory_operand")
902 (DI "x86_64_nonmemory_operand")])
904 ;; Operand predicate for shifts.
905 (define_mode_attr shift_operand
906 [(QI "nonimmediate_operand")
907 (HI "nonimmediate_operand")
908 (SI "nonimmediate_operand")
909 (DI "shiftdi_operand")
910 (TI "register_operand")])
912 ;; Operand predicate for shift argument.
913 (define_mode_attr shift_immediate_operand
914 [(QI "const_1_to_31_operand")
915 (HI "const_1_to_31_operand")
916 (SI "const_1_to_31_operand")
917 (DI "const_1_to_63_operand")])
919 ;; Input operand predicate for arithmetic left shifts.
920 (define_mode_attr ashl_input_operand
921 [(QI "nonimmediate_operand")
922 (HI "nonimmediate_operand")
923 (SI "nonimmediate_operand")
924 (DI "ashldi_input_operand")
925 (TI "reg_or_pm1_operand")])
927 ;; SSE and x87 SFmode and DFmode floating point modes
928 (define_mode_iterator MODEF [SF DF])
930 ;; All x87 floating point modes
931 (define_mode_iterator X87MODEF [SF DF XF])
933 ;; SSE instruction suffix for various modes
934 (define_mode_attr ssemodesuffix
936 (V8SF "ps") (V4DF "pd")
937 (V4SF "ps") (V2DF "pd")
938 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
941 ;; SSE vector suffix for floating point modes
942 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
944 ;; SSE vector mode corresponding to a scalar mode
945 (define_mode_attr ssevecmode
946 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
948 ;; Instruction suffix for REX 64bit operators.
949 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
951 ;; This mode iterator allows :P to be used for patterns that operate on
952 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
953 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
955 ;; Scheduling descriptions
957 (include "pentium.md")
960 (include "athlon.md")
961 (include "bdver1.md")
967 ;; Operand and operator predicates and constraints
969 (include "predicates.md")
970 (include "constraints.md")
973 ;; Compare and branch/compare and store instructions.
975 (define_expand "cbranch<mode>4"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
978 (match_operand:SDWIM 2 "<general_operand>" "")))
979 (set (pc) (if_then_else
980 (match_operator 0 "ordered_comparison_operator"
981 [(reg:CC FLAGS_REG) (const_int 0)])
982 (label_ref (match_operand 3 "" ""))
986 if (MEM_P (operands[1]) && MEM_P (operands[2]))
987 operands[1] = force_reg (<MODE>mode, operands[1]);
988 ix86_expand_branch (GET_CODE (operands[0]),
989 operands[1], operands[2], operands[3]);
993 (define_expand "cstore<mode>4"
994 [(set (reg:CC FLAGS_REG)
995 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
996 (match_operand:SWIM 3 "<general_operand>" "")))
997 (set (match_operand:QI 0 "register_operand" "")
998 (match_operator 1 "ordered_comparison_operator"
999 [(reg:CC FLAGS_REG) (const_int 0)]))]
1002 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1003 operands[2] = force_reg (<MODE>mode, operands[2]);
1004 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1005 operands[2], operands[3]);
1009 (define_expand "cmp<mode>_1"
1010 [(set (reg:CC FLAGS_REG)
1011 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1012 (match_operand:SWI48 1 "<general_operand>" "")))])
1014 (define_insn "*cmp<mode>_ccno_1"
1015 [(set (reg FLAGS_REG)
1016 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1017 (match_operand:SWI 1 "const0_operand" "")))]
1018 "ix86_match_ccmode (insn, CCNOmode)"
1020 test{<imodesuffix>}\t%0, %0
1021 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1022 [(set_attr "type" "test,icmp")
1023 (set_attr "length_immediate" "0,1")
1024 (set_attr "mode" "<MODE>")])
1026 (define_insn "*cmp<mode>_1"
1027 [(set (reg FLAGS_REG)
1028 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1029 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1030 "ix86_match_ccmode (insn, CCmode)"
1031 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1032 [(set_attr "type" "icmp")
1033 (set_attr "mode" "<MODE>")])
1035 (define_insn "*cmp<mode>_minus_1"
1036 [(set (reg FLAGS_REG)
1038 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1039 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1041 "ix86_match_ccmode (insn, CCGOCmode)"
1042 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1043 [(set_attr "type" "icmp")
1044 (set_attr "mode" "<MODE>")])
1046 (define_insn "*cmpqi_ext_1"
1047 [(set (reg FLAGS_REG)
1049 (match_operand:QI 0 "general_operand" "Qm")
1052 (match_operand 1 "ext_register_operand" "Q")
1054 (const_int 8)) 0)))]
1055 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056 "cmp{b}\t{%h1, %0|%0, %h1}"
1057 [(set_attr "type" "icmp")
1058 (set_attr "mode" "QI")])
1060 (define_insn "*cmpqi_ext_1_rex64"
1061 [(set (reg FLAGS_REG)
1063 (match_operand:QI 0 "register_operand" "Q")
1066 (match_operand 1 "ext_register_operand" "Q")
1068 (const_int 8)) 0)))]
1069 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1070 "cmp{b}\t{%h1, %0|%0, %h1}"
1071 [(set_attr "type" "icmp")
1072 (set_attr "mode" "QI")])
1074 (define_insn "*cmpqi_ext_2"
1075 [(set (reg FLAGS_REG)
1079 (match_operand 0 "ext_register_operand" "Q")
1082 (match_operand:QI 1 "const0_operand" "")))]
1083 "ix86_match_ccmode (insn, CCNOmode)"
1085 [(set_attr "type" "test")
1086 (set_attr "length_immediate" "0")
1087 (set_attr "mode" "QI")])
1089 (define_expand "cmpqi_ext_3"
1090 [(set (reg:CC FLAGS_REG)
1094 (match_operand 0 "ext_register_operand" "")
1097 (match_operand:QI 1 "immediate_operand" "")))])
1099 (define_insn "*cmpqi_ext_3_insn"
1100 [(set (reg FLAGS_REG)
1104 (match_operand 0 "ext_register_operand" "Q")
1107 (match_operand:QI 1 "general_operand" "Qmn")))]
1108 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1109 "cmp{b}\t{%1, %h0|%h0, %1}"
1110 [(set_attr "type" "icmp")
1111 (set_attr "modrm" "1")
1112 (set_attr "mode" "QI")])
1114 (define_insn "*cmpqi_ext_3_insn_rex64"
1115 [(set (reg FLAGS_REG)
1119 (match_operand 0 "ext_register_operand" "Q")
1122 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1123 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1124 "cmp{b}\t{%1, %h0|%h0, %1}"
1125 [(set_attr "type" "icmp")
1126 (set_attr "modrm" "1")
1127 (set_attr "mode" "QI")])
1129 (define_insn "*cmpqi_ext_4"
1130 [(set (reg FLAGS_REG)
1134 (match_operand 0 "ext_register_operand" "Q")
1139 (match_operand 1 "ext_register_operand" "Q")
1141 (const_int 8)) 0)))]
1142 "ix86_match_ccmode (insn, CCmode)"
1143 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1144 [(set_attr "type" "icmp")
1145 (set_attr "mode" "QI")])
1147 ;; These implement float point compares.
1148 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1149 ;; which would allow mix and match FP modes on the compares. Which is what
1150 ;; the old patterns did, but with many more of them.
1152 (define_expand "cbranchxf4"
1153 [(set (reg:CC FLAGS_REG)
1154 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1155 (match_operand:XF 2 "nonmemory_operand" "")))
1156 (set (pc) (if_then_else
1157 (match_operator 0 "ix86_fp_comparison_operator"
1160 (label_ref (match_operand 3 "" ""))
1164 ix86_expand_branch (GET_CODE (operands[0]),
1165 operands[1], operands[2], operands[3]);
1169 (define_expand "cstorexf4"
1170 [(set (reg:CC FLAGS_REG)
1171 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1172 (match_operand:XF 3 "nonmemory_operand" "")))
1173 (set (match_operand:QI 0 "register_operand" "")
1174 (match_operator 1 "ix86_fp_comparison_operator"
1179 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1180 operands[2], operands[3]);
1184 (define_expand "cbranch<mode>4"
1185 [(set (reg:CC FLAGS_REG)
1186 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1187 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1188 (set (pc) (if_then_else
1189 (match_operator 0 "ix86_fp_comparison_operator"
1192 (label_ref (match_operand 3 "" ""))
1194 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1196 ix86_expand_branch (GET_CODE (operands[0]),
1197 operands[1], operands[2], operands[3]);
1201 (define_expand "cstore<mode>4"
1202 [(set (reg:CC FLAGS_REG)
1203 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1204 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1205 (set (match_operand:QI 0 "register_operand" "")
1206 (match_operator 1 "ix86_fp_comparison_operator"
1209 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1211 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212 operands[2], operands[3]);
1216 (define_expand "cbranchcc4"
1217 [(set (pc) (if_then_else
1218 (match_operator 0 "comparison_operator"
1219 [(match_operand 1 "flags_reg_operand" "")
1220 (match_operand 2 "const0_operand" "")])
1221 (label_ref (match_operand 3 "" ""))
1225 ix86_expand_branch (GET_CODE (operands[0]),
1226 operands[1], operands[2], operands[3]);
1230 (define_expand "cstorecc4"
1231 [(set (match_operand:QI 0 "register_operand" "")
1232 (match_operator 1 "comparison_operator"
1233 [(match_operand 2 "flags_reg_operand" "")
1234 (match_operand 3 "const0_operand" "")]))]
1237 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238 operands[2], operands[3]);
1243 ;; FP compares, step 1:
1244 ;; Set the FP condition codes.
1246 ;; CCFPmode compare with exceptions
1247 ;; CCFPUmode compare with no exceptions
1249 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1250 ;; used to manage the reg stack popping would not be preserved.
1252 (define_insn "*cmpfp_0"
1253 [(set (match_operand:HI 0 "register_operand" "=a")
1256 (match_operand 1 "register_operand" "f")
1257 (match_operand 2 "const0_operand" ""))]
1259 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1260 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1261 "* return output_fp_compare (insn, operands, false, false);"
1262 [(set_attr "type" "multi")
1263 (set_attr "unit" "i387")
1265 (cond [(match_operand:SF 1 "" "")
1267 (match_operand:DF 1 "" "")
1270 (const_string "XF")))])
1272 (define_insn_and_split "*cmpfp_0_cc"
1273 [(set (reg:CCFP FLAGS_REG)
1275 (match_operand 1 "register_operand" "f")
1276 (match_operand 2 "const0_operand" "")))
1277 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1278 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1279 && TARGET_SAHF && !TARGET_CMOVE
1280 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1282 "&& reload_completed"
1285 [(compare:CCFP (match_dup 1)(match_dup 2))]
1287 (set (reg:CC FLAGS_REG)
1288 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290 [(set_attr "type" "multi")
1291 (set_attr "unit" "i387")
1293 (cond [(match_operand:SF 1 "" "")
1295 (match_operand:DF 1 "" "")
1298 (const_string "XF")))])
1300 (define_insn "*cmpfp_xf"
1301 [(set (match_operand:HI 0 "register_operand" "=a")
1304 (match_operand:XF 1 "register_operand" "f")
1305 (match_operand:XF 2 "register_operand" "f"))]
1308 "* return output_fp_compare (insn, operands, false, false);"
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "XF")])
1313 (define_insn_and_split "*cmpfp_xf_cc"
1314 [(set (reg:CCFP FLAGS_REG)
1316 (match_operand:XF 1 "register_operand" "f")
1317 (match_operand:XF 2 "register_operand" "f")))
1318 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1320 && TARGET_SAHF && !TARGET_CMOVE"
1322 "&& reload_completed"
1325 [(compare:CCFP (match_dup 1)(match_dup 2))]
1327 (set (reg:CC FLAGS_REG)
1328 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set_attr "mode" "XF")])
1334 (define_insn "*cmpfp_<mode>"
1335 [(set (match_operand:HI 0 "register_operand" "=a")
1338 (match_operand:MODEF 1 "register_operand" "f")
1339 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1342 "* return output_fp_compare (insn, operands, false, false);"
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1345 (set_attr "mode" "<MODE>")])
1347 (define_insn_and_split "*cmpfp_<mode>_cc"
1348 [(set (reg:CCFP FLAGS_REG)
1350 (match_operand:MODEF 1 "register_operand" "f")
1351 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1352 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1354 && TARGET_SAHF && !TARGET_CMOVE"
1356 "&& reload_completed"
1359 [(compare:CCFP (match_dup 1)(match_dup 2))]
1361 (set (reg:CC FLAGS_REG)
1362 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1364 [(set_attr "type" "multi")
1365 (set_attr "unit" "i387")
1366 (set_attr "mode" "<MODE>")])
1368 (define_insn "*cmpfp_u"
1369 [(set (match_operand:HI 0 "register_operand" "=a")
1372 (match_operand 1 "register_operand" "f")
1373 (match_operand 2 "register_operand" "f"))]
1375 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1377 "* return output_fp_compare (insn, operands, false, true);"
1378 [(set_attr "type" "multi")
1379 (set_attr "unit" "i387")
1381 (cond [(match_operand:SF 1 "" "")
1383 (match_operand:DF 1 "" "")
1386 (const_string "XF")))])
1388 (define_insn_and_split "*cmpfp_u_cc"
1389 [(set (reg:CCFPU FLAGS_REG)
1391 (match_operand 1 "register_operand" "f")
1392 (match_operand 2 "register_operand" "f")))
1393 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395 && TARGET_SAHF && !TARGET_CMOVE
1396 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1398 "&& reload_completed"
1401 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1403 (set (reg:CC FLAGS_REG)
1404 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1406 [(set_attr "type" "multi")
1407 (set_attr "unit" "i387")
1409 (cond [(match_operand:SF 1 "" "")
1411 (match_operand:DF 1 "" "")
1414 (const_string "XF")))])
1416 (define_insn "*cmpfp_<mode>"
1417 [(set (match_operand:HI 0 "register_operand" "=a")
1420 (match_operand 1 "register_operand" "f")
1421 (match_operator 3 "float_operator"
1422 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1424 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1425 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1426 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1427 "* return output_fp_compare (insn, operands, false, false);"
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set_attr "fp_int_src" "true")
1431 (set_attr "mode" "<MODE>")])
1433 (define_insn_and_split "*cmpfp_<mode>_cc"
1434 [(set (reg:CCFP FLAGS_REG)
1436 (match_operand 1 "register_operand" "f")
1437 (match_operator 3 "float_operator"
1438 [(match_operand:SWI24 2 "memory_operand" "m")])))
1439 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1440 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1441 && TARGET_SAHF && !TARGET_CMOVE
1442 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1443 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1445 "&& reload_completed"
1450 (match_op_dup 3 [(match_dup 2)]))]
1452 (set (reg:CC FLAGS_REG)
1453 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1455 [(set_attr "type" "multi")
1456 (set_attr "unit" "i387")
1457 (set_attr "fp_int_src" "true")
1458 (set_attr "mode" "<MODE>")])
1460 ;; FP compares, step 2
1461 ;; Move the fpsw to ax.
1463 (define_insn "x86_fnstsw_1"
1464 [(set (match_operand:HI 0 "register_operand" "=a")
1465 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1468 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1469 (set_attr "mode" "SI")
1470 (set_attr "unit" "i387")])
1472 ;; FP compares, step 3
1473 ;; Get ax into flags, general case.
1475 (define_insn "x86_sahf_1"
1476 [(set (reg:CC FLAGS_REG)
1477 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1481 #ifndef HAVE_AS_IX86_SAHF
1483 return ASM_BYTE "0x9e";
1488 [(set_attr "length" "1")
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "direct")
1491 (set_attr "bdver1_decode" "direct")
1492 (set_attr "mode" "SI")])
1494 ;; Pentium Pro can do steps 1 through 3 in one go.
1495 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1496 (define_insn "*cmpfp_i_mixed"
1497 [(set (reg:CCFP FLAGS_REG)
1498 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1499 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1500 "TARGET_MIX_SSE_I387
1501 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, true, false);"
1504 [(set_attr "type" "fcmp,ssecomi")
1505 (set_attr "prefix" "orig,maybe_vex")
1507 (if_then_else (match_operand:SF 1 "" "")
1509 (const_string "DF")))
1510 (set (attr "prefix_rep")
1511 (if_then_else (eq_attr "type" "ssecomi")
1513 (const_string "*")))
1514 (set (attr "prefix_data16")
1515 (cond [(eq_attr "type" "fcmp")
1517 (eq_attr "mode" "DF")
1520 (const_string "0")))
1521 (set_attr "athlon_decode" "vector")
1522 (set_attr "amdfam10_decode" "direct")
1523 (set_attr "bdver1_decode" "double")])
1525 (define_insn "*cmpfp_i_sse"
1526 [(set (reg:CCFP FLAGS_REG)
1527 (compare:CCFP (match_operand 0 "register_operand" "x")
1528 (match_operand 1 "nonimmediate_operand" "xm")))]
1530 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532 "* return output_fp_compare (insn, operands, true, false);"
1533 [(set_attr "type" "ssecomi")
1534 (set_attr "prefix" "maybe_vex")
1536 (if_then_else (match_operand:SF 1 "" "")
1538 (const_string "DF")))
1539 (set_attr "prefix_rep" "0")
1540 (set (attr "prefix_data16")
1541 (if_then_else (eq_attr "mode" "DF")
1543 (const_string "0")))
1544 (set_attr "athlon_decode" "vector")
1545 (set_attr "amdfam10_decode" "direct")
1546 (set_attr "bdver1_decode" "double")])
1548 (define_insn "*cmpfp_i_i387"
1549 [(set (reg:CCFP FLAGS_REG)
1550 (compare:CCFP (match_operand 0 "register_operand" "f")
1551 (match_operand 1 "register_operand" "f")))]
1552 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1554 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1555 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556 "* return output_fp_compare (insn, operands, true, false);"
1557 [(set_attr "type" "fcmp")
1559 (cond [(match_operand:SF 1 "" "")
1561 (match_operand:DF 1 "" "")
1564 (const_string "XF")))
1565 (set_attr "athlon_decode" "vector")
1566 (set_attr "amdfam10_decode" "direct")
1567 (set_attr "bdver1_decode" "double")])
1569 (define_insn "*cmpfp_iu_mixed"
1570 [(set (reg:CCFPU FLAGS_REG)
1571 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1572 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1573 "TARGET_MIX_SSE_I387
1574 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, true, true);"
1577 [(set_attr "type" "fcmp,ssecomi")
1578 (set_attr "prefix" "orig,maybe_vex")
1580 (if_then_else (match_operand:SF 1 "" "")
1582 (const_string "DF")))
1583 (set (attr "prefix_rep")
1584 (if_then_else (eq_attr "type" "ssecomi")
1586 (const_string "*")))
1587 (set (attr "prefix_data16")
1588 (cond [(eq_attr "type" "fcmp")
1590 (eq_attr "mode" "DF")
1593 (const_string "0")))
1594 (set_attr "athlon_decode" "vector")
1595 (set_attr "amdfam10_decode" "direct")
1596 (set_attr "bdver1_decode" "double")])
1598 (define_insn "*cmpfp_iu_sse"
1599 [(set (reg:CCFPU FLAGS_REG)
1600 (compare:CCFPU (match_operand 0 "register_operand" "x")
1601 (match_operand 1 "nonimmediate_operand" "xm")))]
1603 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1604 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1605 "* return output_fp_compare (insn, operands, true, true);"
1606 [(set_attr "type" "ssecomi")
1607 (set_attr "prefix" "maybe_vex")
1609 (if_then_else (match_operand:SF 1 "" "")
1611 (const_string "DF")))
1612 (set_attr "prefix_rep" "0")
1613 (set (attr "prefix_data16")
1614 (if_then_else (eq_attr "mode" "DF")
1616 (const_string "0")))
1617 (set_attr "athlon_decode" "vector")
1618 (set_attr "amdfam10_decode" "direct")
1619 (set_attr "bdver1_decode" "double")])
1621 (define_insn "*cmpfp_iu_387"
1622 [(set (reg:CCFPU FLAGS_REG)
1623 (compare:CCFPU (match_operand 0 "register_operand" "f")
1624 (match_operand 1 "register_operand" "f")))]
1625 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1627 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1628 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629 "* return output_fp_compare (insn, operands, true, true);"
1630 [(set_attr "type" "fcmp")
1632 (cond [(match_operand:SF 1 "" "")
1634 (match_operand:DF 1 "" "")
1637 (const_string "XF")))
1638 (set_attr "athlon_decode" "vector")
1639 (set_attr "amdfam10_decode" "direct")
1640 (set_attr "bdver1_decode" "direct")])
1642 ;; Push/pop instructions.
1644 (define_insn "*push<mode>2"
1645 [(set (match_operand:DWI 0 "push_operand" "=<")
1646 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1651 [(set (match_operand:TI 0 "push_operand" "")
1652 (match_operand:TI 1 "general_operand" ""))]
1653 "TARGET_64BIT && reload_completed
1654 && !SSE_REG_P (operands[1])"
1656 "ix86_split_long_move (operands); DONE;")
1658 (define_insn "*pushdi2_rex64"
1659 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1660 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1665 [(set_attr "type" "push,multi")
1666 (set_attr "mode" "DI")])
1668 ;; Convert impossible pushes of immediate to existing instructions.
1669 ;; First try to get scratch register and go through it. In case this
1670 ;; fails, push sign extended lower part first and then overwrite
1671 ;; upper part by 32bit move.
1673 [(match_scratch:DI 2 "r")
1674 (set (match_operand:DI 0 "push_operand" "")
1675 (match_operand:DI 1 "immediate_operand" ""))]
1676 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1677 && !x86_64_immediate_operand (operands[1], DImode)"
1678 [(set (match_dup 2) (match_dup 1))
1679 (set (match_dup 0) (match_dup 2))])
1681 ;; We need to define this as both peepholer and splitter for case
1682 ;; peephole2 pass is not run.
1683 ;; "&& 1" is needed to keep it from matching the previous pattern.
1685 [(set (match_operand:DI 0 "push_operand" "")
1686 (match_operand:DI 1 "immediate_operand" ""))]
1687 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1688 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1689 [(set (match_dup 0) (match_dup 1))
1690 (set (match_dup 2) (match_dup 3))]
1692 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1694 operands[1] = gen_lowpart (DImode, operands[2]);
1695 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1700 [(set (match_operand:DI 0 "push_operand" "")
1701 (match_operand:DI 1 "immediate_operand" ""))]
1702 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1703 ? epilogue_completed : reload_completed)
1704 && !symbolic_operand (operands[1], DImode)
1705 && !x86_64_immediate_operand (operands[1], DImode)"
1706 [(set (match_dup 0) (match_dup 1))
1707 (set (match_dup 2) (match_dup 3))]
1709 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1711 operands[1] = gen_lowpart (DImode, operands[2]);
1712 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1717 [(set (match_operand:DI 0 "push_operand" "")
1718 (match_operand:DI 1 "general_operand" ""))]
1719 "!TARGET_64BIT && reload_completed
1720 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1722 "ix86_split_long_move (operands); DONE;")
1724 (define_insn "*pushsi2"
1725 [(set (match_operand:SI 0 "push_operand" "=<")
1726 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "SI")])
1732 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1733 ;; "push a byte/word". But actually we use pushl, which has the effect
1734 ;; of rounding the amount pushed up to a word.
1736 ;; For TARGET_64BIT we always round up to 8 bytes.
1737 (define_insn "*push<mode>2_rex64"
1738 [(set (match_operand:SWI124 0 "push_operand" "=X")
1739 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "DI")])
1745 (define_insn "*push<mode>2"
1746 [(set (match_operand:SWI12 0 "push_operand" "=X")
1747 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1750 [(set_attr "type" "push")
1751 (set_attr "mode" "SI")])
1753 (define_insn "*push<mode>2_prologue"
1754 [(set (match_operand:P 0 "push_operand" "=<")
1755 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1756 (clobber (mem:BLK (scratch)))]
1758 "push{<imodesuffix>}\t%1"
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "<MODE>")])
1762 (define_insn "*pop<mode>1"
1763 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1764 (match_operand:P 1 "pop_operand" ">"))]
1766 "pop{<imodesuffix>}\t%0"
1767 [(set_attr "type" "pop")
1768 (set_attr "mode" "<MODE>")])
1770 (define_insn "*pop<mode>1_epilogue"
1771 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1772 (match_operand:P 1 "pop_operand" ">"))
1773 (clobber (mem:BLK (scratch)))]
1775 "pop{<imodesuffix>}\t%0"
1776 [(set_attr "type" "pop")
1777 (set_attr "mode" "<MODE>")])
1779 ;; Move instructions.
1781 (define_expand "movoi"
1782 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1783 (match_operand:OI 1 "general_operand" ""))]
1785 "ix86_expand_move (OImode, operands); DONE;")
1787 (define_expand "movti"
1788 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1789 (match_operand:TI 1 "nonimmediate_operand" ""))]
1790 "TARGET_64BIT || TARGET_SSE"
1793 ix86_expand_move (TImode, operands);
1794 else if (push_operand (operands[0], TImode))
1795 ix86_expand_push (TImode, operands[1]);
1797 ix86_expand_vector_move (TImode, operands);
1801 ;; This expands to what emit_move_complex would generate if we didn't
1802 ;; have a movti pattern. Having this avoids problems with reload on
1803 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1804 ;; to have around all the time.
1805 (define_expand "movcdi"
1806 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1807 (match_operand:CDI 1 "general_operand" ""))]
1810 if (push_operand (operands[0], CDImode))
1811 emit_move_complex_push (CDImode, operands[0], operands[1]);
1813 emit_move_complex_parts (operands[0], operands[1]);
1817 (define_expand "mov<mode>"
1818 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1819 (match_operand:SWI1248x 1 "general_operand" ""))]
1821 "ix86_expand_move (<MODE>mode, operands); DONE;")
1823 (define_insn "*mov<mode>_xor"
1824 [(set (match_operand:SWI48 0 "register_operand" "=r")
1825 (match_operand:SWI48 1 "const0_operand" ""))
1826 (clobber (reg:CC FLAGS_REG))]
1829 [(set_attr "type" "alu1")
1830 (set_attr "mode" "SI")
1831 (set_attr "length_immediate" "0")])
1833 (define_insn "*mov<mode>_or"
1834 [(set (match_operand:SWI48 0 "register_operand" "=r")
1835 (match_operand:SWI48 1 "const_int_operand" ""))
1836 (clobber (reg:CC FLAGS_REG))]
1838 && operands[1] == constm1_rtx"
1839 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1840 [(set_attr "type" "alu1")
1841 (set_attr "mode" "<MODE>")
1842 (set_attr "length_immediate" "1")])
1844 (define_insn "*movoi_internal_avx"
1845 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1846 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1847 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1849 switch (which_alternative)
1852 return standard_sse_constant_opcode (insn, operands[1]);
1855 if (misaligned_operand (operands[0], OImode)
1856 || misaligned_operand (operands[1], OImode))
1857 return "vmovdqu\t{%1, %0|%0, %1}";
1859 return "vmovdqa\t{%1, %0|%0, %1}";
1864 [(set_attr "type" "sselog1,ssemov,ssemov")
1865 (set_attr "prefix" "vex")
1866 (set_attr "mode" "OI")])
1868 (define_insn "*movti_internal_rex64"
1869 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1870 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1871 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1873 switch (which_alternative)
1879 return standard_sse_constant_opcode (insn, operands[1]);
1882 /* TDmode values are passed as TImode on the stack. Moving them
1883 to stack may result in unaligned memory access. */
1884 if (misaligned_operand (operands[0], TImode)
1885 || misaligned_operand (operands[1], TImode))
1887 if (get_attr_mode (insn) == MODE_V4SF)
1888 return "%vmovups\t{%1, %0|%0, %1}";
1890 return "%vmovdqu\t{%1, %0|%0, %1}";
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovaps\t{%1, %0|%0, %1}";
1897 return "%vmovdqa\t{%1, %0|%0, %1}";
1903 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1904 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1906 (cond [(eq_attr "alternative" "2,3")
1908 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1910 (const_string "V4SF")
1911 (const_string "TI"))
1912 (eq_attr "alternative" "4")
1914 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1916 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1918 (const_string "V4SF")
1919 (const_string "TI"))]
1920 (const_string "DI")))])
1923 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1924 (match_operand:TI 1 "general_operand" ""))]
1926 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1928 "ix86_split_long_move (operands); DONE;")
1930 (define_insn "*movti_internal_sse"
1931 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1932 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1933 "TARGET_SSE && !TARGET_64BIT
1934 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1936 switch (which_alternative)
1939 return standard_sse_constant_opcode (insn, operands[1]);
1942 /* TDmode values are passed as TImode on the stack. Moving them
1943 to stack may result in unaligned memory access. */
1944 if (misaligned_operand (operands[0], TImode)
1945 || misaligned_operand (operands[1], TImode))
1947 if (get_attr_mode (insn) == MODE_V4SF)
1948 return "%vmovups\t{%1, %0|%0, %1}";
1950 return "%vmovdqu\t{%1, %0|%0, %1}";
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovaps\t{%1, %0|%0, %1}";
1957 return "%vmovdqa\t{%1, %0|%0, %1}";
1963 [(set_attr "type" "sselog1,ssemov,ssemov")
1964 (set_attr "prefix" "maybe_vex")
1966 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1967 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1969 (const_string "V4SF")
1970 (and (eq_attr "alternative" "2")
1971 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1973 (const_string "V4SF")]
1974 (const_string "TI")))])
1976 (define_insn "*movdi_internal_rex64"
1977 [(set (match_operand:DI 0 "nonimmediate_operand"
1978 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1979 (match_operand:DI 1 "general_operand"
1980 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1981 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983 switch (get_attr_type (insn))
1986 if (SSE_REG_P (operands[0]))
1987 return "movq2dq\t{%1, %0|%0, %1}";
1989 return "movdq2q\t{%1, %0|%0, %1}";
1992 if (get_attr_mode (insn) == MODE_TI)
1993 return "%vmovdqa\t{%1, %0|%0, %1}";
1994 /* Handle broken assemblers that require movd instead of movq. */
1995 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996 return "%vmovd\t{%1, %0|%0, %1}";
1998 return "%vmovq\t{%1, %0|%0, %1}";
2001 /* Handle broken assemblers that require movd instead of movq. */
2002 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2003 return "movd\t{%1, %0|%0, %1}";
2005 return "movq\t{%1, %0|%0, %1}";
2008 return standard_sse_constant_opcode (insn, operands[1]);
2011 return "pxor\t%0, %0";
2017 return "lea{q}\t{%a1, %0|%0, %a1}";
2020 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2021 if (get_attr_mode (insn) == MODE_SI)
2022 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2023 else if (which_alternative == 2)
2024 return "movabs{q}\t{%1, %0|%0, %1}";
2026 return "mov{q}\t{%1, %0|%0, %1}";
2030 (cond [(eq_attr "alternative" "5")
2031 (const_string "mmx")
2032 (eq_attr "alternative" "6,7,8,9,10")
2033 (const_string "mmxmov")
2034 (eq_attr "alternative" "11")
2035 (const_string "sselog1")
2036 (eq_attr "alternative" "12,13,14,15,16")
2037 (const_string "ssemov")
2038 (eq_attr "alternative" "17,18")
2039 (const_string "ssecvt")
2040 (eq_attr "alternative" "4")
2041 (const_string "multi")
2042 (match_operand:DI 1 "pic_32bit_operand" "")
2043 (const_string "lea")
2045 (const_string "imov")))
2048 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2050 (const_string "*")))
2051 (set (attr "length_immediate")
2053 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2055 (const_string "*")))
2056 (set (attr "prefix_rex")
2057 (if_then_else (eq_attr "alternative" "7,9")
2059 (const_string "*")))
2060 (set (attr "prefix_data16")
2061 (if_then_else (eq_attr "alternative" "15")
2063 (const_string "*")))
2064 (set (attr "prefix")
2065 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2066 (const_string "maybe_vex")
2067 (const_string "orig")))
2068 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it. In case this
2072 ;; fails, move by 32bit parts.
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))])
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2086 [(set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090 [(set (match_dup 2) (match_dup 3))
2091 (set (match_dup 4) (match_dup 5))]
2092 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2095 [(set (match_operand:DI 0 "memory_operand" "")
2096 (match_operand:DI 1 "immediate_operand" ""))]
2097 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098 ? epilogue_completed : reload_completed)
2099 && !symbolic_operand (operands[1], DImode)
2100 && !x86_64_immediate_operand (operands[1], DImode)"
2101 [(set (match_dup 2) (match_dup 3))
2102 (set (match_dup 4) (match_dup 5))]
2103 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2105 (define_insn "*movdi_internal"
2106 [(set (match_operand:DI 0 "nonimmediate_operand"
2107 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2108 (match_operand:DI 1 "general_operand"
2109 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m ,*Ym ,*Y2"))]
2110 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2112 switch (get_attr_type (insn))
2115 if (SSE_REG_P (operands[0]))
2116 return "movq2dq\t{%1, %0|%0, %1}";
2118 return "movdq2q\t{%1, %0|%0, %1}";
2121 switch (get_attr_mode (insn))
2124 return "%vmovdqa\t{%1, %0|%0, %1}";
2126 return "%vmovq\t{%1, %0|%0, %1}";
2128 return "movaps\t{%1, %0|%0, %1}";
2130 return "movlps\t{%1, %0|%0, %1}";
2136 return "movq\t{%1, %0|%0, %1}";
2139 return standard_sse_constant_opcode (insn, operands[1]);
2142 return "pxor\t%0, %0";
2152 (if_then_else (eq_attr "alternative" "9,10,11,12")
2153 (const_string "noavx")
2154 (const_string "base")))
2156 (cond [(eq_attr "alternative" "0,1")
2157 (const_string "multi")
2158 (eq_attr "alternative" "2")
2159 (const_string "mmx")
2160 (eq_attr "alternative" "3,4")
2161 (const_string "mmxmov")
2162 (eq_attr "alternative" "5,9")
2163 (const_string "sselog1")
2164 (eq_attr "alternative" "13,14")
2165 (const_string "ssecvt")
2167 (const_string "ssemov")))
2168 (set (attr "prefix")
2169 (if_then_else (eq_attr "alternative" "5,6,7,8")
2170 (const_string "maybe_vex")
2171 (const_string "orig")))
2172 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2175 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2176 (match_operand:DI 1 "general_operand" ""))]
2177 "!TARGET_64BIT && reload_completed
2178 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2179 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2181 "ix86_split_long_move (operands); DONE;")
2183 (define_insn "*movsi_internal"
2184 [(set (match_operand:SI 0 "nonimmediate_operand"
2185 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2186 (match_operand:SI 1 "general_operand"
2187 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2188 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2190 switch (get_attr_type (insn))
2193 return standard_sse_constant_opcode (insn, operands[1]);
2196 switch (get_attr_mode (insn))
2199 return "%vmovdqa\t{%1, %0|%0, %1}";
2201 return "%vmovaps\t{%1, %0|%0, %1}";
2203 return "%vmovd\t{%1, %0|%0, %1}";
2205 return "%vmovss\t{%1, %0|%0, %1}";
2211 return "pxor\t%0, %0";
2214 if (get_attr_mode (insn) == MODE_DI)
2215 return "movq\t{%1, %0|%0, %1}";
2216 return "movd\t{%1, %0|%0, %1}";
2219 return "lea{l}\t{%a1, %0|%0, %a1}";
2222 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2223 return "mov{l}\t{%1, %0|%0, %1}";
2227 (cond [(eq_attr "alternative" "2")
2228 (const_string "mmx")
2229 (eq_attr "alternative" "3,4,5")
2230 (const_string "mmxmov")
2231 (eq_attr "alternative" "6")
2232 (const_string "sselog1")
2233 (eq_attr "alternative" "7,8,9,10,11")
2234 (const_string "ssemov")
2235 (match_operand:DI 1 "pic_32bit_operand" "")
2236 (const_string "lea")
2238 (const_string "imov")))
2239 (set (attr "prefix")
2240 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2241 (const_string "orig")
2242 (const_string "maybe_vex")))
2243 (set (attr "prefix_data16")
2244 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2246 (const_string "*")))
2248 (cond [(eq_attr "alternative" "2,3")
2250 (eq_attr "alternative" "6,7")
2252 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2253 (const_string "V4SF")
2254 (const_string "TI"))
2255 (and (eq_attr "alternative" "8,9,10,11")
2256 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2259 (const_string "SI")))])
2261 (define_insn "*movhi_internal"
2262 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2263 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2264 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2266 switch (get_attr_type (insn))
2269 /* movzwl is faster than movw on p2 due to partial word stalls,
2270 though not as fast as an aligned movl. */
2271 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2273 if (get_attr_mode (insn) == MODE_SI)
2274 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2276 return "mov{w}\t{%1, %0|%0, %1}";
2280 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2282 (const_string "imov")
2283 (and (eq_attr "alternative" "0")
2284 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2286 (eq (symbol_ref "TARGET_HIMODE_MATH")
2288 (const_string "imov")
2289 (and (eq_attr "alternative" "1,2")
2290 (match_operand:HI 1 "aligned_operand" ""))
2291 (const_string "imov")
2292 (and (ne (symbol_ref "TARGET_MOVX")
2294 (eq_attr "alternative" "0,2"))
2295 (const_string "imovx")
2297 (const_string "imov")))
2299 (cond [(eq_attr "type" "imovx")
2301 (and (eq_attr "alternative" "1,2")
2302 (match_operand:HI 1 "aligned_operand" ""))
2304 (and (eq_attr "alternative" "0")
2305 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2307 (eq (symbol_ref "TARGET_HIMODE_MATH")
2311 (const_string "HI")))])
2313 ;; Situation is quite tricky about when to choose full sized (SImode) move
2314 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2315 ;; partial register dependency machines (such as AMD Athlon), where QImode
2316 ;; moves issue extra dependency and for partial register stalls machines
2317 ;; that don't use QImode patterns (and QImode move cause stall on the next
2320 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2321 ;; register stall machines with, where we use QImode instructions, since
2322 ;; partial register stall can be caused there. Then we use movzx.
2323 (define_insn "*movqi_internal"
2324 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2325 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2326 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2328 switch (get_attr_type (insn))
2331 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2332 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2334 if (get_attr_mode (insn) == MODE_SI)
2335 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2337 return "mov{b}\t{%1, %0|%0, %1}";
2341 (cond [(and (eq_attr "alternative" "5")
2342 (not (match_operand:QI 1 "aligned_operand" "")))
2343 (const_string "imovx")
2344 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2346 (const_string "imov")
2347 (and (eq_attr "alternative" "3")
2348 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2350 (eq (symbol_ref "TARGET_QIMODE_MATH")
2352 (const_string "imov")
2353 (eq_attr "alternative" "3,5")
2354 (const_string "imovx")
2355 (and (ne (symbol_ref "TARGET_MOVX")
2357 (eq_attr "alternative" "2"))
2358 (const_string "imovx")
2360 (const_string "imov")))
2362 (cond [(eq_attr "alternative" "3,4,5")
2364 (eq_attr "alternative" "6")
2366 (eq_attr "type" "imovx")
2368 (and (eq_attr "type" "imov")
2369 (and (eq_attr "alternative" "0,1")
2370 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2372 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2374 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2377 ;; Avoid partial register stalls when not using QImode arithmetic
2378 (and (eq_attr "type" "imov")
2379 (and (eq_attr "alternative" "0,1")
2380 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2382 (eq (symbol_ref "TARGET_QIMODE_MATH")
2386 (const_string "QI")))])
2388 ;; Stores and loads of ax to arbitrary constant address.
2389 ;; We fake an second form of instruction to force reload to load address
2390 ;; into register when rax is not available
2391 (define_insn "*movabs<mode>_1"
2392 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2393 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2394 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2396 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2397 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2398 [(set_attr "type" "imov")
2399 (set_attr "modrm" "0,*")
2400 (set_attr "length_address" "8,0")
2401 (set_attr "length_immediate" "0,*")
2402 (set_attr "memory" "store")
2403 (set_attr "mode" "<MODE>")])
2405 (define_insn "*movabs<mode>_2"
2406 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2407 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2408 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2410 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2411 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2412 [(set_attr "type" "imov")
2413 (set_attr "modrm" "0,*")
2414 (set_attr "length_address" "8,0")
2415 (set_attr "length_immediate" "0")
2416 (set_attr "memory" "load")
2417 (set_attr "mode" "<MODE>")])
2419 (define_insn "*swap<mode>"
2420 [(set (match_operand:SWI48 0 "register_operand" "+r")
2421 (match_operand:SWI48 1 "register_operand" "+r"))
2425 "xchg{<imodesuffix>}\t%1, %0"
2426 [(set_attr "type" "imov")
2427 (set_attr "mode" "<MODE>")
2428 (set_attr "pent_pair" "np")
2429 (set_attr "athlon_decode" "vector")
2430 (set_attr "amdfam10_decode" "double")
2431 (set_attr "bdver1_decode" "double")])
2433 (define_insn "*swap<mode>_1"
2434 [(set (match_operand:SWI12 0 "register_operand" "+r")
2435 (match_operand:SWI12 1 "register_operand" "+r"))
2438 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2440 [(set_attr "type" "imov")
2441 (set_attr "mode" "SI")
2442 (set_attr "pent_pair" "np")
2443 (set_attr "athlon_decode" "vector")
2444 (set_attr "amdfam10_decode" "double")
2445 (set_attr "bdver1_decode" "double")])
2447 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2448 ;; is disabled for AMDFAM10
2449 (define_insn "*swap<mode>_2"
2450 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2451 (match_operand:SWI12 1 "register_operand" "+<r>"))
2454 "TARGET_PARTIAL_REG_STALL"
2455 "xchg{<imodesuffix>}\t%1, %0"
2456 [(set_attr "type" "imov")
2457 (set_attr "mode" "<MODE>")
2458 (set_attr "pent_pair" "np")
2459 (set_attr "athlon_decode" "vector")])
2461 (define_expand "movstrict<mode>"
2462 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2463 (match_operand:SWI12 1 "general_operand" ""))]
2466 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2468 if (GET_CODE (operands[0]) == SUBREG
2469 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2471 /* Don't generate memory->memory moves, go through a register */
2472 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2473 operands[1] = force_reg (<MODE>mode, operands[1]);
2476 (define_insn "*movstrict<mode>_1"
2477 [(set (strict_low_part
2478 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2479 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2480 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2481 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2483 [(set_attr "type" "imov")
2484 (set_attr "mode" "<MODE>")])
2486 (define_insn "*movstrict<mode>_xor"
2487 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2488 (match_operand:SWI12 1 "const0_operand" ""))
2489 (clobber (reg:CC FLAGS_REG))]
2491 "xor{<imodesuffix>}\t%0, %0"
2492 [(set_attr "type" "alu1")
2493 (set_attr "mode" "<MODE>")
2494 (set_attr "length_immediate" "0")])
2496 (define_insn "*mov<mode>_extv_1"
2497 [(set (match_operand:SWI24 0 "register_operand" "=R")
2498 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2502 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2503 [(set_attr "type" "imovx")
2504 (set_attr "mode" "SI")])
2506 (define_insn "*movqi_extv_1_rex64"
2507 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2508 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2513 switch (get_attr_type (insn))
2516 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2518 return "mov{b}\t{%h1, %0|%0, %h1}";
2522 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2523 (ne (symbol_ref "TARGET_MOVX")
2525 (const_string "imovx")
2526 (const_string "imov")))
2528 (if_then_else (eq_attr "type" "imovx")
2530 (const_string "QI")))])
2532 (define_insn "*movqi_extv_1"
2533 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2534 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2539 switch (get_attr_type (insn))
2542 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2544 return "mov{b}\t{%h1, %0|%0, %h1}";
2548 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2549 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2550 (ne (symbol_ref "TARGET_MOVX")
2552 (const_string "imovx")
2553 (const_string "imov")))
2555 (if_then_else (eq_attr "type" "imovx")
2557 (const_string "QI")))])
2559 (define_insn "*mov<mode>_extzv_1"
2560 [(set (match_operand:SWI48 0 "register_operand" "=R")
2561 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2565 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2566 [(set_attr "type" "imovx")
2567 (set_attr "mode" "SI")])
2569 (define_insn "*movqi_extzv_2_rex64"
2570 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2572 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2577 switch (get_attr_type (insn))
2580 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2582 return "mov{b}\t{%h1, %0|%0, %h1}";
2586 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2587 (ne (symbol_ref "TARGET_MOVX")
2589 (const_string "imovx")
2590 (const_string "imov")))
2592 (if_then_else (eq_attr "type" "imovx")
2594 (const_string "QI")))])
2596 (define_insn "*movqi_extzv_2"
2597 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2599 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2604 switch (get_attr_type (insn))
2607 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2609 return "mov{b}\t{%h1, %0|%0, %h1}";
2613 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2614 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2615 (ne (symbol_ref "TARGET_MOVX")
2617 (const_string "imovx")
2618 (const_string "imov")))
2620 (if_then_else (eq_attr "type" "imovx")
2622 (const_string "QI")))])
2624 (define_expand "mov<mode>_insv_1"
2625 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2628 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2630 (define_insn "*mov<mode>_insv_1_rex64"
2631 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2634 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2636 "mov{b}\t{%b1, %h0|%h0, %b1}"
2637 [(set_attr "type" "imov")
2638 (set_attr "mode" "QI")])
2640 (define_insn "*movsi_insv_1"
2641 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2644 (match_operand:SI 1 "general_operand" "Qmn"))]
2646 "mov{b}\t{%b1, %h0|%h0, %b1}"
2647 [(set_attr "type" "imov")
2648 (set_attr "mode" "QI")])
2650 (define_insn "*movqi_insv_2"
2651 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2654 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2657 "mov{b}\t{%h1, %h0|%h0, %h1}"
2658 [(set_attr "type" "imov")
2659 (set_attr "mode" "QI")])
2661 ;; Floating point push instructions.
2663 (define_insn "*pushtf"
2664 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2665 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2668 /* This insn should be already split before reg-stack. */
2671 [(set_attr "type" "multi")
2672 (set_attr "unit" "sse,*,*")
2673 (set_attr "mode" "TF,SI,SI")])
2675 ;; %%% Kill this when call knows how to work this out.
2677 [(set (match_operand:TF 0 "push_operand" "")
2678 (match_operand:TF 1 "sse_reg_operand" ""))]
2679 "TARGET_SSE2 && reload_completed"
2680 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2681 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2683 (define_insn "*pushxf"
2684 [(set (match_operand:XF 0 "push_operand" "=<,<")
2685 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2686 "optimize_function_for_speed_p (cfun)"
2688 /* This insn should be already split before reg-stack. */
2691 [(set_attr "type" "multi")
2692 (set_attr "unit" "i387,*")
2693 (set_attr "mode" "XF,SI")])
2695 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2696 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2697 ;; Pushing using integer instructions is longer except for constants
2698 ;; and direct memory references (assuming that any given constant is pushed
2699 ;; only once, but this ought to be handled elsewhere).
2701 (define_insn "*pushxf_nointeger"
2702 [(set (match_operand:XF 0 "push_operand" "=X,X")
2703 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2704 "optimize_function_for_size_p (cfun)"
2706 /* This insn should be already split before reg-stack. */
2709 [(set_attr "type" "multi")
2710 (set_attr "unit" "i387,*")
2711 (set_attr "mode" "XF,SI")])
2713 ;; %%% Kill this when call knows how to work this out.
2715 [(set (match_operand:XF 0 "push_operand" "")
2716 (match_operand:XF 1 "fp_register_operand" ""))]
2718 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2719 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2720 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2724 ;; On the average, pushdf using integers can be still shorter.
2726 (define_insn "*pushdf"
2727 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2728 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2731 /* This insn should be already split before reg-stack. */
2734 [(set_attr "type" "multi")
2735 (set_attr "unit" "i387,*,*")
2736 (set_attr "mode" "DF,SI,DF")])
2738 ;; %%% Kill this when call knows how to work this out.
2740 [(set (match_operand:DF 0 "push_operand" "")
2741 (match_operand:DF 1 "any_fp_register_operand" ""))]
2743 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2744 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2746 (define_insn "*pushsf_rex64"
2747 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2748 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2751 /* Anything else should be already split before reg-stack. */
2752 gcc_assert (which_alternative == 1);
2753 return "push{q}\t%q1";
2755 [(set_attr "type" "multi,push,multi")
2756 (set_attr "unit" "i387,*,*")
2757 (set_attr "mode" "SF,DI,SF")])
2759 (define_insn "*pushsf"
2760 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2761 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2764 /* Anything else should be already split before reg-stack. */
2765 gcc_assert (which_alternative == 1);
2766 return "push{l}\t%1";
2768 [(set_attr "type" "multi,push,multi")
2769 (set_attr "unit" "i387,*,*")
2770 (set_attr "mode" "SF,SI,SF")])
2772 ;; %%% Kill this when call knows how to work this out.
2774 [(set (match_operand:SF 0 "push_operand" "")
2775 (match_operand:SF 1 "any_fp_register_operand" ""))]
2777 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2782 [(set (match_operand:SF 0 "push_operand" "")
2783 (match_operand:SF 1 "memory_operand" ""))]
2785 && (operands[2] = find_constant_src (insn))"
2786 [(set (match_dup 0) (match_dup 2))])
2789 [(set (match_operand 0 "push_operand" "")
2790 (match_operand 1 "general_operand" ""))]
2792 && (GET_MODE (operands[0]) == TFmode
2793 || GET_MODE (operands[0]) == XFmode
2794 || GET_MODE (operands[0]) == DFmode)
2795 && !ANY_FP_REG_P (operands[1])"
2797 "ix86_split_long_move (operands); DONE;")
2799 ;; Floating point move instructions.
2801 (define_expand "movtf"
2802 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803 (match_operand:TF 1 "nonimmediate_operand" ""))]
2806 ix86_expand_move (TFmode, operands);
2810 (define_expand "mov<mode>"
2811 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2812 (match_operand:X87MODEF 1 "general_operand" ""))]
2814 "ix86_expand_move (<MODE>mode, operands); DONE;")
2816 (define_insn "*movtf_internal"
2817 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2818 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2821 && (!can_create_pseudo_p ()
2822 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2823 || GET_CODE (operands[1]) != CONST_DOUBLE
2824 || (optimize_function_for_size_p (cfun)
2825 && standard_sse_constant_p (operands[1])
2826 && !memory_operand (operands[0], TFmode))
2827 || (!TARGET_MEMORY_MISMATCH_STALL
2828 && memory_operand (operands[0], TFmode)))"
2830 switch (which_alternative)
2834 /* Handle misaligned load/store since we
2835 don't have movmisaligntf pattern. */
2836 if (misaligned_operand (operands[0], TFmode)
2837 || misaligned_operand (operands[1], TFmode))
2839 if (get_attr_mode (insn) == MODE_V4SF)
2840 return "%vmovups\t{%1, %0|%0, %1}";
2842 return "%vmovdqu\t{%1, %0|%0, %1}";
2846 if (get_attr_mode (insn) == MODE_V4SF)
2847 return "%vmovaps\t{%1, %0|%0, %1}";
2849 return "%vmovdqa\t{%1, %0|%0, %1}";
2853 return standard_sse_constant_opcode (insn, operands[1]);
2863 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2864 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2866 (cond [(eq_attr "alternative" "0,2")
2868 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2870 (const_string "V4SF")
2871 (const_string "TI"))
2872 (eq_attr "alternative" "1")
2874 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2876 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2878 (const_string "V4SF")
2879 (const_string "TI"))]
2880 (const_string "DI")))])
2882 ;; Possible store forwarding (partial memory) stall in alternative 4.
2883 (define_insn "*movxf_internal"
2884 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2885 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2886 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2887 && (!can_create_pseudo_p ()
2888 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889 || GET_CODE (operands[1]) != CONST_DOUBLE
2890 || (optimize_function_for_size_p (cfun)
2891 && standard_80387_constant_p (operands[1]) > 0
2892 && !memory_operand (operands[0], XFmode))
2893 || (!TARGET_MEMORY_MISMATCH_STALL
2894 && memory_operand (operands[0], XFmode)))"
2896 switch (which_alternative)
2900 return output_387_reg_move (insn, operands);
2903 return standard_80387_constant_opcode (operands[1]);
2913 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2914 (set_attr "mode" "XF,XF,XF,SI,SI")])
2916 (define_insn "*movdf_internal_rex64"
2917 [(set (match_operand:DF 0 "nonimmediate_operand"
2918 "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2919 (match_operand:DF 1 "general_operand"
2920 "fm,f,G,rm,r ,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2921 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922 && (!can_create_pseudo_p ()
2923 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2924 || GET_CODE (operands[1]) != CONST_DOUBLE
2925 || (optimize_function_for_size_p (cfun)
2926 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2927 && standard_80387_constant_p (operands[1]) > 0)
2928 || (TARGET_SSE2 && TARGET_SSE_MATH
2929 && standard_sse_constant_p (operands[1]))))
2930 || memory_operand (operands[0], DFmode))"
2932 switch (which_alternative)
2936 return output_387_reg_move (insn, operands);
2939 return standard_80387_constant_opcode (operands[1]);
2943 return "mov{q}\t{%1, %0|%0, %1}";
2946 return "movabs{q}\t{%1, %0|%0, %1}";
2952 return standard_sse_constant_opcode (insn, operands[1]);
2957 switch (get_attr_mode (insn))
2960 return "%vmovaps\t{%1, %0|%0, %1}";
2962 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2963 return "%vmovaps\t{%1, %0|%0, %1}";
2965 return "%vmovapd\t{%1, %0|%0, %1}";
2967 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2968 return "%vmovaps\t{%1, %0|%0, %1}";
2970 return "%vmovdqa\t{%1, %0|%0, %1}";
2972 return "%vmovq\t{%1, %0|%0, %1}";
2974 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2975 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2977 return "%vmovsd\t{%1, %0|%0, %1}";
2979 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2981 return "%vmovlps\t{%1, %d0|%d0, %1}";
2988 /* Handle broken assemblers that require movd instead of movq. */
2989 return "%vmovd\t{%1, %0|%0, %1}";
2995 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2998 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3000 (const_string "*")))
3001 (set (attr "length_immediate")
3003 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3005 (const_string "*")))
3006 (set (attr "prefix")
3007 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3008 (const_string "orig")
3009 (const_string "maybe_vex")))
3010 (set (attr "prefix_data16")
3011 (if_then_else (eq_attr "mode" "V1DF")
3013 (const_string "*")))
3015 (cond [(eq_attr "alternative" "0,1,2")
3017 (eq_attr "alternative" "3,4,5,6,11,12")
3020 /* For SSE1, we have many fewer alternatives. */
3021 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3022 (cond [(eq_attr "alternative" "7,8")
3023 (const_string "V4SF")
3025 (const_string "V2SF"))
3027 /* xorps is one byte shorter. */
3028 (eq_attr "alternative" "7")
3029 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3031 (const_string "V4SF")
3032 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3036 (const_string "V2DF"))
3038 /* For architectures resolving dependencies on
3039 whole SSE registers use APD move to break dependency
3040 chains, otherwise use short move to avoid extra work.
3042 movaps encodes one byte shorter. */
3043 (eq_attr "alternative" "8")
3045 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3047 (const_string "V4SF")
3048 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3050 (const_string "V2DF")
3052 (const_string "DF"))
3053 /* For architectures resolving dependencies on register
3054 parts we may avoid extra work to zero out upper part
3056 (eq_attr "alternative" "9")
3058 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3060 (const_string "V1DF")
3061 (const_string "DF"))
3063 (const_string "DF")))])
3065 ;; Possible store forwarding (partial memory) stall in alternative 4.
3066 (define_insn "*movdf_internal"
3067 [(set (match_operand:DF 0 "nonimmediate_operand"
3068 "=f,m,f,?Yd*r ,!o ,Y2*x,Y2*x,Y2*x,m ")
3069 (match_operand:DF 1 "general_operand"
3070 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3071 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3072 && (!can_create_pseudo_p ()
3073 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3074 || GET_CODE (operands[1]) != CONST_DOUBLE
3075 || (optimize_function_for_size_p (cfun)
3076 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3077 && standard_80387_constant_p (operands[1]) > 0)
3078 || (TARGET_SSE2 && TARGET_SSE_MATH
3079 && standard_sse_constant_p (operands[1])))
3080 && !memory_operand (operands[0], DFmode))
3081 || (!TARGET_MEMORY_MISMATCH_STALL
3082 && memory_operand (operands[0], DFmode)))"
3084 switch (which_alternative)
3088 return output_387_reg_move (insn, operands);
3091 return standard_80387_constant_opcode (operands[1]);
3098 return standard_sse_constant_opcode (insn, operands[1]);
3103 switch (get_attr_mode (insn))
3106 return "%vmovaps\t{%1, %0|%0, %1}";
3108 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3109 return "%vmovaps\t{%1, %0|%0, %1}";
3111 return "%vmovapd\t{%1, %0|%0, %1}";
3113 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3114 return "%vmovaps\t{%1, %0|%0, %1}";
3116 return "%vmovdqa\t{%1, %0|%0, %1}";
3118 return "%vmovq\t{%1, %0|%0, %1}";
3120 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3121 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3123 return "%vmovsd\t{%1, %0|%0, %1}";
3125 if (TARGET_AVX && REG_P (operands[0]))
3126 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3128 return "%vmovlpd\t{%1, %0|%0, %1}";
3130 if (TARGET_AVX && REG_P (operands[0]))
3131 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3133 return "%vmovlps\t{%1, %0|%0, %1}";
3142 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3143 (set (attr "prefix")
3144 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3145 (const_string "orig")
3146 (const_string "maybe_vex")))
3147 (set (attr "prefix_data16")
3148 (if_then_else (eq_attr "mode" "V1DF")
3150 (const_string "*")))
3152 (cond [(eq_attr "alternative" "0,1,2")
3154 (eq_attr "alternative" "3,4")
3157 /* For SSE1, we have many fewer alternatives. */
3158 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3159 (cond [(eq_attr "alternative" "5,6")
3160 (const_string "V4SF")
3162 (const_string "V2SF"))
3164 /* xorps is one byte shorter. */
3165 (eq_attr "alternative" "5")
3166 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3168 (const_string "V4SF")
3169 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3173 (const_string "V2DF"))
3175 /* For architectures resolving dependencies on
3176 whole SSE registers use APD move to break dependency
3177 chains, otherwise use short move to avoid extra work.
3179 movaps encodes one byte shorter. */
3180 (eq_attr "alternative" "6")
3182 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3184 (const_string "V4SF")
3185 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3187 (const_string "V2DF")
3189 (const_string "DF"))
3190 /* For architectures resolving dependencies on register
3191 parts we may avoid extra work to zero out upper part
3193 (eq_attr "alternative" "7")
3195 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3197 (const_string "V1DF")
3198 (const_string "DF"))
3200 (const_string "DF")))])
3202 (define_insn "*movsf_internal"
3203 [(set (match_operand:SF 0 "nonimmediate_operand"
3204 "=f,m,f,?r ,?m,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3205 (match_operand:SF 1 "general_operand"
3206 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3207 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3208 && (!can_create_pseudo_p ()
3209 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3210 || GET_CODE (operands[1]) != CONST_DOUBLE
3211 || (optimize_function_for_size_p (cfun)
3212 && ((!TARGET_SSE_MATH
3213 && standard_80387_constant_p (operands[1]) > 0)
3215 && standard_sse_constant_p (operands[1]))))
3216 || memory_operand (operands[0], SFmode))"
3218 switch (which_alternative)
3222 return output_387_reg_move (insn, operands);
3225 return standard_80387_constant_opcode (operands[1]);
3229 return "mov{l}\t{%1, %0|%0, %1}";
3232 return standard_sse_constant_opcode (insn, operands[1]);
3235 if (get_attr_mode (insn) == MODE_V4SF)
3236 return "%vmovaps\t{%1, %0|%0, %1}";
3238 return "%vmovss\t{%1, %d0|%d0, %1}";
3240 if (TARGET_AVX && REG_P (operands[1]))
3241 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3243 return "%vmovss\t{%1, %0|%0, %1}";
3245 return "%vmovss\t{%1, %0|%0, %1}";
3247 case 9: case 10: case 14: case 15:
3248 return "movd\t{%1, %0|%0, %1}";
3251 return "movq\t{%1, %0|%0, %1}";
3254 return "%vmovd\t{%1, %0|%0, %1}";
3260 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3261 (set (attr "prefix")
3262 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3263 (const_string "maybe_vex")
3264 (const_string "orig")))
3266 (cond [(eq_attr "alternative" "3,4,9,10")
3268 (eq_attr "alternative" "5")
3270 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3272 (ne (symbol_ref "TARGET_SSE2")
3274 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3277 (const_string "V4SF"))
3278 /* For architectures resolving dependencies on
3279 whole SSE registers use APS move to break dependency
3280 chains, otherwise use short move to avoid extra work.
3282 Do the same for architectures resolving dependencies on
3283 the parts. While in DF mode it is better to always handle
3284 just register parts, the SF mode is different due to lack
3285 of instructions to load just part of the register. It is
3286 better to maintain the whole registers in single format
3287 to avoid problems on using packed logical operations. */
3288 (eq_attr "alternative" "6")
3290 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3292 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3294 (const_string "V4SF")
3295 (const_string "SF"))
3296 (eq_attr "alternative" "11")
3297 (const_string "DI")]
3298 (const_string "SF")))])
3301 [(set (match_operand 0 "any_fp_register_operand" "")
3302 (match_operand 1 "memory_operand" ""))]
3304 && (GET_MODE (operands[0]) == TFmode
3305 || GET_MODE (operands[0]) == XFmode
3306 || GET_MODE (operands[0]) == DFmode
3307 || GET_MODE (operands[0]) == SFmode)
3308 && (operands[2] = find_constant_src (insn))"
3309 [(set (match_dup 0) (match_dup 2))]
3311 rtx c = operands[2];
3312 int r = REGNO (operands[0]);
3314 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3315 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3320 [(set (match_operand 0 "any_fp_register_operand" "")
3321 (float_extend (match_operand 1 "memory_operand" "")))]
3323 && (GET_MODE (operands[0]) == TFmode
3324 || GET_MODE (operands[0]) == XFmode
3325 || GET_MODE (operands[0]) == DFmode)
3326 && (operands[2] = find_constant_src (insn))"
3327 [(set (match_dup 0) (match_dup 2))]
3329 rtx c = operands[2];
3330 int r = REGNO (operands[0]);
3332 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3333 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3337 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3339 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3340 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3342 && (standard_80387_constant_p (operands[1]) == 8
3343 || standard_80387_constant_p (operands[1]) == 9)"
3344 [(set (match_dup 0)(match_dup 1))
3346 (neg:X87MODEF (match_dup 0)))]
3350 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3351 if (real_isnegzero (&r))
3352 operands[1] = CONST0_RTX (<MODE>mode);
3354 operands[1] = CONST1_RTX (<MODE>mode);
3358 [(set (match_operand 0 "nonimmediate_operand" "")
3359 (match_operand 1 "general_operand" ""))]
3361 && (GET_MODE (operands[0]) == TFmode
3362 || GET_MODE (operands[0]) == XFmode
3363 || GET_MODE (operands[0]) == DFmode)
3364 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3366 "ix86_split_long_move (operands); DONE;")
3368 (define_insn "swapxf"
3369 [(set (match_operand:XF 0 "register_operand" "+f")
3370 (match_operand:XF 1 "register_operand" "+f"))
3375 if (STACK_TOP_P (operands[0]))
3380 [(set_attr "type" "fxch")
3381 (set_attr "mode" "XF")])
3383 (define_insn "*swap<mode>"
3384 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3385 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3388 "TARGET_80387 || reload_completed"
3390 if (STACK_TOP_P (operands[0]))
3395 [(set_attr "type" "fxch")
3396 (set_attr "mode" "<MODE>")])
3398 ;; Zero extension instructions
3400 (define_expand "zero_extendsidi2"
3401 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3402 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3407 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3412 (define_insn "*zero_extendsidi2_rex64"
3413 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3415 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3418 mov\t{%k1, %k0|%k0, %k1}
3420 movd\t{%1, %0|%0, %1}
3421 movd\t{%1, %0|%0, %1}
3422 %vmovd\t{%1, %0|%0, %1}
3423 %vmovd\t{%1, %0|%0, %1}"
3424 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3425 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3426 (set_attr "prefix_0f" "0,*,*,*,*,*")
3427 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3430 [(set (match_operand:DI 0 "memory_operand" "")
3431 (zero_extend:DI (match_dup 0)))]
3433 [(set (match_dup 4) (const_int 0))]
3434 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3436 ;; %%% Kill me once multi-word ops are sane.
3437 (define_insn "zero_extendsidi2_1"
3438 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3440 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3441 (clobber (reg:CC FLAGS_REG))]
3447 movd\t{%1, %0|%0, %1}
3448 movd\t{%1, %0|%0, %1}
3449 %vmovd\t{%1, %0|%0, %1}
3450 %vmovd\t{%1, %0|%0, %1}"
3451 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3452 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3453 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3456 [(set (match_operand:DI 0 "register_operand" "")
3457 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3458 (clobber (reg:CC FLAGS_REG))]
3459 "!TARGET_64BIT && reload_completed
3460 && true_regnum (operands[0]) == true_regnum (operands[1])"
3461 [(set (match_dup 4) (const_int 0))]
3462 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3465 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3466 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3467 (clobber (reg:CC FLAGS_REG))]
3468 "!TARGET_64BIT && reload_completed
3469 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3470 [(set (match_dup 3) (match_dup 1))
3471 (set (match_dup 4) (const_int 0))]
3472 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3474 (define_insn "zero_extend<mode>di2"
3475 [(set (match_operand:DI 0 "register_operand" "=r")
3477 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3479 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3480 [(set_attr "type" "imovx")
3481 (set_attr "mode" "SI")])
3483 (define_expand "zero_extendhisi2"
3484 [(set (match_operand:SI 0 "register_operand" "")
3485 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3488 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3490 operands[1] = force_reg (HImode, operands[1]);
3491 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3496 (define_insn_and_split "zero_extendhisi2_and"
3497 [(set (match_operand:SI 0 "register_operand" "=r")
3498 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3499 (clobber (reg:CC FLAGS_REG))]
3500 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3502 "&& reload_completed"
3503 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3504 (clobber (reg:CC FLAGS_REG))])]
3506 [(set_attr "type" "alu1")
3507 (set_attr "mode" "SI")])
3509 (define_insn "*zero_extendhisi2_movzwl"
3510 [(set (match_operand:SI 0 "register_operand" "=r")
3511 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3512 "!TARGET_ZERO_EXTEND_WITH_AND
3513 || optimize_function_for_size_p (cfun)"
3514 "movz{wl|x}\t{%1, %0|%0, %1}"
3515 [(set_attr "type" "imovx")
3516 (set_attr "mode" "SI")])
3518 (define_expand "zero_extendqi<mode>2"
3520 [(set (match_operand:SWI24 0 "register_operand" "")
3521 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3522 (clobber (reg:CC FLAGS_REG))])])
3524 (define_insn "*zero_extendqi<mode>2_and"
3525 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3526 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3527 (clobber (reg:CC FLAGS_REG))]
3528 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3530 [(set_attr "type" "alu1")
3531 (set_attr "mode" "<MODE>")])
3533 ;; When source and destination does not overlap, clear destination
3534 ;; first and then do the movb
3536 [(set (match_operand:SWI24 0 "register_operand" "")
3537 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3538 (clobber (reg:CC FLAGS_REG))]
3540 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3541 && ANY_QI_REG_P (operands[0])
3542 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3543 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3544 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3546 operands[2] = gen_lowpart (QImode, operands[0]);
3547 ix86_expand_clear (operands[0]);
3550 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3551 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3552 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3553 (clobber (reg:CC FLAGS_REG))]
3554 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3556 [(set_attr "type" "imovx,alu1")
3557 (set_attr "mode" "<MODE>")])
3559 ;; For the movzbl case strip only the clobber
3561 [(set (match_operand:SWI24 0 "register_operand" "")
3562 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3563 (clobber (reg:CC FLAGS_REG))]
3565 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3566 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3568 (zero_extend:SWI24 (match_dup 1)))])
3570 ; zero extend to SImode to avoid partial register stalls
3571 (define_insn "*zero_extendqi<mode>2_movzbl"
3572 [(set (match_operand:SWI24 0 "register_operand" "=r")
3573 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3575 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3576 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3577 [(set_attr "type" "imovx")
3578 (set_attr "mode" "SI")])
3580 ;; Rest is handled by single and.
3582 [(set (match_operand:SWI24 0 "register_operand" "")
3583 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3584 (clobber (reg:CC FLAGS_REG))]
3586 && true_regnum (operands[0]) == true_regnum (operands[1])"
3587 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3588 (clobber (reg:CC FLAGS_REG))])])
3590 ;; Sign extension instructions
3592 (define_expand "extendsidi2"
3593 [(set (match_operand:DI 0 "register_operand" "")
3594 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3599 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3604 (define_insn "*extendsidi2_rex64"
3605 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3606 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3610 movs{lq|x}\t{%1, %0|%0, %1}"
3611 [(set_attr "type" "imovx")
3612 (set_attr "mode" "DI")
3613 (set_attr "prefix_0f" "0")
3614 (set_attr "modrm" "0,1")])
3616 (define_insn "extendsidi2_1"
3617 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3618 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3619 (clobber (reg:CC FLAGS_REG))
3620 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3624 ;; Extend to memory case when source register does die.
3626 [(set (match_operand:DI 0 "memory_operand" "")
3627 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3628 (clobber (reg:CC FLAGS_REG))
3629 (clobber (match_operand:SI 2 "register_operand" ""))]
3631 && dead_or_set_p (insn, operands[1])
3632 && !reg_mentioned_p (operands[1], operands[0]))"
3633 [(set (match_dup 3) (match_dup 1))
3634 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3635 (clobber (reg:CC FLAGS_REG))])
3636 (set (match_dup 4) (match_dup 1))]
3637 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3639 ;; Extend to memory case when source register does not die.
3641 [(set (match_operand:DI 0 "memory_operand" "")
3642 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3643 (clobber (reg:CC FLAGS_REG))
3644 (clobber (match_operand:SI 2 "register_operand" ""))]
3648 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3650 emit_move_insn (operands[3], operands[1]);
3652 /* Generate a cltd if possible and doing so it profitable. */
3653 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3654 && true_regnum (operands[1]) == AX_REG
3655 && true_regnum (operands[2]) == DX_REG)
3657 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3661 emit_move_insn (operands[2], operands[1]);
3662 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3664 emit_move_insn (operands[4], operands[2]);
3668 ;; Extend to register case. Optimize case where source and destination
3669 ;; registers match and cases where we can use cltd.
3671 [(set (match_operand:DI 0 "register_operand" "")
3672 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3673 (clobber (reg:CC FLAGS_REG))
3674 (clobber (match_scratch:SI 2 ""))]
3678 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3680 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3681 emit_move_insn (operands[3], operands[1]);
3683 /* Generate a cltd if possible and doing so it profitable. */
3684 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3685 && true_regnum (operands[3]) == AX_REG
3686 && true_regnum (operands[4]) == DX_REG)
3688 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3692 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3693 emit_move_insn (operands[4], operands[1]);
3695 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3699 (define_insn "extend<mode>di2"
3700 [(set (match_operand:DI 0 "register_operand" "=r")
3702 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3704 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3705 [(set_attr "type" "imovx")
3706 (set_attr "mode" "DI")])
3708 (define_insn "extendhisi2"
3709 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3710 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3713 switch (get_attr_prefix_0f (insn))
3716 return "{cwtl|cwde}";
3718 return "movs{wl|x}\t{%1, %0|%0, %1}";
3721 [(set_attr "type" "imovx")
3722 (set_attr "mode" "SI")
3723 (set (attr "prefix_0f")
3724 ;; movsx is short decodable while cwtl is vector decoded.
3725 (if_then_else (and (eq_attr "cpu" "!k6")
3726 (eq_attr "alternative" "0"))
3728 (const_string "1")))
3730 (if_then_else (eq_attr "prefix_0f" "0")
3732 (const_string "1")))])
3734 (define_insn "*extendhisi2_zext"
3735 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3738 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3741 switch (get_attr_prefix_0f (insn))
3744 return "{cwtl|cwde}";
3746 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3749 [(set_attr "type" "imovx")
3750 (set_attr "mode" "SI")
3751 (set (attr "prefix_0f")
3752 ;; movsx is short decodable while cwtl is vector decoded.
3753 (if_then_else (and (eq_attr "cpu" "!k6")
3754 (eq_attr "alternative" "0"))
3756 (const_string "1")))
3758 (if_then_else (eq_attr "prefix_0f" "0")
3760 (const_string "1")))])
3762 (define_insn "extendqisi2"
3763 [(set (match_operand:SI 0 "register_operand" "=r")
3764 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3766 "movs{bl|x}\t{%1, %0|%0, %1}"
3767 [(set_attr "type" "imovx")
3768 (set_attr "mode" "SI")])
3770 (define_insn "*extendqisi2_zext"
3771 [(set (match_operand:DI 0 "register_operand" "=r")
3773 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3775 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3776 [(set_attr "type" "imovx")
3777 (set_attr "mode" "SI")])
3779 (define_insn "extendqihi2"
3780 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3781 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3784 switch (get_attr_prefix_0f (insn))
3787 return "{cbtw|cbw}";
3789 return "movs{bw|x}\t{%1, %0|%0, %1}";
3792 [(set_attr "type" "imovx")
3793 (set_attr "mode" "HI")
3794 (set (attr "prefix_0f")
3795 ;; movsx is short decodable while cwtl is vector decoded.
3796 (if_then_else (and (eq_attr "cpu" "!k6")
3797 (eq_attr "alternative" "0"))
3799 (const_string "1")))
3801 (if_then_else (eq_attr "prefix_0f" "0")
3803 (const_string "1")))])
3805 ;; Conversions between float and double.
3807 ;; These are all no-ops in the model used for the 80387.
3808 ;; So just emit moves.
3810 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3812 [(set (match_operand:DF 0 "push_operand" "")
3813 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3815 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3816 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3819 [(set (match_operand:XF 0 "push_operand" "")
3820 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3822 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3823 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3824 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3826 (define_expand "extendsfdf2"
3827 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3828 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3829 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3831 /* ??? Needed for compress_float_constant since all fp constants
3832 are TARGET_LEGITIMATE_CONSTANT_P. */
3833 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3835 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3836 && standard_80387_constant_p (operands[1]) > 0)
3838 operands[1] = simplify_const_unary_operation
3839 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3840 emit_move_insn_1 (operands[0], operands[1]);
3843 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3847 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3849 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3851 We do the conversion post reload to avoid producing of 128bit spills
3852 that might lead to ICE on 32bit target. The sequence unlikely combine
3855 [(set (match_operand:DF 0 "register_operand" "")
3857 (match_operand:SF 1 "nonimmediate_operand" "")))]
3858 "TARGET_USE_VECTOR_FP_CONVERTS
3859 && optimize_insn_for_speed_p ()
3860 && reload_completed && SSE_REG_P (operands[0])"
3865 (parallel [(const_int 0) (const_int 1)]))))]
3867 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3868 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3869 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3870 Try to avoid move when unpacking can be done in source. */
3871 if (REG_P (operands[1]))
3873 /* If it is unsafe to overwrite upper half of source, we need
3874 to move to destination and unpack there. */
3875 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3876 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3877 && true_regnum (operands[0]) != true_regnum (operands[1]))
3879 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3880 emit_move_insn (tmp, operands[1]);
3883 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3884 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3888 emit_insn (gen_vec_setv4sf_0 (operands[3],
3889 CONST0_RTX (V4SFmode), operands[1]));
3892 (define_insn "*extendsfdf2_mixed"
3893 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3895 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3896 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3898 switch (which_alternative)
3902 return output_387_reg_move (insn, operands);
3905 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3911 [(set_attr "type" "fmov,fmov,ssecvt")
3912 (set_attr "prefix" "orig,orig,maybe_vex")
3913 (set_attr "mode" "SF,XF,DF")])
3915 (define_insn "*extendsfdf2_sse"
3916 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3917 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3918 "TARGET_SSE2 && TARGET_SSE_MATH"
3919 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3920 [(set_attr "type" "ssecvt")
3921 (set_attr "prefix" "maybe_vex")
3922 (set_attr "mode" "DF")])
3924 (define_insn "*extendsfdf2_i387"
3925 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3926 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3928 "* return output_387_reg_move (insn, operands);"
3929 [(set_attr "type" "fmov")
3930 (set_attr "mode" "SF,XF")])
3932 (define_expand "extend<mode>xf2"
3933 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3934 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3937 /* ??? Needed for compress_float_constant since all fp constants
3938 are TARGET_LEGITIMATE_CONSTANT_P. */
3939 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3941 if (standard_80387_constant_p (operands[1]) > 0)
3943 operands[1] = simplify_const_unary_operation
3944 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3945 emit_move_insn_1 (operands[0], operands[1]);
3948 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3952 (define_insn "*extend<mode>xf2_i387"
3953 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3955 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3957 "* return output_387_reg_move (insn, operands);"
3958 [(set_attr "type" "fmov")
3959 (set_attr "mode" "<MODE>,XF")])
3961 ;; %%% This seems bad bad news.
3962 ;; This cannot output into an f-reg because there is no way to be sure
3963 ;; of truncating in that case. Otherwise this is just like a simple move
3964 ;; insn. So we pretend we can output to a reg in order to get better
3965 ;; register preferencing, but we really use a stack slot.
3967 ;; Conversion from DFmode to SFmode.
3969 (define_expand "truncdfsf2"
3970 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3972 (match_operand:DF 1 "nonimmediate_operand" "")))]
3973 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3975 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3977 else if (flag_unsafe_math_optimizations)
3981 enum ix86_stack_slot slot = (virtuals_instantiated
3984 rtx temp = assign_386_stack_local (SFmode, slot);
3985 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3990 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3992 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3994 We do the conversion post reload to avoid producing of 128bit spills
3995 that might lead to ICE on 32bit target. The sequence unlikely combine
3998 [(set (match_operand:SF 0 "register_operand" "")
4000 (match_operand:DF 1 "nonimmediate_operand" "")))]
4001 "TARGET_USE_VECTOR_FP_CONVERTS
4002 && optimize_insn_for_speed_p ()
4003 && reload_completed && SSE_REG_P (operands[0])"
4006 (float_truncate:V2SF
4010 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4011 operands[3] = CONST0_RTX (V2SFmode);
4012 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4013 /* Use movsd for loading from memory, unpcklpd for registers.
4014 Try to avoid move when unpacking can be done in source, or SSE3
4015 movddup is available. */
4016 if (REG_P (operands[1]))
4019 && true_regnum (operands[0]) != true_regnum (operands[1])
4020 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4021 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4023 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4024 emit_move_insn (tmp, operands[1]);
4027 else if (!TARGET_SSE3)
4028 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4029 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4032 emit_insn (gen_sse2_loadlpd (operands[4],
4033 CONST0_RTX (V2DFmode), operands[1]));
4036 (define_expand "truncdfsf2_with_temp"
4037 [(parallel [(set (match_operand:SF 0 "" "")
4038 (float_truncate:SF (match_operand:DF 1 "" "")))
4039 (clobber (match_operand:SF 2 "" ""))])])
4041 (define_insn "*truncdfsf_fast_mixed"
4042 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4044 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4045 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4047 switch (which_alternative)
4050 return output_387_reg_move (insn, operands);
4052 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4057 [(set_attr "type" "fmov,ssecvt")
4058 (set_attr "prefix" "orig,maybe_vex")
4059 (set_attr "mode" "SF")])
4061 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4062 ;; because nothing we do here is unsafe.
4063 (define_insn "*truncdfsf_fast_sse"
4064 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4066 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4067 "TARGET_SSE2 && TARGET_SSE_MATH"
4068 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4069 [(set_attr "type" "ssecvt")
4070 (set_attr "prefix" "maybe_vex")
4071 (set_attr "mode" "SF")])
4073 (define_insn "*truncdfsf_fast_i387"
4074 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4076 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4077 "TARGET_80387 && flag_unsafe_math_optimizations"
4078 "* return output_387_reg_move (insn, operands);"
4079 [(set_attr "type" "fmov")
4080 (set_attr "mode" "SF")])
4082 (define_insn "*truncdfsf_mixed"
4083 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4085 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4086 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4087 "TARGET_MIX_SSE_I387"
4089 switch (which_alternative)
4092 return output_387_reg_move (insn, operands);
4094 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4100 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4101 (set_attr "unit" "*,*,i387,i387,i387")
4102 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4103 (set_attr "mode" "SF")])
4105 (define_insn "*truncdfsf_i387"
4106 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4108 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4109 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4112 switch (which_alternative)
4115 return output_387_reg_move (insn, operands);
4121 [(set_attr "type" "fmov,multi,multi,multi")
4122 (set_attr "unit" "*,i387,i387,i387")
4123 (set_attr "mode" "SF")])
4125 (define_insn "*truncdfsf2_i387_1"
4126 [(set (match_operand:SF 0 "memory_operand" "=m")
4128 (match_operand:DF 1 "register_operand" "f")))]
4130 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4131 && !TARGET_MIX_SSE_I387"
4132 "* return output_387_reg_move (insn, operands);"
4133 [(set_attr "type" "fmov")
4134 (set_attr "mode" "SF")])
4137 [(set (match_operand:SF 0 "register_operand" "")
4139 (match_operand:DF 1 "fp_register_operand" "")))
4140 (clobber (match_operand 2 "" ""))]
4142 [(set (match_dup 2) (match_dup 1))
4143 (set (match_dup 0) (match_dup 2))]
4144 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4146 ;; Conversion from XFmode to {SF,DF}mode
4148 (define_expand "truncxf<mode>2"
4149 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4150 (float_truncate:MODEF
4151 (match_operand:XF 1 "register_operand" "")))
4152 (clobber (match_dup 2))])]
4155 if (flag_unsafe_math_optimizations)
4157 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4158 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4159 if (reg != operands[0])
4160 emit_move_insn (operands[0], reg);
4165 enum ix86_stack_slot slot = (virtuals_instantiated
4168 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4172 (define_insn "*truncxfsf2_mixed"
4173 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4175 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4176 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4179 gcc_assert (!which_alternative);
4180 return output_387_reg_move (insn, operands);
4182 [(set_attr "type" "fmov,multi,multi,multi")
4183 (set_attr "unit" "*,i387,i387,i387")
4184 (set_attr "mode" "SF")])
4186 (define_insn "*truncxfdf2_mixed"
4187 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4189 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4190 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4193 gcc_assert (!which_alternative);
4194 return output_387_reg_move (insn, operands);
4196 [(set_attr "type" "fmov,multi,multi,multi")
4197 (set_attr "unit" "*,i387,i387,i387")
4198 (set_attr "mode" "DF")])
4200 (define_insn "truncxf<mode>2_i387_noop"
4201 [(set (match_operand:MODEF 0 "register_operand" "=f")
4202 (float_truncate:MODEF
4203 (match_operand:XF 1 "register_operand" "f")))]
4204 "TARGET_80387 && flag_unsafe_math_optimizations"
4205 "* return output_387_reg_move (insn, operands);"
4206 [(set_attr "type" "fmov")
4207 (set_attr "mode" "<MODE>")])
4209 (define_insn "*truncxf<mode>2_i387"
4210 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4211 (float_truncate:MODEF
4212 (match_operand:XF 1 "register_operand" "f")))]
4214 "* return output_387_reg_move (insn, operands);"
4215 [(set_attr "type" "fmov")
4216 (set_attr "mode" "<MODE>")])
4219 [(set (match_operand:MODEF 0 "register_operand" "")
4220 (float_truncate:MODEF
4221 (match_operand:XF 1 "register_operand" "")))
4222 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4223 "TARGET_80387 && reload_completed"
4224 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4225 (set (match_dup 0) (match_dup 2))])
4228 [(set (match_operand:MODEF 0 "memory_operand" "")
4229 (float_truncate:MODEF
4230 (match_operand:XF 1 "register_operand" "")))
4231 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4233 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4235 ;; Signed conversion to DImode.
4237 (define_expand "fix_truncxfdi2"
4238 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4239 (fix:DI (match_operand:XF 1 "register_operand" "")))
4240 (clobber (reg:CC FLAGS_REG))])]
4245 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4250 (define_expand "fix_trunc<mode>di2"
4251 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4252 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4253 (clobber (reg:CC FLAGS_REG))])]
4254 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4257 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4259 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4262 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4264 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4265 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4266 if (out != operands[0])
4267 emit_move_insn (operands[0], out);
4272 ;; Signed conversion to SImode.
4274 (define_expand "fix_truncxfsi2"
4275 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4276 (fix:SI (match_operand:XF 1 "register_operand" "")))
4277 (clobber (reg:CC FLAGS_REG))])]
4282 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4287 (define_expand "fix_trunc<mode>si2"
4288 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4289 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4290 (clobber (reg:CC FLAGS_REG))])]
4291 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4294 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4296 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4299 if (SSE_FLOAT_MODE_P (<MODE>mode))
4301 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4302 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4303 if (out != operands[0])
4304 emit_move_insn (operands[0], out);
4309 ;; Signed conversion to HImode.
4311 (define_expand "fix_trunc<mode>hi2"
4312 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4313 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4314 (clobber (reg:CC FLAGS_REG))])]
4316 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4320 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4325 ;; Unsigned conversion to SImode.
4327 (define_expand "fixuns_trunc<mode>si2"
4329 [(set (match_operand:SI 0 "register_operand" "")
4331 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4333 (clobber (match_scratch:<ssevecmode> 3 ""))
4334 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4335 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4337 enum machine_mode mode = <MODE>mode;
4338 enum machine_mode vecmode = <ssevecmode>mode;
4339 REAL_VALUE_TYPE TWO31r;
4342 if (optimize_insn_for_size_p ())
4345 real_ldexp (&TWO31r, &dconst1, 31);
4346 two31 = const_double_from_real_value (TWO31r, mode);
4347 two31 = ix86_build_const_vector (vecmode, true, two31);
4348 operands[2] = force_reg (vecmode, two31);
4351 (define_insn_and_split "*fixuns_trunc<mode>_1"
4352 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4354 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4355 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4356 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4357 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4358 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4359 && optimize_function_for_speed_p (cfun)"
4361 "&& reload_completed"
4364 ix86_split_convert_uns_si_sse (operands);
4368 ;; Unsigned conversion to HImode.
4369 ;; Without these patterns, we'll try the unsigned SI conversion which
4370 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4372 (define_expand "fixuns_trunc<mode>hi2"
4374 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4375 (set (match_operand:HI 0 "nonimmediate_operand" "")
4376 (subreg:HI (match_dup 2) 0))]
4377 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4378 "operands[2] = gen_reg_rtx (SImode);")
4380 ;; When SSE is available, it is always faster to use it!
4381 (define_insn "fix_trunc<mode>di_sse"
4382 [(set (match_operand:DI 0 "register_operand" "=r,r")
4383 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4384 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4385 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4386 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4387 [(set_attr "type" "sseicvt")
4388 (set_attr "prefix" "maybe_vex")
4389 (set_attr "prefix_rex" "1")
4390 (set_attr "mode" "<MODE>")
4391 (set_attr "athlon_decode" "double,vector")
4392 (set_attr "amdfam10_decode" "double,double")
4393 (set_attr "bdver1_decode" "double,double")])
4395 (define_insn "fix_trunc<mode>si_sse"
4396 [(set (match_operand:SI 0 "register_operand" "=r,r")
4397 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4398 "SSE_FLOAT_MODE_P (<MODE>mode)
4399 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4400 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4401 [(set_attr "type" "sseicvt")
4402 (set_attr "prefix" "maybe_vex")
4403 (set_attr "mode" "<MODE>")
4404 (set_attr "athlon_decode" "double,vector")
4405 (set_attr "amdfam10_decode" "double,double")
4406 (set_attr "bdver1_decode" "double,double")])
4408 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4410 [(set (match_operand:MODEF 0 "register_operand" "")
4411 (match_operand:MODEF 1 "memory_operand" ""))
4412 (set (match_operand:SWI48x 2 "register_operand" "")
4413 (fix:SWI48x (match_dup 0)))]
4414 "TARGET_SHORTEN_X87_SSE
4415 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4416 && peep2_reg_dead_p (2, operands[0])"
4417 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4419 ;; Avoid vector decoded forms of the instruction.
4421 [(match_scratch:DF 2 "Y2")
4422 (set (match_operand:SWI48x 0 "register_operand" "")
4423 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4424 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4425 [(set (match_dup 2) (match_dup 1))
4426 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4429 [(match_scratch:SF 2 "x")
4430 (set (match_operand:SWI48x 0 "register_operand" "")
4431 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4432 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4433 [(set (match_dup 2) (match_dup 1))
4434 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4436 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4437 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4438 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4439 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4441 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4442 && (TARGET_64BIT || <MODE>mode != DImode))
4444 && can_create_pseudo_p ()"
4449 if (memory_operand (operands[0], VOIDmode))
4450 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4453 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4454 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4460 [(set_attr "type" "fisttp")
4461 (set_attr "mode" "<MODE>")])
4463 (define_insn "fix_trunc<mode>_i387_fisttp"
4464 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4465 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4466 (clobber (match_scratch:XF 2 "=&1f"))]
4467 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4469 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4470 && (TARGET_64BIT || <MODE>mode != DImode))
4471 && TARGET_SSE_MATH)"
4472 "* return output_fix_trunc (insn, operands, true);"
4473 [(set_attr "type" "fisttp")
4474 (set_attr "mode" "<MODE>")])
4476 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4477 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4478 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4479 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4480 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4481 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4483 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4484 && (TARGET_64BIT || <MODE>mode != DImode))
4485 && TARGET_SSE_MATH)"
4487 [(set_attr "type" "fisttp")
4488 (set_attr "mode" "<MODE>")])
4491 [(set (match_operand:SWI248x 0 "register_operand" "")
4492 (fix:SWI248x (match_operand 1 "register_operand" "")))
4493 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4494 (clobber (match_scratch 3 ""))]
4496 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4497 (clobber (match_dup 3))])
4498 (set (match_dup 0) (match_dup 2))])
4501 [(set (match_operand:SWI248x 0 "memory_operand" "")
4502 (fix:SWI248x (match_operand 1 "register_operand" "")))
4503 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4504 (clobber (match_scratch 3 ""))]
4506 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4507 (clobber (match_dup 3))])])
4509 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4510 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4511 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4512 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4513 ;; function in i386.c.
4514 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4515 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4516 (fix:SWI248x (match_operand 1 "register_operand" "")))
4517 (clobber (reg:CC FLAGS_REG))]
4518 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4520 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4521 && (TARGET_64BIT || <MODE>mode != DImode))
4522 && can_create_pseudo_p ()"
4527 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4529 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4530 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4531 if (memory_operand (operands[0], VOIDmode))
4532 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4533 operands[2], operands[3]));
4536 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4537 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4538 operands[2], operands[3],
4543 [(set_attr "type" "fistp")
4544 (set_attr "i387_cw" "trunc")
4545 (set_attr "mode" "<MODE>")])
4547 (define_insn "fix_truncdi_i387"
4548 [(set (match_operand:DI 0 "memory_operand" "=m")
4549 (fix:DI (match_operand 1 "register_operand" "f")))
4550 (use (match_operand:HI 2 "memory_operand" "m"))
4551 (use (match_operand:HI 3 "memory_operand" "m"))
4552 (clobber (match_scratch:XF 4 "=&1f"))]
4553 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4555 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4556 "* return output_fix_trunc (insn, operands, false);"
4557 [(set_attr "type" "fistp")
4558 (set_attr "i387_cw" "trunc")
4559 (set_attr "mode" "DI")])
4561 (define_insn "fix_truncdi_i387_with_temp"
4562 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4563 (fix:DI (match_operand 1 "register_operand" "f,f")))
4564 (use (match_operand:HI 2 "memory_operand" "m,m"))
4565 (use (match_operand:HI 3 "memory_operand" "m,m"))
4566 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4567 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4568 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4570 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4572 [(set_attr "type" "fistp")
4573 (set_attr "i387_cw" "trunc")
4574 (set_attr "mode" "DI")])
4577 [(set (match_operand:DI 0 "register_operand" "")
4578 (fix:DI (match_operand 1 "register_operand" "")))
4579 (use (match_operand:HI 2 "memory_operand" ""))
4580 (use (match_operand:HI 3 "memory_operand" ""))
4581 (clobber (match_operand:DI 4 "memory_operand" ""))
4582 (clobber (match_scratch 5 ""))]
4584 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4587 (clobber (match_dup 5))])
4588 (set (match_dup 0) (match_dup 4))])
4591 [(set (match_operand:DI 0 "memory_operand" "")
4592 (fix:DI (match_operand 1 "register_operand" "")))
4593 (use (match_operand:HI 2 "memory_operand" ""))
4594 (use (match_operand:HI 3 "memory_operand" ""))
4595 (clobber (match_operand:DI 4 "memory_operand" ""))
4596 (clobber (match_scratch 5 ""))]
4598 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4601 (clobber (match_dup 5))])])
4603 (define_insn "fix_trunc<mode>_i387"
4604 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4605 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4606 (use (match_operand:HI 2 "memory_operand" "m"))
4607 (use (match_operand:HI 3 "memory_operand" "m"))]
4608 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4610 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4611 "* return output_fix_trunc (insn, operands, false);"
4612 [(set_attr "type" "fistp")
4613 (set_attr "i387_cw" "trunc")
4614 (set_attr "mode" "<MODE>")])
4616 (define_insn "fix_trunc<mode>_i387_with_temp"
4617 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4618 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4619 (use (match_operand:HI 2 "memory_operand" "m,m"))
4620 (use (match_operand:HI 3 "memory_operand" "m,m"))
4621 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4622 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4624 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4626 [(set_attr "type" "fistp")
4627 (set_attr "i387_cw" "trunc")
4628 (set_attr "mode" "<MODE>")])
4631 [(set (match_operand:SWI24 0 "register_operand" "")
4632 (fix:SWI24 (match_operand 1 "register_operand" "")))
4633 (use (match_operand:HI 2 "memory_operand" ""))
4634 (use (match_operand:HI 3 "memory_operand" ""))
4635 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4637 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4639 (use (match_dup 3))])
4640 (set (match_dup 0) (match_dup 4))])
4643 [(set (match_operand:SWI24 0 "memory_operand" "")
4644 (fix:SWI24 (match_operand 1 "register_operand" "")))
4645 (use (match_operand:HI 2 "memory_operand" ""))
4646 (use (match_operand:HI 3 "memory_operand" ""))
4647 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4649 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4651 (use (match_dup 3))])])
4653 (define_insn "x86_fnstcw_1"
4654 [(set (match_operand:HI 0 "memory_operand" "=m")
4655 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4658 [(set (attr "length")
4659 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4660 (set_attr "mode" "HI")
4661 (set_attr "unit" "i387")
4662 (set_attr "bdver1_decode" "vector")])
4664 (define_insn "x86_fldcw_1"
4665 [(set (reg:HI FPCR_REG)
4666 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4669 [(set (attr "length")
4670 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4671 (set_attr "mode" "HI")
4672 (set_attr "unit" "i387")
4673 (set_attr "athlon_decode" "vector")
4674 (set_attr "amdfam10_decode" "vector")
4675 (set_attr "bdver1_decode" "vector")])
4677 ;; Conversion between fixed point and floating point.
4679 ;; Even though we only accept memory inputs, the backend _really_
4680 ;; wants to be able to do this between registers.
4682 (define_expand "floathi<mode>2"
4683 [(set (match_operand:X87MODEF 0 "register_operand" "")
4684 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4687 || TARGET_MIX_SSE_I387)")
4689 ;; Pre-reload splitter to add memory clobber to the pattern.
4690 (define_insn_and_split "*floathi<mode>2_1"
4691 [(set (match_operand:X87MODEF 0 "register_operand" "")
4692 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4694 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4695 || TARGET_MIX_SSE_I387)
4696 && can_create_pseudo_p ()"
4699 [(parallel [(set (match_dup 0)
4700 (float:X87MODEF (match_dup 1)))
4701 (clobber (match_dup 2))])]
4702 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4704 (define_insn "*floathi<mode>2_i387_with_temp"
4705 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4706 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4707 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4709 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4710 || TARGET_MIX_SSE_I387)"
4712 [(set_attr "type" "fmov,multi")
4713 (set_attr "mode" "<MODE>")
4714 (set_attr "unit" "*,i387")
4715 (set_attr "fp_int_src" "true")])
4717 (define_insn "*floathi<mode>2_i387"
4718 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4719 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4722 || TARGET_MIX_SSE_I387)"
4724 [(set_attr "type" "fmov")
4725 (set_attr "mode" "<MODE>")
4726 (set_attr "fp_int_src" "true")])
4729 [(set (match_operand:X87MODEF 0 "register_operand" "")
4730 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4731 (clobber (match_operand:HI 2 "memory_operand" ""))]
4733 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4734 || TARGET_MIX_SSE_I387)
4735 && reload_completed"
4736 [(set (match_dup 2) (match_dup 1))
4737 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4740 [(set (match_operand:X87MODEF 0 "register_operand" "")
4741 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4742 (clobber (match_operand:HI 2 "memory_operand" ""))]
4744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4745 || TARGET_MIX_SSE_I387)
4746 && reload_completed"
4747 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4749 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4750 [(set (match_operand:X87MODEF 0 "register_operand" "")
4752 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4754 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4755 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4757 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4758 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4759 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4761 rtx reg = gen_reg_rtx (XFmode);
4762 rtx (*insn)(rtx, rtx);
4764 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4766 if (<X87MODEF:MODE>mode == SFmode)
4767 insn = gen_truncxfsf2;
4768 else if (<X87MODEF:MODE>mode == DFmode)
4769 insn = gen_truncxfdf2;
4773 emit_insn (insn (operands[0], reg));
4778 ;; Pre-reload splitter to add memory clobber to the pattern.
4779 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4780 [(set (match_operand:X87MODEF 0 "register_operand" "")
4781 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4783 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4784 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4785 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4786 || TARGET_MIX_SSE_I387))
4787 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4788 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4789 && ((<SWI48x:MODE>mode == SImode
4790 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4791 && optimize_function_for_speed_p (cfun)
4792 && flag_trapping_math)
4793 || !(TARGET_INTER_UNIT_CONVERSIONS
4794 || optimize_function_for_size_p (cfun)))))
4795 && can_create_pseudo_p ()"
4798 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4799 (clobber (match_dup 2))])]
4801 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4803 /* Avoid store forwarding (partial memory) stall penalty
4804 by passing DImode value through XMM registers. */
4805 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4806 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4807 && optimize_function_for_speed_p (cfun))
4809 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4816 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4817 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4819 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4820 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4821 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4822 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4824 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4825 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4826 (set_attr "unit" "*,i387,*,*,*")
4827 (set_attr "athlon_decode" "*,*,double,direct,double")
4828 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4829 (set_attr "bdver1_decode" "*,*,double,direct,double")
4830 (set_attr "fp_int_src" "true")])
4832 (define_insn "*floatsi<mode>2_vector_mixed"
4833 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4834 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4835 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4836 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4840 [(set_attr "type" "fmov,sseicvt")
4841 (set_attr "mode" "<MODE>,<ssevecmode>")
4842 (set_attr "unit" "i387,*")
4843 (set_attr "athlon_decode" "*,direct")
4844 (set_attr "amdfam10_decode" "*,double")
4845 (set_attr "bdver1_decode" "*,direct")
4846 (set_attr "fp_int_src" "true")])
4848 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4849 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4851 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4852 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4853 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4854 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4856 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4857 (set_attr "mode" "<MODEF:MODE>")
4858 (set_attr "unit" "*,i387,*,*")
4859 (set_attr "athlon_decode" "*,*,double,direct")
4860 (set_attr "amdfam10_decode" "*,*,vector,double")
4861 (set_attr "bdver1_decode" "*,*,double,direct")
4862 (set_attr "fp_int_src" "true")])
4865 [(set (match_operand:MODEF 0 "register_operand" "")
4866 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4867 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4868 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4869 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4870 && TARGET_INTER_UNIT_CONVERSIONS
4872 && (SSE_REG_P (operands[0])
4873 || (GET_CODE (operands[0]) == SUBREG
4874 && SSE_REG_P (operands[0])))"
4875 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4878 [(set (match_operand:MODEF 0 "register_operand" "")
4879 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4880 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4881 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4882 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4883 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4885 && (SSE_REG_P (operands[0])
4886 || (GET_CODE (operands[0]) == SUBREG
4887 && SSE_REG_P (operands[0])))"
4888 [(set (match_dup 2) (match_dup 1))
4889 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4891 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4892 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4894 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,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 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4902 [(set_attr "type" "fmov,sseicvt,sseicvt")
4903 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4904 (set_attr "mode" "<MODEF:MODE>")
4905 (set (attr "prefix_rex")
4907 (and (eq_attr "prefix" "maybe_vex")
4908 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4910 (const_string "*")))
4911 (set_attr "unit" "i387,*,*")
4912 (set_attr "athlon_decode" "*,double,direct")
4913 (set_attr "amdfam10_decode" "*,vector,double")
4914 (set_attr "bdver1_decode" "*,double,direct")
4915 (set_attr "fp_int_src" "true")])
4917 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4918 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4920 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4921 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4922 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4923 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4926 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4927 [(set_attr "type" "fmov,sseicvt")
4928 (set_attr "prefix" "orig,maybe_vex")
4929 (set_attr "mode" "<MODEF:MODE>")
4930 (set (attr "prefix_rex")
4932 (and (eq_attr "prefix" "maybe_vex")
4933 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4935 (const_string "*")))
4936 (set_attr "athlon_decode" "*,direct")
4937 (set_attr "amdfam10_decode" "*,double")
4938 (set_attr "bdver1_decode" "*,direct")
4939 (set_attr "fp_int_src" "true")])
4941 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4942 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4944 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4945 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4946 "TARGET_SSE2 && TARGET_SSE_MATH
4947 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4949 [(set_attr "type" "sseicvt")
4950 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4951 (set_attr "athlon_decode" "double,direct,double")
4952 (set_attr "amdfam10_decode" "vector,double,double")
4953 (set_attr "bdver1_decode" "double,direct,double")
4954 (set_attr "fp_int_src" "true")])
4956 (define_insn "*floatsi<mode>2_vector_sse"
4957 [(set (match_operand:MODEF 0 "register_operand" "=x")
4958 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4959 "TARGET_SSE2 && TARGET_SSE_MATH
4960 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4962 [(set_attr "type" "sseicvt")
4963 (set_attr "mode" "<MODE>")
4964 (set_attr "athlon_decode" "direct")
4965 (set_attr "amdfam10_decode" "double")
4966 (set_attr "bdver1_decode" "direct")
4967 (set_attr "fp_int_src" "true")])
4970 [(set (match_operand:MODEF 0 "register_operand" "")
4971 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4972 (clobber (match_operand:SI 2 "memory_operand" ""))]
4973 "TARGET_SSE2 && TARGET_SSE_MATH
4974 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4976 && (SSE_REG_P (operands[0])
4977 || (GET_CODE (operands[0]) == SUBREG
4978 && SSE_REG_P (operands[0])))"
4981 rtx op1 = operands[1];
4983 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4985 if (GET_CODE (op1) == SUBREG)
4986 op1 = SUBREG_REG (op1);
4988 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4990 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4991 emit_insn (gen_sse2_loadld (operands[4],
4992 CONST0_RTX (V4SImode), operands[1]));
4994 /* We can ignore possible trapping value in the
4995 high part of SSE register for non-trapping math. */
4996 else if (SSE_REG_P (op1) && !flag_trapping_math)
4997 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5000 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5001 emit_move_insn (operands[2], operands[1]);
5002 emit_insn (gen_sse2_loadld (operands[4],
5003 CONST0_RTX (V4SImode), operands[2]));
5006 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5011 [(set (match_operand:MODEF 0 "register_operand" "")
5012 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5013 (clobber (match_operand:SI 2 "memory_operand" ""))]
5014 "TARGET_SSE2 && TARGET_SSE_MATH
5015 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5017 && (SSE_REG_P (operands[0])
5018 || (GET_CODE (operands[0]) == SUBREG
5019 && SSE_REG_P (operands[0])))"
5022 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5024 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5026 emit_insn (gen_sse2_loadld (operands[4],
5027 CONST0_RTX (V4SImode), operands[1]));
5029 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5034 [(set (match_operand:MODEF 0 "register_operand" "")
5035 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5036 "TARGET_SSE2 && TARGET_SSE_MATH
5037 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5039 && (SSE_REG_P (operands[0])
5040 || (GET_CODE (operands[0]) == SUBREG
5041 && SSE_REG_P (operands[0])))"
5044 rtx op1 = operands[1];
5046 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5048 if (GET_CODE (op1) == SUBREG)
5049 op1 = SUBREG_REG (op1);
5051 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5053 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5054 emit_insn (gen_sse2_loadld (operands[4],
5055 CONST0_RTX (V4SImode), operands[1]));
5057 /* We can ignore possible trapping value in the
5058 high part of SSE register for non-trapping math. */
5059 else if (SSE_REG_P (op1) && !flag_trapping_math)
5060 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5064 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5069 [(set (match_operand:MODEF 0 "register_operand" "")
5070 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5071 "TARGET_SSE2 && TARGET_SSE_MATH
5072 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5074 && (SSE_REG_P (operands[0])
5075 || (GET_CODE (operands[0]) == SUBREG
5076 && SSE_REG_P (operands[0])))"
5079 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5081 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5083 emit_insn (gen_sse2_loadld (operands[4],
5084 CONST0_RTX (V4SImode), operands[1]));
5086 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5090 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5091 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5093 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5094 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5095 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5096 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5098 [(set_attr "type" "sseicvt")
5099 (set_attr "mode" "<MODEF:MODE>")
5100 (set_attr "athlon_decode" "double,direct")
5101 (set_attr "amdfam10_decode" "vector,double")
5102 (set_attr "bdver1_decode" "double,direct")
5103 (set_attr "fp_int_src" "true")])
5105 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5106 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5108 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5109 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5110 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5111 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5112 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5113 [(set_attr "type" "sseicvt")
5114 (set_attr "prefix" "maybe_vex")
5115 (set_attr "mode" "<MODEF:MODE>")
5116 (set (attr "prefix_rex")
5118 (and (eq_attr "prefix" "maybe_vex")
5119 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5121 (const_string "*")))
5122 (set_attr "athlon_decode" "double,direct")
5123 (set_attr "amdfam10_decode" "vector,double")
5124 (set_attr "bdver1_decode" "double,direct")
5125 (set_attr "fp_int_src" "true")])
5128 [(set (match_operand:MODEF 0 "register_operand" "")
5129 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5130 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5131 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5132 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5133 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5135 && (SSE_REG_P (operands[0])
5136 || (GET_CODE (operands[0]) == SUBREG
5137 && SSE_REG_P (operands[0])))"
5138 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5140 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5141 [(set (match_operand:MODEF 0 "register_operand" "=x")
5143 (match_operand:SWI48x 1 "memory_operand" "m")))]
5144 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5145 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5146 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5147 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5148 [(set_attr "type" "sseicvt")
5149 (set_attr "prefix" "maybe_vex")
5150 (set_attr "mode" "<MODEF:MODE>")
5151 (set (attr "prefix_rex")
5153 (and (eq_attr "prefix" "maybe_vex")
5154 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5156 (const_string "*")))
5157 (set_attr "athlon_decode" "direct")
5158 (set_attr "amdfam10_decode" "double")
5159 (set_attr "bdver1_decode" "direct")
5160 (set_attr "fp_int_src" "true")])
5163 [(set (match_operand:MODEF 0 "register_operand" "")
5164 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5165 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5166 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5167 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5168 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5170 && (SSE_REG_P (operands[0])
5171 || (GET_CODE (operands[0]) == SUBREG
5172 && SSE_REG_P (operands[0])))"
5173 [(set (match_dup 2) (match_dup 1))
5174 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5177 [(set (match_operand:MODEF 0 "register_operand" "")
5178 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5179 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5180 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5181 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5183 && (SSE_REG_P (operands[0])
5184 || (GET_CODE (operands[0]) == SUBREG
5185 && SSE_REG_P (operands[0])))"
5186 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5188 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5189 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5191 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5192 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5194 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5198 [(set_attr "type" "fmov,multi")
5199 (set_attr "mode" "<X87MODEF:MODE>")
5200 (set_attr "unit" "*,i387")
5201 (set_attr "fp_int_src" "true")])
5203 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5204 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5206 (match_operand:SWI48x 1 "memory_operand" "m")))]
5208 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5210 [(set_attr "type" "fmov")
5211 (set_attr "mode" "<X87MODEF:MODE>")
5212 (set_attr "fp_int_src" "true")])
5215 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5216 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5217 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5219 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5220 && reload_completed"
5221 [(set (match_dup 2) (match_dup 1))
5222 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5225 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5226 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5227 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5229 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5230 && reload_completed"
5231 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5233 ;; Avoid store forwarding (partial memory) stall penalty
5234 ;; by passing DImode value through XMM registers. */
5236 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5237 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5239 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5240 (clobber (match_scratch:V4SI 3 "=X,x"))
5241 (clobber (match_scratch:V4SI 4 "=X,x"))
5242 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5243 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5244 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5245 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5247 [(set_attr "type" "multi")
5248 (set_attr "mode" "<X87MODEF:MODE>")
5249 (set_attr "unit" "i387")
5250 (set_attr "fp_int_src" "true")])
5253 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5254 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5255 (clobber (match_scratch:V4SI 3 ""))
5256 (clobber (match_scratch:V4SI 4 ""))
5257 (clobber (match_operand:DI 2 "memory_operand" ""))]
5258 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5259 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5260 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5261 && reload_completed"
5262 [(set (match_dup 2) (match_dup 3))
5263 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5265 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5266 Assemble the 64-bit DImode value in an xmm register. */
5267 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5268 gen_rtx_SUBREG (SImode, operands[1], 0)));
5269 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5270 gen_rtx_SUBREG (SImode, operands[1], 4)));
5271 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5274 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5278 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5279 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5280 (clobber (match_scratch:V4SI 3 ""))
5281 (clobber (match_scratch:V4SI 4 ""))
5282 (clobber (match_operand:DI 2 "memory_operand" ""))]
5283 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5284 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5285 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5286 && reload_completed"
5287 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5289 ;; Avoid store forwarding (partial memory) stall penalty by extending
5290 ;; SImode value to DImode through XMM register instead of pushing two
5291 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5292 ;; targets benefit from this optimization. Also note that fild
5293 ;; loads from memory only.
5295 (define_insn "*floatunssi<mode>2_1"
5296 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5297 (unsigned_float:X87MODEF
5298 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5299 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5300 (clobber (match_scratch:SI 3 "=X,x"))]
5302 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5305 [(set_attr "type" "multi")
5306 (set_attr "mode" "<MODE>")])
5309 [(set (match_operand:X87MODEF 0 "register_operand" "")
5310 (unsigned_float:X87MODEF
5311 (match_operand:SI 1 "register_operand" "")))
5312 (clobber (match_operand:DI 2 "memory_operand" ""))
5313 (clobber (match_scratch:SI 3 ""))]
5315 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5317 && reload_completed"
5318 [(set (match_dup 2) (match_dup 1))
5320 (float:X87MODEF (match_dup 2)))]
5321 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5324 [(set (match_operand:X87MODEF 0 "register_operand" "")
5325 (unsigned_float:X87MODEF
5326 (match_operand:SI 1 "memory_operand" "")))
5327 (clobber (match_operand:DI 2 "memory_operand" ""))
5328 (clobber (match_scratch:SI 3 ""))]
5330 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5332 && reload_completed"
5333 [(set (match_dup 2) (match_dup 3))
5335 (float:X87MODEF (match_dup 2)))]
5337 emit_move_insn (operands[3], operands[1]);
5338 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5341 (define_expand "floatunssi<mode>2"
5343 [(set (match_operand:X87MODEF 0 "register_operand" "")
5344 (unsigned_float:X87MODEF
5345 (match_operand:SI 1 "nonimmediate_operand" "")))
5346 (clobber (match_dup 2))
5347 (clobber (match_scratch:SI 3 ""))])]
5349 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5351 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5353 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5355 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5360 enum ix86_stack_slot slot = (virtuals_instantiated
5363 operands[2] = assign_386_stack_local (DImode, slot);
5367 (define_expand "floatunsdisf2"
5368 [(use (match_operand:SF 0 "register_operand" ""))
5369 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5370 "TARGET_64BIT && TARGET_SSE_MATH"
5371 "x86_emit_floatuns (operands); DONE;")
5373 (define_expand "floatunsdidf2"
5374 [(use (match_operand:DF 0 "register_operand" ""))
5375 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5376 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5377 && TARGET_SSE2 && TARGET_SSE_MATH"
5380 x86_emit_floatuns (operands);
5382 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5388 (define_expand "add<mode>3"
5389 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5390 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5391 (match_operand:SDWIM 2 "<general_operand>" "")))]
5393 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5395 (define_insn_and_split "*add<dwi>3_doubleword"
5396 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5398 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5399 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5400 (clobber (reg:CC FLAGS_REG))]
5401 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5404 [(parallel [(set (reg:CC FLAGS_REG)
5405 (unspec:CC [(match_dup 1) (match_dup 2)]
5408 (plus:DWIH (match_dup 1) (match_dup 2)))])
5409 (parallel [(set (match_dup 3)
5413 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5415 (clobber (reg:CC FLAGS_REG))])]
5416 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5418 (define_insn "*add<mode>3_cc"
5419 [(set (reg:CC FLAGS_REG)
5421 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5422 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5424 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5425 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5426 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5427 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5428 [(set_attr "type" "alu")
5429 (set_attr "mode" "<MODE>")])
5431 (define_insn "addqi3_cc"
5432 [(set (reg:CC FLAGS_REG)
5434 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5435 (match_operand:QI 2 "general_operand" "qn,qm")]
5437 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5438 (plus:QI (match_dup 1) (match_dup 2)))]
5439 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5440 "add{b}\t{%2, %0|%0, %2}"
5441 [(set_attr "type" "alu")
5442 (set_attr "mode" "QI")])
5444 (define_insn "*lea_1"
5445 [(set (match_operand:P 0 "register_operand" "=r")
5446 (match_operand:P 1 "no_seg_address_operand" "p"))]
5448 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5449 [(set_attr "type" "lea")
5450 (set_attr "mode" "<MODE>")])
5452 (define_insn "*lea_2"
5453 [(set (match_operand:SI 0 "register_operand" "=r")
5454 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5456 "lea{l}\t{%a1, %0|%0, %a1}"
5457 [(set_attr "type" "lea")
5458 (set_attr "mode" "SI")])
5460 (define_insn "*lea_2_zext"
5461 [(set (match_operand:DI 0 "register_operand" "=r")
5463 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5465 "lea{l}\t{%a1, %k0|%k0, %a1}"
5466 [(set_attr "type" "lea")
5467 (set_attr "mode" "SI")])
5469 (define_insn "*add<mode>_1"
5470 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5472 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5473 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5474 (clobber (reg:CC FLAGS_REG))]
5475 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5477 switch (get_attr_type (insn))
5483 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5484 if (operands[2] == const1_rtx)
5485 return "inc{<imodesuffix>}\t%0";
5488 gcc_assert (operands[2] == constm1_rtx);
5489 return "dec{<imodesuffix>}\t%0";
5493 /* For most processors, ADD is faster than LEA. This alternative
5494 was added to use ADD as much as possible. */
5495 if (which_alternative == 2)
5498 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5501 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5502 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5503 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5505 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5509 (cond [(eq_attr "alternative" "3")
5510 (const_string "lea")
5511 (match_operand:SWI48 2 "incdec_operand" "")
5512 (const_string "incdec")
5514 (const_string "alu")))
5515 (set (attr "length_immediate")
5517 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5519 (const_string "*")))
5520 (set_attr "mode" "<MODE>")])
5522 ;; It may seem that nonimmediate operand is proper one for operand 1.
5523 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5524 ;; we take care in ix86_binary_operator_ok to not allow two memory
5525 ;; operands so proper swapping will be done in reload. This allow
5526 ;; patterns constructed from addsi_1 to match.
5528 (define_insn "*addsi_1_zext"
5529 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5531 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5532 (match_operand:SI 2 "general_operand" "g,0,li"))))
5533 (clobber (reg:CC FLAGS_REG))]
5534 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5536 switch (get_attr_type (insn))
5542 if (operands[2] == const1_rtx)
5543 return "inc{l}\t%k0";
5546 gcc_assert (operands[2] == constm1_rtx);
5547 return "dec{l}\t%k0";
5551 /* For most processors, ADD is faster than LEA. This alternative
5552 was added to use ADD as much as possible. */
5553 if (which_alternative == 1)
5556 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5559 if (x86_maybe_negate_const_int (&operands[2], SImode))
5560 return "sub{l}\t{%2, %k0|%k0, %2}";
5562 return "add{l}\t{%2, %k0|%k0, %2}";
5566 (cond [(eq_attr "alternative" "2")
5567 (const_string "lea")
5568 (match_operand:SI 2 "incdec_operand" "")
5569 (const_string "incdec")
5571 (const_string "alu")))
5572 (set (attr "length_immediate")
5574 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5576 (const_string "*")))
5577 (set_attr "mode" "SI")])
5579 (define_insn "*addhi_1"
5580 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5581 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5582 (match_operand:HI 2 "general_operand" "rn,rm")))
5583 (clobber (reg:CC FLAGS_REG))]
5584 "TARGET_PARTIAL_REG_STALL
5585 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5587 switch (get_attr_type (insn))
5590 if (operands[2] == const1_rtx)
5591 return "inc{w}\t%0";
5594 gcc_assert (operands[2] == constm1_rtx);
5595 return "dec{w}\t%0";
5599 if (x86_maybe_negate_const_int (&operands[2], HImode))
5600 return "sub{w}\t{%2, %0|%0, %2}";
5602 return "add{w}\t{%2, %0|%0, %2}";
5606 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5607 (const_string "incdec")
5608 (const_string "alu")))
5609 (set (attr "length_immediate")
5611 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5613 (const_string "*")))
5614 (set_attr "mode" "HI")])
5616 (define_insn "*addhi_1_lea"
5617 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5618 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5619 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5620 (clobber (reg:CC FLAGS_REG))]
5621 "!TARGET_PARTIAL_REG_STALL
5622 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5624 switch (get_attr_type (insn))
5630 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5631 if (operands[2] == const1_rtx)
5632 return "inc{w}\t%0";
5635 gcc_assert (operands[2] == constm1_rtx);
5636 return "dec{w}\t%0";
5640 /* For most processors, ADD is faster than LEA. This alternative
5641 was added to use ADD as much as possible. */
5642 if (which_alternative == 2)
5645 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5648 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5649 if (x86_maybe_negate_const_int (&operands[2], HImode))
5650 return "sub{w}\t{%2, %0|%0, %2}";
5652 return "add{w}\t{%2, %0|%0, %2}";
5656 (cond [(eq_attr "alternative" "3")
5657 (const_string "lea")
5658 (match_operand:HI 2 "incdec_operand" "")
5659 (const_string "incdec")
5661 (const_string "alu")))
5662 (set (attr "length_immediate")
5664 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5666 (const_string "*")))
5667 (set_attr "mode" "HI,HI,HI,SI")])
5669 ;; %%% Potential partial reg stall on alternative 2. What to do?
5670 (define_insn "*addqi_1"
5671 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5672 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5673 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5674 (clobber (reg:CC FLAGS_REG))]
5675 "TARGET_PARTIAL_REG_STALL
5676 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5678 int widen = (which_alternative == 2);
5679 switch (get_attr_type (insn))
5682 if (operands[2] == const1_rtx)
5683 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5686 gcc_assert (operands[2] == constm1_rtx);
5687 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5691 if (x86_maybe_negate_const_int (&operands[2], QImode))
5694 return "sub{l}\t{%2, %k0|%k0, %2}";
5696 return "sub{b}\t{%2, %0|%0, %2}";
5699 return "add{l}\t{%k2, %k0|%k0, %k2}";
5701 return "add{b}\t{%2, %0|%0, %2}";
5705 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5706 (const_string "incdec")
5707 (const_string "alu")))
5708 (set (attr "length_immediate")
5710 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5712 (const_string "*")))
5713 (set_attr "mode" "QI,QI,SI")])
5715 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5716 (define_insn "*addqi_1_lea"
5717 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5718 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5719 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5720 (clobber (reg:CC FLAGS_REG))]
5721 "!TARGET_PARTIAL_REG_STALL
5722 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5724 int widen = (which_alternative == 3 || which_alternative == 4);
5726 switch (get_attr_type (insn))
5732 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5733 if (operands[2] == const1_rtx)
5734 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5737 gcc_assert (operands[2] == constm1_rtx);
5738 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5742 /* For most processors, ADD is faster than LEA. These alternatives
5743 were added to use ADD as much as possible. */
5744 if (which_alternative == 2 || which_alternative == 4)
5747 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5750 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5751 if (x86_maybe_negate_const_int (&operands[2], QImode))
5754 return "sub{l}\t{%2, %k0|%k0, %2}";
5756 return "sub{b}\t{%2, %0|%0, %2}";
5759 return "add{l}\t{%k2, %k0|%k0, %k2}";
5761 return "add{b}\t{%2, %0|%0, %2}";
5765 (cond [(eq_attr "alternative" "5")
5766 (const_string "lea")
5767 (match_operand:QI 2 "incdec_operand" "")
5768 (const_string "incdec")
5770 (const_string "alu")))
5771 (set (attr "length_immediate")
5773 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5775 (const_string "*")))
5776 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5778 (define_insn "*addqi_1_slp"
5779 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5780 (plus:QI (match_dup 0)
5781 (match_operand:QI 1 "general_operand" "qn,qnm")))
5782 (clobber (reg:CC FLAGS_REG))]
5783 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5784 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5786 switch (get_attr_type (insn))
5789 if (operands[1] == const1_rtx)
5790 return "inc{b}\t%0";
5793 gcc_assert (operands[1] == constm1_rtx);
5794 return "dec{b}\t%0";
5798 if (x86_maybe_negate_const_int (&operands[1], QImode))
5799 return "sub{b}\t{%1, %0|%0, %1}";
5801 return "add{b}\t{%1, %0|%0, %1}";
5805 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5806 (const_string "incdec")
5807 (const_string "alu1")))
5808 (set (attr "memory")
5809 (if_then_else (match_operand 1 "memory_operand" "")
5810 (const_string "load")
5811 (const_string "none")))
5812 (set_attr "mode" "QI")])
5814 ;; Convert lea to the lea pattern to avoid flags dependency.
5816 [(set (match_operand 0 "register_operand" "")
5817 (plus (match_operand 1 "register_operand" "")
5818 (match_operand 2 "nonmemory_operand" "")))
5819 (clobber (reg:CC FLAGS_REG))]
5820 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5824 enum machine_mode mode = GET_MODE (operands[0]);
5826 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5827 may confuse gen_lowpart. */
5830 operands[1] = gen_lowpart (Pmode, operands[1]);
5831 operands[2] = gen_lowpart (Pmode, operands[2]);
5834 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5836 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5837 operands[0] = gen_lowpart (SImode, operands[0]);
5839 if (TARGET_64BIT && mode != Pmode)
5840 pat = gen_rtx_SUBREG (SImode, pat, 0);
5842 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5846 ;; Convert lea to the lea pattern to avoid flags dependency.
5847 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5848 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5850 [(set (match_operand:DI 0 "register_operand" "")
5851 (plus:DI (match_operand:DI 1 "register_operand" "")
5852 (match_operand:DI 2 "x86_64_immediate_operand" "")))
5853 (clobber (reg:CC FLAGS_REG))]
5854 "TARGET_64BIT && reload_completed
5855 && true_regnum (operands[0]) != true_regnum (operands[1])"
5857 (plus:DI (match_dup 1) (match_dup 2)))])
5859 ;; Convert lea to the lea pattern to avoid flags dependency.
5861 [(set (match_operand:DI 0 "register_operand" "")
5863 (plus:SI (match_operand:SI 1 "register_operand" "")
5864 (match_operand:SI 2 "nonmemory_operand" ""))))
5865 (clobber (reg:CC FLAGS_REG))]
5866 "TARGET_64BIT && reload_completed
5867 && ix86_lea_for_add_ok (insn, operands)"
5869 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5871 operands[1] = gen_lowpart (DImode, operands[1]);
5872 operands[2] = gen_lowpart (DImode, operands[2]);
5875 (define_insn "*add<mode>_2"
5876 [(set (reg FLAGS_REG)
5879 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5880 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5882 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5883 (plus:SWI (match_dup 1) (match_dup 2)))]
5884 "ix86_match_ccmode (insn, CCGOCmode)
5885 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5887 switch (get_attr_type (insn))
5890 if (operands[2] == const1_rtx)
5891 return "inc{<imodesuffix>}\t%0";
5894 gcc_assert (operands[2] == constm1_rtx);
5895 return "dec{<imodesuffix>}\t%0";
5899 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5900 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5902 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5906 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5907 (const_string "incdec")
5908 (const_string "alu")))
5909 (set (attr "length_immediate")
5911 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5913 (const_string "*")))
5914 (set_attr "mode" "<MODE>")])
5916 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5917 (define_insn "*addsi_2_zext"
5918 [(set (reg FLAGS_REG)
5920 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5921 (match_operand:SI 2 "general_operand" "g"))
5923 (set (match_operand:DI 0 "register_operand" "=r")
5924 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5925 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5926 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5928 switch (get_attr_type (insn))
5931 if (operands[2] == const1_rtx)
5932 return "inc{l}\t%k0";
5935 gcc_assert (operands[2] == constm1_rtx);
5936 return "dec{l}\t%k0";
5940 if (x86_maybe_negate_const_int (&operands[2], SImode))
5941 return "sub{l}\t{%2, %k0|%k0, %2}";
5943 return "add{l}\t{%2, %k0|%k0, %2}";
5947 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5948 (const_string "incdec")
5949 (const_string "alu")))
5950 (set (attr "length_immediate")
5952 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5954 (const_string "*")))
5955 (set_attr "mode" "SI")])
5957 (define_insn "*add<mode>_3"
5958 [(set (reg FLAGS_REG)
5960 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5961 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5962 (clobber (match_scratch:SWI 0 "=<r>"))]
5963 "ix86_match_ccmode (insn, CCZmode)
5964 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5966 switch (get_attr_type (insn))
5969 if (operands[2] == const1_rtx)
5970 return "inc{<imodesuffix>}\t%0";
5973 gcc_assert (operands[2] == constm1_rtx);
5974 return "dec{<imodesuffix>}\t%0";
5978 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5979 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5981 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5985 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5986 (const_string "incdec")
5987 (const_string "alu")))
5988 (set (attr "length_immediate")
5990 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5992 (const_string "*")))
5993 (set_attr "mode" "<MODE>")])
5995 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5996 (define_insn "*addsi_3_zext"
5997 [(set (reg FLAGS_REG)
5999 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6000 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6001 (set (match_operand:DI 0 "register_operand" "=r")
6002 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6003 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6004 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6006 switch (get_attr_type (insn))
6009 if (operands[2] == const1_rtx)
6010 return "inc{l}\t%k0";
6013 gcc_assert (operands[2] == constm1_rtx);
6014 return "dec{l}\t%k0";
6018 if (x86_maybe_negate_const_int (&operands[2], SImode))
6019 return "sub{l}\t{%2, %k0|%k0, %2}";
6021 return "add{l}\t{%2, %k0|%k0, %2}";
6025 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6026 (const_string "incdec")
6027 (const_string "alu")))
6028 (set (attr "length_immediate")
6030 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6032 (const_string "*")))
6033 (set_attr "mode" "SI")])
6035 ; For comparisons against 1, -1 and 128, we may generate better code
6036 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6037 ; is matched then. We can't accept general immediate, because for
6038 ; case of overflows, the result is messed up.
6039 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6040 ; only for comparisons not depending on it.
6042 (define_insn "*adddi_4"
6043 [(set (reg FLAGS_REG)
6045 (match_operand:DI 1 "nonimmediate_operand" "0")
6046 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6047 (clobber (match_scratch:DI 0 "=rm"))]
6049 && ix86_match_ccmode (insn, CCGCmode)"
6051 switch (get_attr_type (insn))
6054 if (operands[2] == constm1_rtx)
6055 return "inc{q}\t%0";
6058 gcc_assert (operands[2] == const1_rtx);
6059 return "dec{q}\t%0";
6063 if (x86_maybe_negate_const_int (&operands[2], DImode))
6064 return "add{q}\t{%2, %0|%0, %2}";
6066 return "sub{q}\t{%2, %0|%0, %2}";
6070 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6071 (const_string "incdec")
6072 (const_string "alu")))
6073 (set (attr "length_immediate")
6075 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6077 (const_string "*")))
6078 (set_attr "mode" "DI")])
6080 ; For comparisons against 1, -1 and 128, we may generate better code
6081 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6082 ; is matched then. We can't accept general immediate, because for
6083 ; case of overflows, the result is messed up.
6084 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6085 ; only for comparisons not depending on it.
6087 (define_insn "*add<mode>_4"
6088 [(set (reg FLAGS_REG)
6090 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6091 (match_operand:SWI124 2 "const_int_operand" "n")))
6092 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6093 "ix86_match_ccmode (insn, CCGCmode)"
6095 switch (get_attr_type (insn))
6098 if (operands[2] == constm1_rtx)
6099 return "inc{<imodesuffix>}\t%0";
6102 gcc_assert (operands[2] == const1_rtx);
6103 return "dec{<imodesuffix>}\t%0";
6107 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6108 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6110 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6114 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6115 (const_string "incdec")
6116 (const_string "alu")))
6117 (set (attr "length_immediate")
6119 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6121 (const_string "*")))
6122 (set_attr "mode" "<MODE>")])
6124 (define_insn "*add<mode>_5"
6125 [(set (reg FLAGS_REG)
6128 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6129 (match_operand:SWI 2 "<general_operand>" "<g>"))
6131 (clobber (match_scratch:SWI 0 "=<r>"))]
6132 "ix86_match_ccmode (insn, CCGOCmode)
6133 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6135 switch (get_attr_type (insn))
6138 if (operands[2] == const1_rtx)
6139 return "inc{<imodesuffix>}\t%0";
6142 gcc_assert (operands[2] == constm1_rtx);
6143 return "dec{<imodesuffix>}\t%0";
6147 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6148 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6150 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6154 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6155 (const_string "incdec")
6156 (const_string "alu")))
6157 (set (attr "length_immediate")
6159 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6161 (const_string "*")))
6162 (set_attr "mode" "<MODE>")])
6164 (define_insn "*addqi_ext_1_rex64"
6165 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6170 (match_operand 1 "ext_register_operand" "0")
6173 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6174 (clobber (reg:CC FLAGS_REG))]
6177 switch (get_attr_type (insn))
6180 if (operands[2] == const1_rtx)
6181 return "inc{b}\t%h0";
6184 gcc_assert (operands[2] == constm1_rtx);
6185 return "dec{b}\t%h0";
6189 return "add{b}\t{%2, %h0|%h0, %2}";
6193 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6194 (const_string "incdec")
6195 (const_string "alu")))
6196 (set_attr "modrm" "1")
6197 (set_attr "mode" "QI")])
6199 (define_insn "addqi_ext_1"
6200 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6205 (match_operand 1 "ext_register_operand" "0")
6208 (match_operand:QI 2 "general_operand" "Qmn")))
6209 (clobber (reg:CC FLAGS_REG))]
6212 switch (get_attr_type (insn))
6215 if (operands[2] == const1_rtx)
6216 return "inc{b}\t%h0";
6219 gcc_assert (operands[2] == constm1_rtx);
6220 return "dec{b}\t%h0";
6224 return "add{b}\t{%2, %h0|%h0, %2}";
6228 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6229 (const_string "incdec")
6230 (const_string "alu")))
6231 (set_attr "modrm" "1")
6232 (set_attr "mode" "QI")])
6234 (define_insn "*addqi_ext_2"
6235 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6240 (match_operand 1 "ext_register_operand" "%0")
6244 (match_operand 2 "ext_register_operand" "Q")
6247 (clobber (reg:CC FLAGS_REG))]
6249 "add{b}\t{%h2, %h0|%h0, %h2}"
6250 [(set_attr "type" "alu")
6251 (set_attr "mode" "QI")])
6253 ;; The lea patterns for non-Pmodes needs to be matched by
6254 ;; several insns converted to real lea by splitters.
6256 (define_insn_and_split "*lea_general_1"
6257 [(set (match_operand 0 "register_operand" "=r")
6258 (plus (plus (match_operand 1 "index_register_operand" "l")
6259 (match_operand 2 "register_operand" "r"))
6260 (match_operand 3 "immediate_operand" "i")))]
6261 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6262 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6263 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6264 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6265 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6266 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6267 || GET_MODE (operands[3]) == VOIDmode)"
6269 "&& reload_completed"
6273 operands[0] = gen_lowpart (SImode, operands[0]);
6274 operands[1] = gen_lowpart (Pmode, operands[1]);
6275 operands[2] = gen_lowpart (Pmode, operands[2]);
6276 operands[3] = gen_lowpart (Pmode, operands[3]);
6277 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6279 if (Pmode != SImode)
6280 pat = gen_rtx_SUBREG (SImode, pat, 0);
6281 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6284 [(set_attr "type" "lea")
6285 (set_attr "mode" "SI")])
6287 (define_insn_and_split "*lea_general_1_zext"
6288 [(set (match_operand:DI 0 "register_operand" "=r")
6291 (match_operand:SI 1 "index_register_operand" "l")
6292 (match_operand:SI 2 "register_operand" "r"))
6293 (match_operand:SI 3 "immediate_operand" "i"))))]
6296 "&& reload_completed"
6298 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6300 (match_dup 3)) 0)))]
6302 operands[1] = gen_lowpart (Pmode, operands[1]);
6303 operands[2] = gen_lowpart (Pmode, operands[2]);
6304 operands[3] = gen_lowpart (Pmode, operands[3]);
6306 [(set_attr "type" "lea")
6307 (set_attr "mode" "SI")])
6309 (define_insn_and_split "*lea_general_2"
6310 [(set (match_operand 0 "register_operand" "=r")
6311 (plus (mult (match_operand 1 "index_register_operand" "l")
6312 (match_operand 2 "const248_operand" "i"))
6313 (match_operand 3 "nonmemory_operand" "ri")))]
6314 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6315 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6316 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6317 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6318 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6319 || GET_MODE (operands[3]) == VOIDmode)"
6321 "&& reload_completed"
6325 operands[0] = gen_lowpart (SImode, operands[0]);
6326 operands[1] = gen_lowpart (Pmode, operands[1]);
6327 operands[3] = gen_lowpart (Pmode, operands[3]);
6328 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6330 if (Pmode != SImode)
6331 pat = gen_rtx_SUBREG (SImode, pat, 0);
6332 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6335 [(set_attr "type" "lea")
6336 (set_attr "mode" "SI")])
6338 (define_insn_and_split "*lea_general_2_zext"
6339 [(set (match_operand:DI 0 "register_operand" "=r")
6342 (match_operand:SI 1 "index_register_operand" "l")
6343 (match_operand:SI 2 "const248_operand" "n"))
6344 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6347 "&& reload_completed"
6349 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6351 (match_dup 3)) 0)))]
6353 operands[1] = gen_lowpart (Pmode, operands[1]);
6354 operands[3] = gen_lowpart (Pmode, operands[3]);
6356 [(set_attr "type" "lea")
6357 (set_attr "mode" "SI")])
6359 (define_insn_and_split "*lea_general_3"
6360 [(set (match_operand 0 "register_operand" "=r")
6361 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6362 (match_operand 2 "const248_operand" "i"))
6363 (match_operand 3 "register_operand" "r"))
6364 (match_operand 4 "immediate_operand" "i")))]
6365 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6366 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6367 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6368 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6369 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6371 "&& reload_completed"
6375 operands[0] = gen_lowpart (SImode, operands[0]);
6376 operands[1] = gen_lowpart (Pmode, operands[1]);
6377 operands[3] = gen_lowpart (Pmode, operands[3]);
6378 operands[4] = gen_lowpart (Pmode, operands[4]);
6379 pat = gen_rtx_PLUS (Pmode,
6380 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6384 if (Pmode != SImode)
6385 pat = gen_rtx_SUBREG (SImode, pat, 0);
6386 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6389 [(set_attr "type" "lea")
6390 (set_attr "mode" "SI")])
6392 (define_insn_and_split "*lea_general_3_zext"
6393 [(set (match_operand:DI 0 "register_operand" "=r")
6397 (match_operand:SI 1 "index_register_operand" "l")
6398 (match_operand:SI 2 "const248_operand" "n"))
6399 (match_operand:SI 3 "register_operand" "r"))
6400 (match_operand:SI 4 "immediate_operand" "i"))))]
6403 "&& reload_completed"
6405 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6408 (match_dup 4)) 0)))]
6410 operands[1] = gen_lowpart (Pmode, operands[1]);
6411 operands[3] = gen_lowpart (Pmode, operands[3]);
6412 operands[4] = gen_lowpart (Pmode, operands[4]);
6414 [(set_attr "type" "lea")
6415 (set_attr "mode" "SI")])
6417 ;; Subtract instructions
6419 (define_expand "sub<mode>3"
6420 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6421 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6422 (match_operand:SDWIM 2 "<general_operand>" "")))]
6424 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6426 (define_insn_and_split "*sub<dwi>3_doubleword"
6427 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6429 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6430 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6431 (clobber (reg:CC FLAGS_REG))]
6432 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6435 [(parallel [(set (reg:CC FLAGS_REG)
6436 (compare:CC (match_dup 1) (match_dup 2)))
6438 (minus:DWIH (match_dup 1) (match_dup 2)))])
6439 (parallel [(set (match_dup 3)
6443 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6445 (clobber (reg:CC FLAGS_REG))])]
6446 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6448 (define_insn "*sub<mode>_1"
6449 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6451 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6452 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6453 (clobber (reg:CC FLAGS_REG))]
6454 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6455 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6456 [(set_attr "type" "alu")
6457 (set_attr "mode" "<MODE>")])
6459 (define_insn "*subsi_1_zext"
6460 [(set (match_operand:DI 0 "register_operand" "=r")
6462 (minus:SI (match_operand:SI 1 "register_operand" "0")
6463 (match_operand:SI 2 "general_operand" "g"))))
6464 (clobber (reg:CC FLAGS_REG))]
6465 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6466 "sub{l}\t{%2, %k0|%k0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "SI")])
6470 (define_insn "*subqi_1_slp"
6471 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6472 (minus:QI (match_dup 0)
6473 (match_operand:QI 1 "general_operand" "qn,qm")))
6474 (clobber (reg:CC FLAGS_REG))]
6475 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6476 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6477 "sub{b}\t{%1, %0|%0, %1}"
6478 [(set_attr "type" "alu1")
6479 (set_attr "mode" "QI")])
6481 (define_insn "*sub<mode>_2"
6482 [(set (reg FLAGS_REG)
6485 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6486 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6488 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6489 (minus:SWI (match_dup 1) (match_dup 2)))]
6490 "ix86_match_ccmode (insn, CCGOCmode)
6491 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6492 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6493 [(set_attr "type" "alu")
6494 (set_attr "mode" "<MODE>")])
6496 (define_insn "*subsi_2_zext"
6497 [(set (reg FLAGS_REG)
6499 (minus:SI (match_operand:SI 1 "register_operand" "0")
6500 (match_operand:SI 2 "general_operand" "g"))
6502 (set (match_operand:DI 0 "register_operand" "=r")
6504 (minus:SI (match_dup 1)
6506 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6507 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6508 "sub{l}\t{%2, %k0|%k0, %2}"
6509 [(set_attr "type" "alu")
6510 (set_attr "mode" "SI")])
6512 (define_insn "*sub<mode>_3"
6513 [(set (reg FLAGS_REG)
6514 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6515 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6516 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6517 (minus:SWI (match_dup 1) (match_dup 2)))]
6518 "ix86_match_ccmode (insn, CCmode)
6519 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6520 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6521 [(set_attr "type" "alu")
6522 (set_attr "mode" "<MODE>")])
6524 (define_insn "*subsi_3_zext"
6525 [(set (reg FLAGS_REG)
6526 (compare (match_operand:SI 1 "register_operand" "0")
6527 (match_operand:SI 2 "general_operand" "g")))
6528 (set (match_operand:DI 0 "register_operand" "=r")
6530 (minus:SI (match_dup 1)
6532 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6533 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6534 "sub{l}\t{%2, %1|%1, %2}"
6535 [(set_attr "type" "alu")
6536 (set_attr "mode" "SI")])
6538 ;; Add with carry and subtract with borrow
6540 (define_expand "<plusminus_insn><mode>3_carry"
6542 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6544 (match_operand:SWI 1 "nonimmediate_operand" "")
6545 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6546 [(match_operand 3 "flags_reg_operand" "")
6548 (match_operand:SWI 2 "<general_operand>" ""))))
6549 (clobber (reg:CC FLAGS_REG))])]
6550 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6552 (define_insn "*<plusminus_insn><mode>3_carry"
6553 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6555 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6557 (match_operator 3 "ix86_carry_flag_operator"
6558 [(reg FLAGS_REG) (const_int 0)])
6559 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6560 (clobber (reg:CC FLAGS_REG))]
6561 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6562 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "use_carry" "1")
6565 (set_attr "pent_pair" "pu")
6566 (set_attr "mode" "<MODE>")])
6568 (define_insn "*addsi3_carry_zext"
6569 [(set (match_operand:DI 0 "register_operand" "=r")
6571 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6572 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6573 [(reg FLAGS_REG) (const_int 0)])
6574 (match_operand:SI 2 "general_operand" "g")))))
6575 (clobber (reg:CC FLAGS_REG))]
6576 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6577 "adc{l}\t{%2, %k0|%k0, %2}"
6578 [(set_attr "type" "alu")
6579 (set_attr "use_carry" "1")
6580 (set_attr "pent_pair" "pu")
6581 (set_attr "mode" "SI")])
6583 (define_insn "*subsi3_carry_zext"
6584 [(set (match_operand:DI 0 "register_operand" "=r")
6586 (minus:SI (match_operand:SI 1 "register_operand" "0")
6587 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6588 [(reg FLAGS_REG) (const_int 0)])
6589 (match_operand:SI 2 "general_operand" "g")))))
6590 (clobber (reg:CC FLAGS_REG))]
6591 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6592 "sbb{l}\t{%2, %k0|%k0, %2}"
6593 [(set_attr "type" "alu")
6594 (set_attr "pent_pair" "pu")
6595 (set_attr "mode" "SI")])
6597 ;; Overflow setting add and subtract instructions
6599 (define_insn "*add<mode>3_cconly_overflow"
6600 [(set (reg:CCC FLAGS_REG)
6603 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6604 (match_operand:SWI 2 "<general_operand>" "<g>"))
6606 (clobber (match_scratch:SWI 0 "=<r>"))]
6607 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6608 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "alu")
6610 (set_attr "mode" "<MODE>")])
6612 (define_insn "*sub<mode>3_cconly_overflow"
6613 [(set (reg:CCC FLAGS_REG)
6616 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6617 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6620 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6621 [(set_attr "type" "icmp")
6622 (set_attr "mode" "<MODE>")])
6624 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6625 [(set (reg:CCC FLAGS_REG)
6628 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6629 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6631 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6632 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6633 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6634 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6635 [(set_attr "type" "alu")
6636 (set_attr "mode" "<MODE>")])
6638 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6639 [(set (reg:CCC FLAGS_REG)
6642 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6643 (match_operand:SI 2 "general_operand" "g"))
6645 (set (match_operand:DI 0 "register_operand" "=r")
6646 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6647 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6648 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6649 [(set_attr "type" "alu")
6650 (set_attr "mode" "SI")])
6652 ;; The patterns that match these are at the end of this file.
6654 (define_expand "<plusminus_insn>xf3"
6655 [(set (match_operand:XF 0 "register_operand" "")
6657 (match_operand:XF 1 "register_operand" "")
6658 (match_operand:XF 2 "register_operand" "")))]
6661 (define_expand "<plusminus_insn><mode>3"
6662 [(set (match_operand:MODEF 0 "register_operand" "")
6664 (match_operand:MODEF 1 "register_operand" "")
6665 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6666 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6667 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6669 ;; Multiply instructions
6671 (define_expand "mul<mode>3"
6672 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6674 (match_operand:SWIM248 1 "register_operand" "")
6675 (match_operand:SWIM248 2 "<general_operand>" "")))
6676 (clobber (reg:CC FLAGS_REG))])])
6678 (define_expand "mulqi3"
6679 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6681 (match_operand:QI 1 "register_operand" "")
6682 (match_operand:QI 2 "nonimmediate_operand" "")))
6683 (clobber (reg:CC FLAGS_REG))])]
6684 "TARGET_QIMODE_MATH")
6687 ;; IMUL reg32/64, reg32/64, imm8 Direct
6688 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6689 ;; IMUL reg32/64, reg32/64, imm32 Direct
6690 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6691 ;; IMUL reg32/64, reg32/64 Direct
6692 ;; IMUL reg32/64, mem32/64 Direct
6694 ;; On BDVER1, all above IMULs use DirectPath
6696 (define_insn "*mul<mode>3_1"
6697 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6699 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6700 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6701 (clobber (reg:CC FLAGS_REG))]
6702 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6704 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6705 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6706 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6707 [(set_attr "type" "imul")
6708 (set_attr "prefix_0f" "0,0,1")
6709 (set (attr "athlon_decode")
6710 (cond [(eq_attr "cpu" "athlon")
6711 (const_string "vector")
6712 (eq_attr "alternative" "1")
6713 (const_string "vector")
6714 (and (eq_attr "alternative" "2")
6715 (match_operand 1 "memory_operand" ""))
6716 (const_string "vector")]
6717 (const_string "direct")))
6718 (set (attr "amdfam10_decode")
6719 (cond [(and (eq_attr "alternative" "0,1")
6720 (match_operand 1 "memory_operand" ""))
6721 (const_string "vector")]
6722 (const_string "direct")))
6723 (set_attr "bdver1_decode" "direct")
6724 (set_attr "mode" "<MODE>")])
6726 (define_insn "*mulsi3_1_zext"
6727 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6729 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6730 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6731 (clobber (reg:CC FLAGS_REG))]
6733 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6735 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6736 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6737 imul{l}\t{%2, %k0|%k0, %2}"
6738 [(set_attr "type" "imul")
6739 (set_attr "prefix_0f" "0,0,1")
6740 (set (attr "athlon_decode")
6741 (cond [(eq_attr "cpu" "athlon")
6742 (const_string "vector")
6743 (eq_attr "alternative" "1")
6744 (const_string "vector")
6745 (and (eq_attr "alternative" "2")
6746 (match_operand 1 "memory_operand" ""))
6747 (const_string "vector")]
6748 (const_string "direct")))
6749 (set (attr "amdfam10_decode")
6750 (cond [(and (eq_attr "alternative" "0,1")
6751 (match_operand 1 "memory_operand" ""))
6752 (const_string "vector")]
6753 (const_string "direct")))
6754 (set_attr "bdver1_decode" "direct")
6755 (set_attr "mode" "SI")])
6758 ;; IMUL reg16, reg16, imm8 VectorPath
6759 ;; IMUL reg16, mem16, imm8 VectorPath
6760 ;; IMUL reg16, reg16, imm16 VectorPath
6761 ;; IMUL reg16, mem16, imm16 VectorPath
6762 ;; IMUL reg16, reg16 Direct
6763 ;; IMUL reg16, mem16 Direct
6765 ;; On BDVER1, all HI MULs use DoublePath
6767 (define_insn "*mulhi3_1"
6768 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6769 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6770 (match_operand:HI 2 "general_operand" "K,n,mr")))
6771 (clobber (reg:CC FLAGS_REG))]
6773 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6775 imul{w}\t{%2, %1, %0|%0, %1, %2}
6776 imul{w}\t{%2, %1, %0|%0, %1, %2}
6777 imul{w}\t{%2, %0|%0, %2}"
6778 [(set_attr "type" "imul")
6779 (set_attr "prefix_0f" "0,0,1")
6780 (set (attr "athlon_decode")
6781 (cond [(eq_attr "cpu" "athlon")
6782 (const_string "vector")
6783 (eq_attr "alternative" "1,2")
6784 (const_string "vector")]
6785 (const_string "direct")))
6786 (set (attr "amdfam10_decode")
6787 (cond [(eq_attr "alternative" "0,1")
6788 (const_string "vector")]
6789 (const_string "direct")))
6790 (set_attr "bdver1_decode" "double")
6791 (set_attr "mode" "HI")])
6793 ;;On AMDFAM10 and BDVER1
6797 (define_insn "*mulqi3_1"
6798 [(set (match_operand:QI 0 "register_operand" "=a")
6799 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6800 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6801 (clobber (reg:CC FLAGS_REG))]
6803 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6805 [(set_attr "type" "imul")
6806 (set_attr "length_immediate" "0")
6807 (set (attr "athlon_decode")
6808 (if_then_else (eq_attr "cpu" "athlon")
6809 (const_string "vector")
6810 (const_string "direct")))
6811 (set_attr "amdfam10_decode" "direct")
6812 (set_attr "bdver1_decode" "direct")
6813 (set_attr "mode" "QI")])
6815 (define_expand "<u>mul<mode><dwi>3"
6816 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6819 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6821 (match_operand:DWIH 2 "register_operand" ""))))
6822 (clobber (reg:CC FLAGS_REG))])])
6824 (define_expand "<u>mulqihi3"
6825 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6828 (match_operand:QI 1 "nonimmediate_operand" ""))
6830 (match_operand:QI 2 "register_operand" ""))))
6831 (clobber (reg:CC FLAGS_REG))])]
6832 "TARGET_QIMODE_MATH")
6834 (define_insn "*<u>mul<mode><dwi>3_1"
6835 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6838 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6840 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6841 (clobber (reg:CC FLAGS_REG))]
6842 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6843 "<sgnprefix>mul{<imodesuffix>}\t%2"
6844 [(set_attr "type" "imul")
6845 (set_attr "length_immediate" "0")
6846 (set (attr "athlon_decode")
6847 (if_then_else (eq_attr "cpu" "athlon")
6848 (const_string "vector")
6849 (const_string "double")))
6850 (set_attr "amdfam10_decode" "double")
6851 (set_attr "bdver1_decode" "direct")
6852 (set_attr "mode" "<MODE>")])
6854 (define_insn "*<u>mulqihi3_1"
6855 [(set (match_operand:HI 0 "register_operand" "=a")
6858 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6860 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6861 (clobber (reg:CC FLAGS_REG))]
6863 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6864 "<sgnprefix>mul{b}\t%2"
6865 [(set_attr "type" "imul")
6866 (set_attr "length_immediate" "0")
6867 (set (attr "athlon_decode")
6868 (if_then_else (eq_attr "cpu" "athlon")
6869 (const_string "vector")
6870 (const_string "direct")))
6871 (set_attr "amdfam10_decode" "direct")
6872 (set_attr "bdver1_decode" "direct")
6873 (set_attr "mode" "QI")])
6875 (define_expand "<s>mul<mode>3_highpart"
6876 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6881 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6883 (match_operand:SWI48 2 "register_operand" "")))
6885 (clobber (match_scratch:SWI48 3 ""))
6886 (clobber (reg:CC FLAGS_REG))])]
6888 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6890 (define_insn "*<s>muldi3_highpart_1"
6891 [(set (match_operand:DI 0 "register_operand" "=d")
6896 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6898 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6900 (clobber (match_scratch:DI 3 "=1"))
6901 (clobber (reg:CC FLAGS_REG))]
6903 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6904 "<sgnprefix>mul{q}\t%2"
6905 [(set_attr "type" "imul")
6906 (set_attr "length_immediate" "0")
6907 (set (attr "athlon_decode")
6908 (if_then_else (eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (const_string "double")))
6911 (set_attr "amdfam10_decode" "double")
6912 (set_attr "bdver1_decode" "direct")
6913 (set_attr "mode" "DI")])
6915 (define_insn "*<s>mulsi3_highpart_1"
6916 [(set (match_operand:SI 0 "register_operand" "=d")
6921 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6923 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6925 (clobber (match_scratch:SI 3 "=1"))
6926 (clobber (reg:CC FLAGS_REG))]
6927 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928 "<sgnprefix>mul{l}\t%2"
6929 [(set_attr "type" "imul")
6930 (set_attr "length_immediate" "0")
6931 (set (attr "athlon_decode")
6932 (if_then_else (eq_attr "cpu" "athlon")
6933 (const_string "vector")
6934 (const_string "double")))
6935 (set_attr "amdfam10_decode" "double")
6936 (set_attr "bdver1_decode" "direct")
6937 (set_attr "mode" "SI")])
6939 (define_insn "*<s>mulsi3_highpart_zext"
6940 [(set (match_operand:DI 0 "register_operand" "=d")
6941 (zero_extend:DI (truncate:SI
6943 (mult:DI (any_extend:DI
6944 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6946 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6948 (clobber (match_scratch:SI 3 "=1"))
6949 (clobber (reg:CC FLAGS_REG))]
6951 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952 "<sgnprefix>mul{l}\t%2"
6953 [(set_attr "type" "imul")
6954 (set_attr "length_immediate" "0")
6955 (set (attr "athlon_decode")
6956 (if_then_else (eq_attr "cpu" "athlon")
6957 (const_string "vector")
6958 (const_string "double")))
6959 (set_attr "amdfam10_decode" "double")
6960 (set_attr "bdver1_decode" "direct")
6961 (set_attr "mode" "SI")])
6963 ;; The patterns that match these are at the end of this file.
6965 (define_expand "mulxf3"
6966 [(set (match_operand:XF 0 "register_operand" "")
6967 (mult:XF (match_operand:XF 1 "register_operand" "")
6968 (match_operand:XF 2 "register_operand" "")))]
6971 (define_expand "mul<mode>3"
6972 [(set (match_operand:MODEF 0 "register_operand" "")
6973 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6974 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6975 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6976 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6978 ;; Divide instructions
6980 ;; The patterns that match these are at the end of this file.
6982 (define_expand "divxf3"
6983 [(set (match_operand:XF 0 "register_operand" "")
6984 (div:XF (match_operand:XF 1 "register_operand" "")
6985 (match_operand:XF 2 "register_operand" "")))]
6988 (define_expand "divdf3"
6989 [(set (match_operand:DF 0 "register_operand" "")
6990 (div:DF (match_operand:DF 1 "register_operand" "")
6991 (match_operand:DF 2 "nonimmediate_operand" "")))]
6992 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6993 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6995 (define_expand "divsf3"
6996 [(set (match_operand:SF 0 "register_operand" "")
6997 (div:SF (match_operand:SF 1 "register_operand" "")
6998 (match_operand:SF 2 "nonimmediate_operand" "")))]
6999 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7002 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7003 && flag_finite_math_only && !flag_trapping_math
7004 && flag_unsafe_math_optimizations)
7006 ix86_emit_swdivsf (operands[0], operands[1],
7007 operands[2], SFmode);
7012 ;; Divmod instructions.
7014 (define_expand "divmod<mode>4"
7015 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7017 (match_operand:SWIM248 1 "register_operand" "")
7018 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7019 (set (match_operand:SWIM248 3 "register_operand" "")
7020 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7021 (clobber (reg:CC FLAGS_REG))])])
7023 ;; Split with 8bit unsigned divide:
7024 ;; if (dividend an divisor are in [0-255])
7025 ;; use 8bit unsigned integer divide
7027 ;; use original integer divide
7029 [(set (match_operand:SWI48 0 "register_operand" "")
7030 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7031 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7032 (set (match_operand:SWI48 1 "register_operand" "")
7033 (mod:SWI48 (match_dup 2) (match_dup 3)))
7034 (clobber (reg:CC FLAGS_REG))]
7035 "TARGET_USE_8BIT_IDIV
7036 && TARGET_QIMODE_MATH
7037 && can_create_pseudo_p ()
7038 && !optimize_insn_for_size_p ()"
7040 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7042 (define_insn_and_split "divmod<mode>4_1"
7043 [(set (match_operand:SWI48 0 "register_operand" "=a")
7044 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7045 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7046 (set (match_operand:SWI48 1 "register_operand" "=&d")
7047 (mod:SWI48 (match_dup 2) (match_dup 3)))
7048 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7049 (clobber (reg:CC FLAGS_REG))]
7053 [(parallel [(set (match_dup 1)
7054 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7055 (clobber (reg:CC FLAGS_REG))])
7056 (parallel [(set (match_dup 0)
7057 (div:SWI48 (match_dup 2) (match_dup 3)))
7059 (mod:SWI48 (match_dup 2) (match_dup 3)))
7061 (clobber (reg:CC FLAGS_REG))])]
7063 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7065 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7066 operands[4] = operands[2];
7069 /* Avoid use of cltd in favor of a mov+shift. */
7070 emit_move_insn (operands[1], operands[2]);
7071 operands[4] = operands[1];
7074 [(set_attr "type" "multi")
7075 (set_attr "mode" "<MODE>")])
7077 (define_insn_and_split "*divmod<mode>4"
7078 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7079 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7080 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7081 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7082 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7083 (clobber (reg:CC FLAGS_REG))]
7087 [(parallel [(set (match_dup 1)
7088 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7089 (clobber (reg:CC FLAGS_REG))])
7090 (parallel [(set (match_dup 0)
7091 (div:SWIM248 (match_dup 2) (match_dup 3)))
7093 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7095 (clobber (reg:CC FLAGS_REG))])]
7097 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7099 if (<MODE>mode != HImode
7100 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7101 operands[4] = operands[2];
7104 /* Avoid use of cltd in favor of a mov+shift. */
7105 emit_move_insn (operands[1], operands[2]);
7106 operands[4] = operands[1];
7109 [(set_attr "type" "multi")
7110 (set_attr "mode" "<MODE>")])
7112 (define_insn "*divmod<mode>4_noext"
7113 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7114 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7115 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7116 (set (match_operand:SWIM248 1 "register_operand" "=d")
7117 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7118 (use (match_operand:SWIM248 4 "register_operand" "1"))
7119 (clobber (reg:CC FLAGS_REG))]
7121 "idiv{<imodesuffix>}\t%3"
7122 [(set_attr "type" "idiv")
7123 (set_attr "mode" "<MODE>")])
7125 (define_expand "divmodqi4"
7126 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7128 (match_operand:QI 1 "register_operand" "")
7129 (match_operand:QI 2 "nonimmediate_operand" "")))
7130 (set (match_operand:QI 3 "register_operand" "")
7131 (mod:QI (match_dup 1) (match_dup 2)))
7132 (clobber (reg:CC FLAGS_REG))])]
7133 "TARGET_QIMODE_MATH"
7138 tmp0 = gen_reg_rtx (HImode);
7139 tmp1 = gen_reg_rtx (HImode);
7141 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7143 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7144 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7146 /* Extract remainder from AH. */
7147 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7148 insn = emit_move_insn (operands[3], tmp1);
7150 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7151 set_unique_reg_note (insn, REG_EQUAL, mod);
7153 /* Extract quotient from AL. */
7154 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7156 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7157 set_unique_reg_note (insn, REG_EQUAL, div);
7162 ;; Divide AX by r/m8, with result stored in
7165 ;; Change div/mod to HImode and extend the second argument to HImode
7166 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7167 ;; combine may fail.
7168 (define_insn "divmodhiqi3"
7169 [(set (match_operand:HI 0 "register_operand" "=a")
7174 (mod:HI (match_operand:HI 1 "register_operand" "0")
7176 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7180 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7181 (clobber (reg:CC FLAGS_REG))]
7182 "TARGET_QIMODE_MATH"
7184 [(set_attr "type" "idiv")
7185 (set_attr "mode" "QI")])
7187 (define_expand "udivmod<mode>4"
7188 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7190 (match_operand:SWIM248 1 "register_operand" "")
7191 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7192 (set (match_operand:SWIM248 3 "register_operand" "")
7193 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7194 (clobber (reg:CC FLAGS_REG))])])
7196 ;; Split with 8bit unsigned divide:
7197 ;; if (dividend an divisor are in [0-255])
7198 ;; use 8bit unsigned integer divide
7200 ;; use original integer divide
7202 [(set (match_operand:SWI48 0 "register_operand" "")
7203 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7204 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7205 (set (match_operand:SWI48 1 "register_operand" "")
7206 (umod:SWI48 (match_dup 2) (match_dup 3)))
7207 (clobber (reg:CC FLAGS_REG))]
7208 "TARGET_USE_8BIT_IDIV
7209 && TARGET_QIMODE_MATH
7210 && can_create_pseudo_p ()
7211 && !optimize_insn_for_size_p ()"
7213 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7215 (define_insn_and_split "udivmod<mode>4_1"
7216 [(set (match_operand:SWI48 0 "register_operand" "=a")
7217 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7218 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7219 (set (match_operand:SWI48 1 "register_operand" "=&d")
7220 (umod:SWI48 (match_dup 2) (match_dup 3)))
7221 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7222 (clobber (reg:CC FLAGS_REG))]
7226 [(set (match_dup 1) (const_int 0))
7227 (parallel [(set (match_dup 0)
7228 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7230 (umod:SWI48 (match_dup 2) (match_dup 3)))
7232 (clobber (reg:CC FLAGS_REG))])]
7234 [(set_attr "type" "multi")
7235 (set_attr "mode" "<MODE>")])
7237 (define_insn_and_split "*udivmod<mode>4"
7238 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7239 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7240 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7241 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7242 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7243 (clobber (reg:CC FLAGS_REG))]
7247 [(set (match_dup 1) (const_int 0))
7248 (parallel [(set (match_dup 0)
7249 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7251 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7253 (clobber (reg:CC FLAGS_REG))])]
7255 [(set_attr "type" "multi")
7256 (set_attr "mode" "<MODE>")])
7258 (define_insn "*udivmod<mode>4_noext"
7259 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7260 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7261 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7262 (set (match_operand:SWIM248 1 "register_operand" "=d")
7263 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7264 (use (match_operand:SWIM248 4 "register_operand" "1"))
7265 (clobber (reg:CC FLAGS_REG))]
7267 "div{<imodesuffix>}\t%3"
7268 [(set_attr "type" "idiv")
7269 (set_attr "mode" "<MODE>")])
7271 (define_expand "udivmodqi4"
7272 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7274 (match_operand:QI 1 "register_operand" "")
7275 (match_operand:QI 2 "nonimmediate_operand" "")))
7276 (set (match_operand:QI 3 "register_operand" "")
7277 (umod:QI (match_dup 1) (match_dup 2)))
7278 (clobber (reg:CC FLAGS_REG))])]
7279 "TARGET_QIMODE_MATH"
7284 tmp0 = gen_reg_rtx (HImode);
7285 tmp1 = gen_reg_rtx (HImode);
7287 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7289 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7290 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7292 /* Extract remainder from AH. */
7293 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7294 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7295 insn = emit_move_insn (operands[3], tmp1);
7297 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7298 set_unique_reg_note (insn, REG_EQUAL, mod);
7300 /* Extract quotient from AL. */
7301 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7303 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7304 set_unique_reg_note (insn, REG_EQUAL, div);
7309 (define_insn "udivmodhiqi3"
7310 [(set (match_operand:HI 0 "register_operand" "=a")
7315 (mod:HI (match_operand:HI 1 "register_operand" "0")
7317 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7321 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7322 (clobber (reg:CC FLAGS_REG))]
7323 "TARGET_QIMODE_MATH"
7325 [(set_attr "type" "idiv")
7326 (set_attr "mode" "QI")])
7328 ;; We cannot use div/idiv for double division, because it causes
7329 ;; "division by zero" on the overflow and that's not what we expect
7330 ;; from truncate. Because true (non truncating) double division is
7331 ;; never generated, we can't create this insn anyway.
7334 ; [(set (match_operand:SI 0 "register_operand" "=a")
7336 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7338 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7339 ; (set (match_operand:SI 3 "register_operand" "=d")
7341 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7342 ; (clobber (reg:CC FLAGS_REG))]
7344 ; "div{l}\t{%2, %0|%0, %2}"
7345 ; [(set_attr "type" "idiv")])
7347 ;;- Logical AND instructions
7349 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7350 ;; Note that this excludes ah.
7352 (define_expand "testsi_ccno_1"
7353 [(set (reg:CCNO FLAGS_REG)
7355 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7356 (match_operand:SI 1 "nonmemory_operand" ""))
7359 (define_expand "testqi_ccz_1"
7360 [(set (reg:CCZ FLAGS_REG)
7361 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7362 (match_operand:QI 1 "nonmemory_operand" ""))
7365 (define_expand "testdi_ccno_1"
7366 [(set (reg:CCNO FLAGS_REG)
7368 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7369 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7371 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7373 (define_insn "*testdi_1"
7374 [(set (reg FLAGS_REG)
7377 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7378 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7380 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7381 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7383 test{l}\t{%k1, %k0|%k0, %k1}
7384 test{l}\t{%k1, %k0|%k0, %k1}
7385 test{q}\t{%1, %0|%0, %1}
7386 test{q}\t{%1, %0|%0, %1}
7387 test{q}\t{%1, %0|%0, %1}"
7388 [(set_attr "type" "test")
7389 (set_attr "modrm" "0,1,0,1,1")
7390 (set_attr "mode" "SI,SI,DI,DI,DI")])
7392 (define_insn "*testqi_1_maybe_si"
7393 [(set (reg FLAGS_REG)
7396 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7397 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7399 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7400 && ix86_match_ccmode (insn,
7401 CONST_INT_P (operands[1])
7402 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7404 if (which_alternative == 3)
7406 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7407 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7408 return "test{l}\t{%1, %k0|%k0, %1}";
7410 return "test{b}\t{%1, %0|%0, %1}";
7412 [(set_attr "type" "test")
7413 (set_attr "modrm" "0,1,1,1")
7414 (set_attr "mode" "QI,QI,QI,SI")
7415 (set_attr "pent_pair" "uv,np,uv,np")])
7417 (define_insn "*test<mode>_1"
7418 [(set (reg FLAGS_REG)
7421 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7422 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7424 "ix86_match_ccmode (insn, CCNOmode)
7425 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7426 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7427 [(set_attr "type" "test")
7428 (set_attr "modrm" "0,1,1")
7429 (set_attr "mode" "<MODE>")
7430 (set_attr "pent_pair" "uv,np,uv")])
7432 (define_expand "testqi_ext_ccno_0"
7433 [(set (reg:CCNO FLAGS_REG)
7437 (match_operand 0 "ext_register_operand" "")
7440 (match_operand 1 "const_int_operand" ""))
7443 (define_insn "*testqi_ext_0"
7444 [(set (reg FLAGS_REG)
7448 (match_operand 0 "ext_register_operand" "Q")
7451 (match_operand 1 "const_int_operand" "n"))
7453 "ix86_match_ccmode (insn, CCNOmode)"
7454 "test{b}\t{%1, %h0|%h0, %1}"
7455 [(set_attr "type" "test")
7456 (set_attr "mode" "QI")
7457 (set_attr "length_immediate" "1")
7458 (set_attr "modrm" "1")
7459 (set_attr "pent_pair" "np")])
7461 (define_insn "*testqi_ext_1_rex64"
7462 [(set (reg FLAGS_REG)
7466 (match_operand 0 "ext_register_operand" "Q")
7470 (match_operand:QI 1 "register_operand" "Q")))
7472 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7473 "test{b}\t{%1, %h0|%h0, %1}"
7474 [(set_attr "type" "test")
7475 (set_attr "mode" "QI")])
7477 (define_insn "*testqi_ext_1"
7478 [(set (reg FLAGS_REG)
7482 (match_operand 0 "ext_register_operand" "Q")
7486 (match_operand:QI 1 "general_operand" "Qm")))
7488 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7489 "test{b}\t{%1, %h0|%h0, %1}"
7490 [(set_attr "type" "test")
7491 (set_attr "mode" "QI")])
7493 (define_insn "*testqi_ext_2"
7494 [(set (reg FLAGS_REG)
7498 (match_operand 0 "ext_register_operand" "Q")
7502 (match_operand 1 "ext_register_operand" "Q")
7506 "ix86_match_ccmode (insn, CCNOmode)"
7507 "test{b}\t{%h1, %h0|%h0, %h1}"
7508 [(set_attr "type" "test")
7509 (set_attr "mode" "QI")])
7511 (define_insn "*testqi_ext_3_rex64"
7512 [(set (reg FLAGS_REG)
7513 (compare (zero_extract:DI
7514 (match_operand 0 "nonimmediate_operand" "rm")
7515 (match_operand:DI 1 "const_int_operand" "")
7516 (match_operand:DI 2 "const_int_operand" ""))
7519 && ix86_match_ccmode (insn, CCNOmode)
7520 && INTVAL (operands[1]) > 0
7521 && INTVAL (operands[2]) >= 0
7522 /* Ensure that resulting mask is zero or sign extended operand. */
7523 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7524 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7525 && INTVAL (operands[1]) > 32))
7526 && (GET_MODE (operands[0]) == SImode
7527 || GET_MODE (operands[0]) == DImode
7528 || GET_MODE (operands[0]) == HImode
7529 || GET_MODE (operands[0]) == QImode)"
7532 ;; Combine likes to form bit extractions for some tests. Humor it.
7533 (define_insn "*testqi_ext_3"
7534 [(set (reg FLAGS_REG)
7535 (compare (zero_extract:SI
7536 (match_operand 0 "nonimmediate_operand" "rm")
7537 (match_operand:SI 1 "const_int_operand" "")
7538 (match_operand:SI 2 "const_int_operand" ""))
7540 "ix86_match_ccmode (insn, CCNOmode)
7541 && INTVAL (operands[1]) > 0
7542 && INTVAL (operands[2]) >= 0
7543 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7544 && (GET_MODE (operands[0]) == SImode
7545 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7546 || GET_MODE (operands[0]) == HImode
7547 || GET_MODE (operands[0]) == QImode)"
7551 [(set (match_operand 0 "flags_reg_operand" "")
7552 (match_operator 1 "compare_operator"
7554 (match_operand 2 "nonimmediate_operand" "")
7555 (match_operand 3 "const_int_operand" "")
7556 (match_operand 4 "const_int_operand" ""))
7558 "ix86_match_ccmode (insn, CCNOmode)"
7559 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7561 rtx val = operands[2];
7562 HOST_WIDE_INT len = INTVAL (operands[3]);
7563 HOST_WIDE_INT pos = INTVAL (operands[4]);
7565 enum machine_mode mode, submode;
7567 mode = GET_MODE (val);
7570 /* ??? Combine likes to put non-volatile mem extractions in QImode
7571 no matter the size of the test. So find a mode that works. */
7572 if (! MEM_VOLATILE_P (val))
7574 mode = smallest_mode_for_size (pos + len, MODE_INT);
7575 val = adjust_address (val, mode, 0);
7578 else if (GET_CODE (val) == SUBREG
7579 && (submode = GET_MODE (SUBREG_REG (val)),
7580 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7581 && pos + len <= GET_MODE_BITSIZE (submode)
7582 && GET_MODE_CLASS (submode) == MODE_INT)
7584 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7586 val = SUBREG_REG (val);
7588 else if (mode == HImode && pos + len <= 8)
7590 /* Small HImode tests can be converted to QImode. */
7592 val = gen_lowpart (QImode, val);
7595 if (len == HOST_BITS_PER_WIDE_INT)
7598 mask = ((HOST_WIDE_INT)1 << len) - 1;
7601 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7604 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7605 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7606 ;; this is relatively important trick.
7607 ;; Do the conversion only post-reload to avoid limiting of the register class
7610 [(set (match_operand 0 "flags_reg_operand" "")
7611 (match_operator 1 "compare_operator"
7612 [(and (match_operand 2 "register_operand" "")
7613 (match_operand 3 "const_int_operand" ""))
7616 && QI_REG_P (operands[2])
7617 && GET_MODE (operands[2]) != QImode
7618 && ((ix86_match_ccmode (insn, CCZmode)
7619 && !(INTVAL (operands[3]) & ~(255 << 8)))
7620 || (ix86_match_ccmode (insn, CCNOmode)
7621 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7624 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7627 "operands[2] = gen_lowpart (SImode, operands[2]);
7628 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7631 [(set (match_operand 0 "flags_reg_operand" "")
7632 (match_operator 1 "compare_operator"
7633 [(and (match_operand 2 "nonimmediate_operand" "")
7634 (match_operand 3 "const_int_operand" ""))
7637 && GET_MODE (operands[2]) != QImode
7638 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7639 && ((ix86_match_ccmode (insn, CCZmode)
7640 && !(INTVAL (operands[3]) & ~255))
7641 || (ix86_match_ccmode (insn, CCNOmode)
7642 && !(INTVAL (operands[3]) & ~127)))"
7644 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7646 "operands[2] = gen_lowpart (QImode, operands[2]);
7647 operands[3] = gen_lowpart (QImode, operands[3]);")
7649 ;; %%% This used to optimize known byte-wide and operations to memory,
7650 ;; and sometimes to QImode registers. If this is considered useful,
7651 ;; it should be done with splitters.
7653 (define_expand "and<mode>3"
7654 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7655 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7656 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7658 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7660 (define_insn "*anddi_1"
7661 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7663 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7664 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7665 (clobber (reg:CC FLAGS_REG))]
7666 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7668 switch (get_attr_type (insn))
7672 enum machine_mode mode;
7674 gcc_assert (CONST_INT_P (operands[2]));
7675 if (INTVAL (operands[2]) == 0xff)
7679 gcc_assert (INTVAL (operands[2]) == 0xffff);
7683 operands[1] = gen_lowpart (mode, operands[1]);
7685 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7687 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7691 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7692 if (get_attr_mode (insn) == MODE_SI)
7693 return "and{l}\t{%k2, %k0|%k0, %k2}";
7695 return "and{q}\t{%2, %0|%0, %2}";
7698 [(set_attr "type" "alu,alu,alu,imovx")
7699 (set_attr "length_immediate" "*,*,*,0")
7700 (set (attr "prefix_rex")
7702 (and (eq_attr "type" "imovx")
7703 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7704 (match_operand 1 "ext_QIreg_operand" "")))
7706 (const_string "*")))
7707 (set_attr "mode" "SI,DI,DI,SI")])
7709 (define_insn "*andsi_1"
7710 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7711 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7712 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7713 (clobber (reg:CC FLAGS_REG))]
7714 "ix86_binary_operator_ok (AND, SImode, operands)"
7716 switch (get_attr_type (insn))
7720 enum machine_mode mode;
7722 gcc_assert (CONST_INT_P (operands[2]));
7723 if (INTVAL (operands[2]) == 0xff)
7727 gcc_assert (INTVAL (operands[2]) == 0xffff);
7731 operands[1] = gen_lowpart (mode, operands[1]);
7733 return "movz{bl|x}\t{%1, %0|%0, %1}";
7735 return "movz{wl|x}\t{%1, %0|%0, %1}";
7739 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7740 return "and{l}\t{%2, %0|%0, %2}";
7743 [(set_attr "type" "alu,alu,imovx")
7744 (set (attr "prefix_rex")
7746 (and (eq_attr "type" "imovx")
7747 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7748 (match_operand 1 "ext_QIreg_operand" "")))
7750 (const_string "*")))
7751 (set_attr "length_immediate" "*,*,0")
7752 (set_attr "mode" "SI")])
7754 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7755 (define_insn "*andsi_1_zext"
7756 [(set (match_operand:DI 0 "register_operand" "=r")
7758 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7759 (match_operand:SI 2 "general_operand" "g"))))
7760 (clobber (reg:CC FLAGS_REG))]
7761 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7762 "and{l}\t{%2, %k0|%k0, %2}"
7763 [(set_attr "type" "alu")
7764 (set_attr "mode" "SI")])
7766 (define_insn "*andhi_1"
7767 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7768 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7769 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7770 (clobber (reg:CC FLAGS_REG))]
7771 "ix86_binary_operator_ok (AND, HImode, operands)"
7773 switch (get_attr_type (insn))
7776 gcc_assert (CONST_INT_P (operands[2]));
7777 gcc_assert (INTVAL (operands[2]) == 0xff);
7778 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7781 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7783 return "and{w}\t{%2, %0|%0, %2}";
7786 [(set_attr "type" "alu,alu,imovx")
7787 (set_attr "length_immediate" "*,*,0")
7788 (set (attr "prefix_rex")
7790 (and (eq_attr "type" "imovx")
7791 (match_operand 1 "ext_QIreg_operand" ""))
7793 (const_string "*")))
7794 (set_attr "mode" "HI,HI,SI")])
7796 ;; %%% Potential partial reg stall on alternative 2. What to do?
7797 (define_insn "*andqi_1"
7798 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7799 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7800 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7801 (clobber (reg:CC FLAGS_REG))]
7802 "ix86_binary_operator_ok (AND, QImode, operands)"
7804 and{b}\t{%2, %0|%0, %2}
7805 and{b}\t{%2, %0|%0, %2}
7806 and{l}\t{%k2, %k0|%k0, %k2}"
7807 [(set_attr "type" "alu")
7808 (set_attr "mode" "QI,QI,SI")])
7810 (define_insn "*andqi_1_slp"
7811 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7812 (and:QI (match_dup 0)
7813 (match_operand:QI 1 "general_operand" "qn,qmn")))
7814 (clobber (reg:CC FLAGS_REG))]
7815 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7816 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7817 "and{b}\t{%1, %0|%0, %1}"
7818 [(set_attr "type" "alu1")
7819 (set_attr "mode" "QI")])
7822 [(set (match_operand 0 "register_operand" "")
7824 (const_int -65536)))
7825 (clobber (reg:CC FLAGS_REG))]
7826 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7827 || optimize_function_for_size_p (cfun)"
7828 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7829 "operands[1] = gen_lowpart (HImode, operands[0]);")
7832 [(set (match_operand 0 "ext_register_operand" "")
7835 (clobber (reg:CC FLAGS_REG))]
7836 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7837 && reload_completed"
7838 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7839 "operands[1] = gen_lowpart (QImode, operands[0]);")
7842 [(set (match_operand 0 "ext_register_operand" "")
7844 (const_int -65281)))
7845 (clobber (reg:CC FLAGS_REG))]
7846 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7847 && reload_completed"
7848 [(parallel [(set (zero_extract:SI (match_dup 0)
7852 (zero_extract:SI (match_dup 0)
7855 (zero_extract:SI (match_dup 0)
7858 (clobber (reg:CC FLAGS_REG))])]
7859 "operands[0] = gen_lowpart (SImode, operands[0]);")
7861 (define_insn "*anddi_2"
7862 [(set (reg FLAGS_REG)
7865 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7866 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7868 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7869 (and:DI (match_dup 1) (match_dup 2)))]
7870 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7871 && ix86_binary_operator_ok (AND, DImode, operands)"
7873 and{l}\t{%k2, %k0|%k0, %k2}
7874 and{q}\t{%2, %0|%0, %2}
7875 and{q}\t{%2, %0|%0, %2}"
7876 [(set_attr "type" "alu")
7877 (set_attr "mode" "SI,DI,DI")])
7879 (define_insn "*andqi_2_maybe_si"
7880 [(set (reg FLAGS_REG)
7882 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7883 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7885 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7886 (and:QI (match_dup 1) (match_dup 2)))]
7887 "ix86_binary_operator_ok (AND, QImode, operands)
7888 && ix86_match_ccmode (insn,
7889 CONST_INT_P (operands[2])
7890 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7892 if (which_alternative == 2)
7894 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7895 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7896 return "and{l}\t{%2, %k0|%k0, %2}";
7898 return "and{b}\t{%2, %0|%0, %2}";
7900 [(set_attr "type" "alu")
7901 (set_attr "mode" "QI,QI,SI")])
7903 (define_insn "*and<mode>_2"
7904 [(set (reg FLAGS_REG)
7905 (compare (and:SWI124
7906 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7907 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7909 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7910 (and:SWI124 (match_dup 1) (match_dup 2)))]
7911 "ix86_match_ccmode (insn, CCNOmode)
7912 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7913 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7914 [(set_attr "type" "alu")
7915 (set_attr "mode" "<MODE>")])
7917 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7918 (define_insn "*andsi_2_zext"
7919 [(set (reg FLAGS_REG)
7921 (match_operand:SI 1 "nonimmediate_operand" "%0")
7922 (match_operand:SI 2 "general_operand" "g"))
7924 (set (match_operand:DI 0 "register_operand" "=r")
7925 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7926 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7927 && ix86_binary_operator_ok (AND, SImode, operands)"
7928 "and{l}\t{%2, %k0|%k0, %2}"
7929 [(set_attr "type" "alu")
7930 (set_attr "mode" "SI")])
7932 (define_insn "*andqi_2_slp"
7933 [(set (reg FLAGS_REG)
7935 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7936 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7938 (set (strict_low_part (match_dup 0))
7939 (and:QI (match_dup 0) (match_dup 1)))]
7940 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7941 && ix86_match_ccmode (insn, CCNOmode)
7942 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7943 "and{b}\t{%1, %0|%0, %1}"
7944 [(set_attr "type" "alu1")
7945 (set_attr "mode" "QI")])
7947 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7948 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7949 ;; for a QImode operand, which of course failed.
7950 (define_insn "andqi_ext_0"
7951 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7956 (match_operand 1 "ext_register_operand" "0")
7959 (match_operand 2 "const_int_operand" "n")))
7960 (clobber (reg:CC FLAGS_REG))]
7962 "and{b}\t{%2, %h0|%h0, %2}"
7963 [(set_attr "type" "alu")
7964 (set_attr "length_immediate" "1")
7965 (set_attr "modrm" "1")
7966 (set_attr "mode" "QI")])
7968 ;; Generated by peephole translating test to and. This shows up
7969 ;; often in fp comparisons.
7970 (define_insn "*andqi_ext_0_cc"
7971 [(set (reg FLAGS_REG)
7975 (match_operand 1 "ext_register_operand" "0")
7978 (match_operand 2 "const_int_operand" "n"))
7980 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7989 "ix86_match_ccmode (insn, CCNOmode)"
7990 "and{b}\t{%2, %h0|%h0, %2}"
7991 [(set_attr "type" "alu")
7992 (set_attr "length_immediate" "1")
7993 (set_attr "modrm" "1")
7994 (set_attr "mode" "QI")])
7996 (define_insn "*andqi_ext_1_rex64"
7997 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8002 (match_operand 1 "ext_register_operand" "0")
8006 (match_operand 2 "ext_register_operand" "Q"))))
8007 (clobber (reg:CC FLAGS_REG))]
8009 "and{b}\t{%2, %h0|%h0, %2}"
8010 [(set_attr "type" "alu")
8011 (set_attr "length_immediate" "0")
8012 (set_attr "mode" "QI")])
8014 (define_insn "*andqi_ext_1"
8015 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8020 (match_operand 1 "ext_register_operand" "0")
8024 (match_operand:QI 2 "general_operand" "Qm"))))
8025 (clobber (reg:CC FLAGS_REG))]
8027 "and{b}\t{%2, %h0|%h0, %2}"
8028 [(set_attr "type" "alu")
8029 (set_attr "length_immediate" "0")
8030 (set_attr "mode" "QI")])
8032 (define_insn "*andqi_ext_2"
8033 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8038 (match_operand 1 "ext_register_operand" "%0")
8042 (match_operand 2 "ext_register_operand" "Q")
8045 (clobber (reg:CC FLAGS_REG))]
8047 "and{b}\t{%h2, %h0|%h0, %h2}"
8048 [(set_attr "type" "alu")
8049 (set_attr "length_immediate" "0")
8050 (set_attr "mode" "QI")])
8052 ;; Convert wide AND instructions with immediate operand to shorter QImode
8053 ;; equivalents when possible.
8054 ;; Don't do the splitting with memory operands, since it introduces risk
8055 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8056 ;; for size, but that can (should?) be handled by generic code instead.
8058 [(set (match_operand 0 "register_operand" "")
8059 (and (match_operand 1 "register_operand" "")
8060 (match_operand 2 "const_int_operand" "")))
8061 (clobber (reg:CC FLAGS_REG))]
8063 && QI_REG_P (operands[0])
8064 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8065 && !(~INTVAL (operands[2]) & ~(255 << 8))
8066 && GET_MODE (operands[0]) != QImode"
8067 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8068 (and:SI (zero_extract:SI (match_dup 1)
8069 (const_int 8) (const_int 8))
8071 (clobber (reg:CC FLAGS_REG))])]
8072 "operands[0] = gen_lowpart (SImode, operands[0]);
8073 operands[1] = gen_lowpart (SImode, operands[1]);
8074 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8076 ;; Since AND can be encoded with sign extended immediate, this is only
8077 ;; profitable when 7th bit is not set.
8079 [(set (match_operand 0 "register_operand" "")
8080 (and (match_operand 1 "general_operand" "")
8081 (match_operand 2 "const_int_operand" "")))
8082 (clobber (reg:CC FLAGS_REG))]
8084 && ANY_QI_REG_P (operands[0])
8085 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8086 && !(~INTVAL (operands[2]) & ~255)
8087 && !(INTVAL (operands[2]) & 128)
8088 && GET_MODE (operands[0]) != QImode"
8089 [(parallel [(set (strict_low_part (match_dup 0))
8090 (and:QI (match_dup 1)
8092 (clobber (reg:CC FLAGS_REG))])]
8093 "operands[0] = gen_lowpart (QImode, operands[0]);
8094 operands[1] = gen_lowpart (QImode, operands[1]);
8095 operands[2] = gen_lowpart (QImode, operands[2]);")
8097 ;; Logical inclusive and exclusive OR instructions
8099 ;; %%% This used to optimize known byte-wide and operations to memory.
8100 ;; If this is considered useful, it should be done with splitters.
8102 (define_expand "<code><mode>3"
8103 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8104 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8105 (match_operand:SWIM 2 "<general_operand>" "")))]
8107 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8109 (define_insn "*<code><mode>_1"
8110 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8112 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8113 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8114 (clobber (reg:CC FLAGS_REG))]
8115 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8116 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8117 [(set_attr "type" "alu")
8118 (set_attr "mode" "<MODE>")])
8120 ;; %%% Potential partial reg stall on alternative 2. What to do?
8121 (define_insn "*<code>qi_1"
8122 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8123 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8124 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8125 (clobber (reg:CC FLAGS_REG))]
8126 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8128 <logic>{b}\t{%2, %0|%0, %2}
8129 <logic>{b}\t{%2, %0|%0, %2}
8130 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8131 [(set_attr "type" "alu")
8132 (set_attr "mode" "QI,QI,SI")])
8134 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8135 (define_insn "*<code>si_1_zext"
8136 [(set (match_operand:DI 0 "register_operand" "=r")
8138 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8139 (match_operand:SI 2 "general_operand" "g"))))
8140 (clobber (reg:CC FLAGS_REG))]
8141 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8142 "<logic>{l}\t{%2, %k0|%k0, %2}"
8143 [(set_attr "type" "alu")
8144 (set_attr "mode" "SI")])
8146 (define_insn "*<code>si_1_zext_imm"
8147 [(set (match_operand:DI 0 "register_operand" "=r")
8149 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8150 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8151 (clobber (reg:CC FLAGS_REG))]
8152 "TARGET_64BIT && 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_1_slp"
8158 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8159 (any_or:QI (match_dup 0)
8160 (match_operand:QI 1 "general_operand" "qmn,qn")))
8161 (clobber (reg:CC FLAGS_REG))]
8162 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8163 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8164 "<logic>{b}\t{%1, %0|%0, %1}"
8165 [(set_attr "type" "alu1")
8166 (set_attr "mode" "QI")])
8168 (define_insn "*<code><mode>_2"
8169 [(set (reg FLAGS_REG)
8170 (compare (any_or:SWI
8171 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8172 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8174 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8175 (any_or:SWI (match_dup 1) (match_dup 2)))]
8176 "ix86_match_ccmode (insn, CCNOmode)
8177 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8178 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8179 [(set_attr "type" "alu")
8180 (set_attr "mode" "<MODE>")])
8182 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8183 ;; ??? Special case for immediate operand is missing - it is tricky.
8184 (define_insn "*<code>si_2_zext"
8185 [(set (reg FLAGS_REG)
8186 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8187 (match_operand:SI 2 "general_operand" "g"))
8189 (set (match_operand:DI 0 "register_operand" "=r")
8190 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8191 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8192 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8193 "<logic>{l}\t{%2, %k0|%k0, %2}"
8194 [(set_attr "type" "alu")
8195 (set_attr "mode" "SI")])
8197 (define_insn "*<code>si_2_zext_imm"
8198 [(set (reg FLAGS_REG)
8200 (match_operand:SI 1 "nonimmediate_operand" "%0")
8201 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8203 (set (match_operand:DI 0 "register_operand" "=r")
8204 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8205 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8206 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8207 "<logic>{l}\t{%2, %k0|%k0, %2}"
8208 [(set_attr "type" "alu")
8209 (set_attr "mode" "SI")])
8211 (define_insn "*<code>qi_2_slp"
8212 [(set (reg FLAGS_REG)
8213 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8214 (match_operand:QI 1 "general_operand" "qmn,qn"))
8216 (set (strict_low_part (match_dup 0))
8217 (any_or:QI (match_dup 0) (match_dup 1)))]
8218 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8219 && ix86_match_ccmode (insn, CCNOmode)
8220 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8221 "<logic>{b}\t{%1, %0|%0, %1}"
8222 [(set_attr "type" "alu1")
8223 (set_attr "mode" "QI")])
8225 (define_insn "*<code><mode>_3"
8226 [(set (reg FLAGS_REG)
8227 (compare (any_or:SWI
8228 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8229 (match_operand:SWI 2 "<general_operand>" "<g>"))
8231 (clobber (match_scratch:SWI 0 "=<r>"))]
8232 "ix86_match_ccmode (insn, CCNOmode)
8233 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8234 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8235 [(set_attr "type" "alu")
8236 (set_attr "mode" "<MODE>")])
8238 (define_insn "*<code>qi_ext_0"
8239 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8244 (match_operand 1 "ext_register_operand" "0")
8247 (match_operand 2 "const_int_operand" "n")))
8248 (clobber (reg:CC FLAGS_REG))]
8249 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8250 "<logic>{b}\t{%2, %h0|%h0, %2}"
8251 [(set_attr "type" "alu")
8252 (set_attr "length_immediate" "1")
8253 (set_attr "modrm" "1")
8254 (set_attr "mode" "QI")])
8256 (define_insn "*<code>qi_ext_1_rex64"
8257 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8262 (match_operand 1 "ext_register_operand" "0")
8266 (match_operand 2 "ext_register_operand" "Q"))))
8267 (clobber (reg:CC FLAGS_REG))]
8269 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8270 "<logic>{b}\t{%2, %h0|%h0, %2}"
8271 [(set_attr "type" "alu")
8272 (set_attr "length_immediate" "0")
8273 (set_attr "mode" "QI")])
8275 (define_insn "*<code>qi_ext_1"
8276 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8281 (match_operand 1 "ext_register_operand" "0")
8285 (match_operand:QI 2 "general_operand" "Qm"))))
8286 (clobber (reg:CC FLAGS_REG))]
8288 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8289 "<logic>{b}\t{%2, %h0|%h0, %2}"
8290 [(set_attr "type" "alu")
8291 (set_attr "length_immediate" "0")
8292 (set_attr "mode" "QI")])
8294 (define_insn "*<code>qi_ext_2"
8295 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8299 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8302 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8305 (clobber (reg:CC FLAGS_REG))]
8306 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8307 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8308 [(set_attr "type" "alu")
8309 (set_attr "length_immediate" "0")
8310 (set_attr "mode" "QI")])
8313 [(set (match_operand 0 "register_operand" "")
8314 (any_or (match_operand 1 "register_operand" "")
8315 (match_operand 2 "const_int_operand" "")))
8316 (clobber (reg:CC FLAGS_REG))]
8318 && QI_REG_P (operands[0])
8319 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8320 && !(INTVAL (operands[2]) & ~(255 << 8))
8321 && GET_MODE (operands[0]) != QImode"
8322 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8323 (any_or:SI (zero_extract:SI (match_dup 1)
8324 (const_int 8) (const_int 8))
8326 (clobber (reg:CC FLAGS_REG))])]
8327 "operands[0] = gen_lowpart (SImode, operands[0]);
8328 operands[1] = gen_lowpart (SImode, operands[1]);
8329 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8331 ;; Since OR can be encoded with sign extended immediate, this is only
8332 ;; profitable when 7th bit is set.
8334 [(set (match_operand 0 "register_operand" "")
8335 (any_or (match_operand 1 "general_operand" "")
8336 (match_operand 2 "const_int_operand" "")))
8337 (clobber (reg:CC FLAGS_REG))]
8339 && ANY_QI_REG_P (operands[0])
8340 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8341 && !(INTVAL (operands[2]) & ~255)
8342 && (INTVAL (operands[2]) & 128)
8343 && GET_MODE (operands[0]) != QImode"
8344 [(parallel [(set (strict_low_part (match_dup 0))
8345 (any_or:QI (match_dup 1)
8347 (clobber (reg:CC FLAGS_REG))])]
8348 "operands[0] = gen_lowpart (QImode, operands[0]);
8349 operands[1] = gen_lowpart (QImode, operands[1]);
8350 operands[2] = gen_lowpart (QImode, operands[2]);")
8352 (define_expand "xorqi_cc_ext_1"
8354 (set (reg:CCNO FLAGS_REG)
8358 (match_operand 1 "ext_register_operand" "")
8361 (match_operand:QI 2 "general_operand" ""))
8363 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8373 (define_insn "*xorqi_cc_ext_1_rex64"
8374 [(set (reg FLAGS_REG)
8378 (match_operand 1 "ext_register_operand" "0")
8381 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8383 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8392 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8393 "xor{b}\t{%2, %h0|%h0, %2}"
8394 [(set_attr "type" "alu")
8395 (set_attr "modrm" "1")
8396 (set_attr "mode" "QI")])
8398 (define_insn "*xorqi_cc_ext_1"
8399 [(set (reg FLAGS_REG)
8403 (match_operand 1 "ext_register_operand" "0")
8406 (match_operand:QI 2 "general_operand" "qmn"))
8408 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8417 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8418 "xor{b}\t{%2, %h0|%h0, %2}"
8419 [(set_attr "type" "alu")
8420 (set_attr "modrm" "1")
8421 (set_attr "mode" "QI")])
8423 ;; Negation instructions
8425 (define_expand "neg<mode>2"
8426 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8427 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8429 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8431 (define_insn_and_split "*neg<dwi>2_doubleword"
8432 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8433 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8434 (clobber (reg:CC FLAGS_REG))]
8435 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8439 [(set (reg:CCZ FLAGS_REG)
8440 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8441 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8444 (plus:DWIH (match_dup 3)
8445 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8447 (clobber (reg:CC FLAGS_REG))])
8450 (neg:DWIH (match_dup 2)))
8451 (clobber (reg:CC FLAGS_REG))])]
8452 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8454 (define_insn "*neg<mode>2_1"
8455 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8456 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8457 (clobber (reg:CC FLAGS_REG))]
8458 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8459 "neg{<imodesuffix>}\t%0"
8460 [(set_attr "type" "negnot")
8461 (set_attr "mode" "<MODE>")])
8463 ;; Combine is quite creative about this pattern.
8464 (define_insn "*negsi2_1_zext"
8465 [(set (match_operand:DI 0 "register_operand" "=r")
8467 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8470 (clobber (reg:CC FLAGS_REG))]
8471 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8473 [(set_attr "type" "negnot")
8474 (set_attr "mode" "SI")])
8476 ;; The problem with neg is that it does not perform (compare x 0),
8477 ;; it really performs (compare 0 x), which leaves us with the zero
8478 ;; flag being the only useful item.
8480 (define_insn "*neg<mode>2_cmpz"
8481 [(set (reg:CCZ FLAGS_REG)
8483 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8485 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8486 (neg:SWI (match_dup 1)))]
8487 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8488 "neg{<imodesuffix>}\t%0"
8489 [(set_attr "type" "negnot")
8490 (set_attr "mode" "<MODE>")])
8492 (define_insn "*negsi2_cmpz_zext"
8493 [(set (reg:CCZ FLAGS_REG)
8497 (match_operand:DI 1 "register_operand" "0")
8501 (set (match_operand:DI 0 "register_operand" "=r")
8502 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8505 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8507 [(set_attr "type" "negnot")
8508 (set_attr "mode" "SI")])
8510 ;; Changing of sign for FP values is doable using integer unit too.
8512 (define_expand "<code><mode>2"
8513 [(set (match_operand:X87MODEF 0 "register_operand" "")
8514 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8515 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8516 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8518 (define_insn "*absneg<mode>2_mixed"
8519 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8520 (match_operator:MODEF 3 "absneg_operator"
8521 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8522 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8523 (clobber (reg:CC FLAGS_REG))]
8524 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8527 (define_insn "*absneg<mode>2_sse"
8528 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8529 (match_operator:MODEF 3 "absneg_operator"
8530 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8531 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8532 (clobber (reg:CC FLAGS_REG))]
8533 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8536 (define_insn "*absneg<mode>2_i387"
8537 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8538 (match_operator:X87MODEF 3 "absneg_operator"
8539 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8540 (use (match_operand 2 "" ""))
8541 (clobber (reg:CC FLAGS_REG))]
8542 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8545 (define_expand "<code>tf2"
8546 [(set (match_operand:TF 0 "register_operand" "")
8547 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8549 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8551 (define_insn "*absnegtf2_sse"
8552 [(set (match_operand:TF 0 "register_operand" "=x,x")
8553 (match_operator:TF 3 "absneg_operator"
8554 [(match_operand:TF 1 "register_operand" "0,x")]))
8555 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8556 (clobber (reg:CC FLAGS_REG))]
8560 ;; Splitters for fp abs and neg.
8563 [(set (match_operand 0 "fp_register_operand" "")
8564 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8565 (use (match_operand 2 "" ""))
8566 (clobber (reg:CC FLAGS_REG))]
8568 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8571 [(set (match_operand 0 "register_operand" "")
8572 (match_operator 3 "absneg_operator"
8573 [(match_operand 1 "register_operand" "")]))
8574 (use (match_operand 2 "nonimmediate_operand" ""))
8575 (clobber (reg:CC FLAGS_REG))]
8576 "reload_completed && SSE_REG_P (operands[0])"
8577 [(set (match_dup 0) (match_dup 3))]
8579 enum machine_mode mode = GET_MODE (operands[0]);
8580 enum machine_mode vmode = GET_MODE (operands[2]);
8583 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8584 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8585 if (operands_match_p (operands[0], operands[2]))
8588 operands[1] = operands[2];
8591 if (GET_CODE (operands[3]) == ABS)
8592 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8594 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8599 [(set (match_operand:SF 0 "register_operand" "")
8600 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8601 (use (match_operand:V4SF 2 "" ""))
8602 (clobber (reg:CC FLAGS_REG))]
8604 [(parallel [(set (match_dup 0) (match_dup 1))
8605 (clobber (reg:CC FLAGS_REG))])]
8608 operands[0] = gen_lowpart (SImode, operands[0]);
8609 if (GET_CODE (operands[1]) == ABS)
8611 tmp = gen_int_mode (0x7fffffff, SImode);
8612 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8616 tmp = gen_int_mode (0x80000000, SImode);
8617 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8623 [(set (match_operand:DF 0 "register_operand" "")
8624 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8625 (use (match_operand 2 "" ""))
8626 (clobber (reg:CC FLAGS_REG))]
8628 [(parallel [(set (match_dup 0) (match_dup 1))
8629 (clobber (reg:CC FLAGS_REG))])]
8634 tmp = gen_lowpart (DImode, operands[0]);
8635 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8638 if (GET_CODE (operands[1]) == ABS)
8641 tmp = gen_rtx_NOT (DImode, tmp);
8645 operands[0] = gen_highpart (SImode, operands[0]);
8646 if (GET_CODE (operands[1]) == ABS)
8648 tmp = gen_int_mode (0x7fffffff, SImode);
8649 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8653 tmp = gen_int_mode (0x80000000, SImode);
8654 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8661 [(set (match_operand:XF 0 "register_operand" "")
8662 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8663 (use (match_operand 2 "" ""))
8664 (clobber (reg:CC FLAGS_REG))]
8666 [(parallel [(set (match_dup 0) (match_dup 1))
8667 (clobber (reg:CC FLAGS_REG))])]
8670 operands[0] = gen_rtx_REG (SImode,
8671 true_regnum (operands[0])
8672 + (TARGET_64BIT ? 1 : 2));
8673 if (GET_CODE (operands[1]) == ABS)
8675 tmp = GEN_INT (0x7fff);
8676 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8680 tmp = GEN_INT (0x8000);
8681 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8686 ;; Conditionalize these after reload. If they match before reload, we
8687 ;; lose the clobber and ability to use integer instructions.
8689 (define_insn "*<code><mode>2_1"
8690 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8691 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8693 && (reload_completed
8694 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8695 "f<absneg_mnemonic>"
8696 [(set_attr "type" "fsgn")
8697 (set_attr "mode" "<MODE>")])
8699 (define_insn "*<code>extendsfdf2"
8700 [(set (match_operand:DF 0 "register_operand" "=f")
8701 (absneg:DF (float_extend:DF
8702 (match_operand:SF 1 "register_operand" "0"))))]
8703 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8704 "f<absneg_mnemonic>"
8705 [(set_attr "type" "fsgn")
8706 (set_attr "mode" "DF")])
8708 (define_insn "*<code>extendsfxf2"
8709 [(set (match_operand:XF 0 "register_operand" "=f")
8710 (absneg:XF (float_extend:XF
8711 (match_operand:SF 1 "register_operand" "0"))))]
8713 "f<absneg_mnemonic>"
8714 [(set_attr "type" "fsgn")
8715 (set_attr "mode" "XF")])
8717 (define_insn "*<code>extenddfxf2"
8718 [(set (match_operand:XF 0 "register_operand" "=f")
8719 (absneg:XF (float_extend:XF
8720 (match_operand:DF 1 "register_operand" "0"))))]
8722 "f<absneg_mnemonic>"
8723 [(set_attr "type" "fsgn")
8724 (set_attr "mode" "XF")])
8726 ;; Copysign instructions
8728 (define_mode_iterator CSGNMODE [SF DF TF])
8729 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8731 (define_expand "copysign<mode>3"
8732 [(match_operand:CSGNMODE 0 "register_operand" "")
8733 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8734 (match_operand:CSGNMODE 2 "register_operand" "")]
8735 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8736 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8737 "ix86_expand_copysign (operands); DONE;")
8739 (define_insn_and_split "copysign<mode>3_const"
8740 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8742 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8743 (match_operand:CSGNMODE 2 "register_operand" "0")
8744 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8746 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8747 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8749 "&& reload_completed"
8751 "ix86_split_copysign_const (operands); DONE;")
8753 (define_insn "copysign<mode>3_var"
8754 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8756 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8757 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8758 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8759 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8761 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8762 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8763 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8767 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8769 [(match_operand:CSGNMODE 2 "register_operand" "")
8770 (match_operand:CSGNMODE 3 "register_operand" "")
8771 (match_operand:<CSGNVMODE> 4 "" "")
8772 (match_operand:<CSGNVMODE> 5 "" "")]
8774 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8775 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8776 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8777 && reload_completed"
8779 "ix86_split_copysign_var (operands); DONE;")
8781 ;; One complement instructions
8783 (define_expand "one_cmpl<mode>2"
8784 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8785 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8787 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8789 (define_insn "*one_cmpl<mode>2_1"
8790 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8791 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8792 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8793 "not{<imodesuffix>}\t%0"
8794 [(set_attr "type" "negnot")
8795 (set_attr "mode" "<MODE>")])
8797 ;; %%% Potential partial reg stall on alternative 1. What to do?
8798 (define_insn "*one_cmplqi2_1"
8799 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8800 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8801 "ix86_unary_operator_ok (NOT, QImode, operands)"
8805 [(set_attr "type" "negnot")
8806 (set_attr "mode" "QI,SI")])
8808 ;; ??? Currently never generated - xor is used instead.
8809 (define_insn "*one_cmplsi2_1_zext"
8810 [(set (match_operand:DI 0 "register_operand" "=r")
8812 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8813 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8815 [(set_attr "type" "negnot")
8816 (set_attr "mode" "SI")])
8818 (define_insn "*one_cmpl<mode>2_2"
8819 [(set (reg FLAGS_REG)
8820 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8822 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8823 (not:SWI (match_dup 1)))]
8824 "ix86_match_ccmode (insn, CCNOmode)
8825 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8827 [(set_attr "type" "alu1")
8828 (set_attr "mode" "<MODE>")])
8831 [(set (match_operand 0 "flags_reg_operand" "")
8832 (match_operator 2 "compare_operator"
8833 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8835 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8836 (not:SWI (match_dup 3)))]
8837 "ix86_match_ccmode (insn, CCNOmode)"
8838 [(parallel [(set (match_dup 0)
8839 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8842 (xor:SWI (match_dup 3) (const_int -1)))])])
8844 ;; ??? Currently never generated - xor is used instead.
8845 (define_insn "*one_cmplsi2_2_zext"
8846 [(set (reg FLAGS_REG)
8847 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8849 (set (match_operand:DI 0 "register_operand" "=r")
8850 (zero_extend:DI (not:SI (match_dup 1))))]
8851 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8852 && ix86_unary_operator_ok (NOT, SImode, operands)"
8854 [(set_attr "type" "alu1")
8855 (set_attr "mode" "SI")])
8858 [(set (match_operand 0 "flags_reg_operand" "")
8859 (match_operator 2 "compare_operator"
8860 [(not:SI (match_operand:SI 3 "register_operand" ""))
8862 (set (match_operand:DI 1 "register_operand" "")
8863 (zero_extend:DI (not:SI (match_dup 3))))]
8864 "ix86_match_ccmode (insn, CCNOmode)"
8865 [(parallel [(set (match_dup 0)
8866 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8869 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8871 ;; Shift instructions
8873 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8874 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8875 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8876 ;; from the assembler input.
8878 ;; This instruction shifts the target reg/mem as usual, but instead of
8879 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8880 ;; is a left shift double, bits are taken from the high order bits of
8881 ;; reg, else if the insn is a shift right double, bits are taken from the
8882 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8883 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8885 ;; Since sh[lr]d does not change the `reg' operand, that is done
8886 ;; separately, making all shifts emit pairs of shift double and normal
8887 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8888 ;; support a 63 bit shift, each shift where the count is in a reg expands
8889 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8891 ;; If the shift count is a constant, we need never emit more than one
8892 ;; shift pair, instead using moves and sign extension for counts greater
8895 (define_expand "ashl<mode>3"
8896 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8897 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8898 (match_operand:QI 2 "nonmemory_operand" "")))]
8900 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8902 (define_insn "*ashl<mode>3_doubleword"
8903 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8904 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8905 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8906 (clobber (reg:CC FLAGS_REG))]
8909 [(set_attr "type" "multi")])
8912 [(set (match_operand:DWI 0 "register_operand" "")
8913 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8914 (match_operand:QI 2 "nonmemory_operand" "")))
8915 (clobber (reg:CC FLAGS_REG))]
8916 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8918 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8920 ;; By default we don't ask for a scratch register, because when DWImode
8921 ;; values are manipulated, registers are already at a premium. But if
8922 ;; we have one handy, we won't turn it away.
8925 [(match_scratch:DWIH 3 "r")
8926 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8928 (match_operand:<DWI> 1 "nonmemory_operand" "")
8929 (match_operand:QI 2 "nonmemory_operand" "")))
8930 (clobber (reg:CC FLAGS_REG))])
8934 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8936 (define_insn "x86_64_shld"
8937 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8938 (ior:DI (ashift:DI (match_dup 0)
8939 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8940 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8941 (minus:QI (const_int 64) (match_dup 2)))))
8942 (clobber (reg:CC FLAGS_REG))]
8944 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8945 [(set_attr "type" "ishift")
8946 (set_attr "prefix_0f" "1")
8947 (set_attr "mode" "DI")
8948 (set_attr "athlon_decode" "vector")
8949 (set_attr "amdfam10_decode" "vector")
8950 (set_attr "bdver1_decode" "vector")])
8952 (define_insn "x86_shld"
8953 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8954 (ior:SI (ashift:SI (match_dup 0)
8955 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8956 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8957 (minus:QI (const_int 32) (match_dup 2)))))
8958 (clobber (reg:CC FLAGS_REG))]
8960 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8961 [(set_attr "type" "ishift")
8962 (set_attr "prefix_0f" "1")
8963 (set_attr "mode" "SI")
8964 (set_attr "pent_pair" "np")
8965 (set_attr "athlon_decode" "vector")
8966 (set_attr "amdfam10_decode" "vector")
8967 (set_attr "bdver1_decode" "vector")])
8969 (define_expand "x86_shift<mode>_adj_1"
8970 [(set (reg:CCZ FLAGS_REG)
8971 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8974 (set (match_operand:SWI48 0 "register_operand" "")
8975 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8976 (match_operand:SWI48 1 "register_operand" "")
8979 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8980 (match_operand:SWI48 3 "register_operand" "r")
8983 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8985 (define_expand "x86_shift<mode>_adj_2"
8986 [(use (match_operand:SWI48 0 "register_operand" ""))
8987 (use (match_operand:SWI48 1 "register_operand" ""))
8988 (use (match_operand:QI 2 "register_operand" ""))]
8991 rtx label = gen_label_rtx ();
8994 emit_insn (gen_testqi_ccz_1 (operands[2],
8995 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8997 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8998 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8999 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9000 gen_rtx_LABEL_REF (VOIDmode, label),
9002 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9003 JUMP_LABEL (tmp) = label;
9005 emit_move_insn (operands[0], operands[1]);
9006 ix86_expand_clear (operands[1]);
9009 LABEL_NUSES (label) = 1;
9014 ;; Avoid useless masking of count operand.
9015 (define_insn_and_split "*ashl<mode>3_mask"
9016 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9018 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9021 (match_operand:SI 2 "nonimmediate_operand" "c")
9022 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9023 (clobber (reg:CC FLAGS_REG))]
9024 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9025 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9026 == GET_MODE_BITSIZE (<MODE>mode)-1"
9029 [(parallel [(set (match_dup 0)
9030 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9031 (clobber (reg:CC FLAGS_REG))])]
9033 if (can_create_pseudo_p ())
9034 operands [2] = force_reg (SImode, operands[2]);
9036 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9038 [(set_attr "type" "ishift")
9039 (set_attr "mode" "<MODE>")])
9041 (define_insn "*ashl<mode>3_1"
9042 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9043 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9044 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9045 (clobber (reg:CC FLAGS_REG))]
9046 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9048 switch (get_attr_type (insn))
9054 gcc_assert (operands[2] == const1_rtx);
9055 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9056 return "add{<imodesuffix>}\t%0, %0";
9059 if (operands[2] == const1_rtx
9060 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9061 return "sal{<imodesuffix>}\t%0";
9063 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9067 (cond [(eq_attr "alternative" "1")
9068 (const_string "lea")
9069 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9071 (match_operand 0 "register_operand" ""))
9072 (match_operand 2 "const1_operand" ""))
9073 (const_string "alu")
9075 (const_string "ishift")))
9076 (set (attr "length_immediate")
9078 (ior (eq_attr "type" "alu")
9079 (and (eq_attr "type" "ishift")
9080 (and (match_operand 2 "const1_operand" "")
9081 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9084 (const_string "*")))
9085 (set_attr "mode" "<MODE>")])
9087 (define_insn "*ashlsi3_1_zext"
9088 [(set (match_operand:DI 0 "register_operand" "=r,r")
9090 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9091 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9092 (clobber (reg:CC FLAGS_REG))]
9093 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9095 switch (get_attr_type (insn))
9101 gcc_assert (operands[2] == const1_rtx);
9102 return "add{l}\t%k0, %k0";
9105 if (operands[2] == const1_rtx
9106 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9107 return "sal{l}\t%k0";
9109 return "sal{l}\t{%2, %k0|%k0, %2}";
9113 (cond [(eq_attr "alternative" "1")
9114 (const_string "lea")
9115 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9117 (match_operand 2 "const1_operand" ""))
9118 (const_string "alu")
9120 (const_string "ishift")))
9121 (set (attr "length_immediate")
9123 (ior (eq_attr "type" "alu")
9124 (and (eq_attr "type" "ishift")
9125 (and (match_operand 2 "const1_operand" "")
9126 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9129 (const_string "*")))
9130 (set_attr "mode" "SI")])
9132 (define_insn "*ashlhi3_1"
9133 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9134 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9135 (match_operand:QI 2 "nonmemory_operand" "cI")))
9136 (clobber (reg:CC FLAGS_REG))]
9137 "TARGET_PARTIAL_REG_STALL
9138 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9140 switch (get_attr_type (insn))
9143 gcc_assert (operands[2] == const1_rtx);
9144 return "add{w}\t%0, %0";
9147 if (operands[2] == const1_rtx
9148 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9149 return "sal{w}\t%0";
9151 return "sal{w}\t{%2, %0|%0, %2}";
9155 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9157 (match_operand 0 "register_operand" ""))
9158 (match_operand 2 "const1_operand" ""))
9159 (const_string "alu")
9161 (const_string "ishift")))
9162 (set (attr "length_immediate")
9164 (ior (eq_attr "type" "alu")
9165 (and (eq_attr "type" "ishift")
9166 (and (match_operand 2 "const1_operand" "")
9167 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9170 (const_string "*")))
9171 (set_attr "mode" "HI")])
9173 (define_insn "*ashlhi3_1_lea"
9174 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9175 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9176 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9177 (clobber (reg:CC FLAGS_REG))]
9178 "!TARGET_PARTIAL_REG_STALL
9179 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9181 switch (get_attr_type (insn))
9187 gcc_assert (operands[2] == const1_rtx);
9188 return "add{w}\t%0, %0";
9191 if (operands[2] == const1_rtx
9192 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9193 return "sal{w}\t%0";
9195 return "sal{w}\t{%2, %0|%0, %2}";
9199 (cond [(eq_attr "alternative" "1")
9200 (const_string "lea")
9201 (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" "HI,SI")])
9219 (define_insn "*ashlqi3_1"
9220 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9221 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9222 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9223 (clobber (reg:CC FLAGS_REG))]
9224 "TARGET_PARTIAL_REG_STALL
9225 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9227 switch (get_attr_type (insn))
9230 gcc_assert (operands[2] == const1_rtx);
9231 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9232 return "add{l}\t%k0, %k0";
9234 return "add{b}\t%0, %0";
9237 if (operands[2] == const1_rtx
9238 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9240 if (get_attr_mode (insn) == MODE_SI)
9241 return "sal{l}\t%k0";
9243 return "sal{b}\t%0";
9247 if (get_attr_mode (insn) == MODE_SI)
9248 return "sal{l}\t{%2, %k0|%k0, %2}";
9250 return "sal{b}\t{%2, %0|%0, %2}";
9255 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9257 (match_operand 0 "register_operand" ""))
9258 (match_operand 2 "const1_operand" ""))
9259 (const_string "alu")
9261 (const_string "ishift")))
9262 (set (attr "length_immediate")
9264 (ior (eq_attr "type" "alu")
9265 (and (eq_attr "type" "ishift")
9266 (and (match_operand 2 "const1_operand" "")
9267 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9270 (const_string "*")))
9271 (set_attr "mode" "QI,SI")])
9273 ;; %%% Potential partial reg stall on alternative 2. What to do?
9274 (define_insn "*ashlqi3_1_lea"
9275 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9276 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9277 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9278 (clobber (reg:CC FLAGS_REG))]
9279 "!TARGET_PARTIAL_REG_STALL
9280 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9282 switch (get_attr_type (insn))
9288 gcc_assert (operands[2] == const1_rtx);
9289 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9290 return "add{l}\t%k0, %k0";
9292 return "add{b}\t%0, %0";
9295 if (operands[2] == const1_rtx
9296 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9298 if (get_attr_mode (insn) == MODE_SI)
9299 return "sal{l}\t%k0";
9301 return "sal{b}\t%0";
9305 if (get_attr_mode (insn) == MODE_SI)
9306 return "sal{l}\t{%2, %k0|%k0, %2}";
9308 return "sal{b}\t{%2, %0|%0, %2}";
9313 (cond [(eq_attr "alternative" "2")
9314 (const_string "lea")
9315 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9317 (match_operand 0 "register_operand" ""))
9318 (match_operand 2 "const1_operand" ""))
9319 (const_string "alu")
9321 (const_string "ishift")))
9322 (set (attr "length_immediate")
9324 (ior (eq_attr "type" "alu")
9325 (and (eq_attr "type" "ishift")
9326 (and (match_operand 2 "const1_operand" "")
9327 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9330 (const_string "*")))
9331 (set_attr "mode" "QI,SI,SI")])
9333 (define_insn "*ashlqi3_1_slp"
9334 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9335 (ashift:QI (match_dup 0)
9336 (match_operand:QI 1 "nonmemory_operand" "cI")))
9337 (clobber (reg:CC FLAGS_REG))]
9338 "(optimize_function_for_size_p (cfun)
9339 || !TARGET_PARTIAL_FLAG_REG_STALL
9340 || (operands[1] == const1_rtx
9342 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9344 switch (get_attr_type (insn))
9347 gcc_assert (operands[1] == const1_rtx);
9348 return "add{b}\t%0, %0";
9351 if (operands[1] == const1_rtx
9352 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9353 return "sal{b}\t%0";
9355 return "sal{b}\t{%1, %0|%0, %1}";
9359 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9361 (match_operand 0 "register_operand" ""))
9362 (match_operand 1 "const1_operand" ""))
9363 (const_string "alu")
9365 (const_string "ishift1")))
9366 (set (attr "length_immediate")
9368 (ior (eq_attr "type" "alu")
9369 (and (eq_attr "type" "ishift1")
9370 (and (match_operand 1 "const1_operand" "")
9371 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9374 (const_string "*")))
9375 (set_attr "mode" "QI")])
9377 ;; Convert lea to the lea pattern to avoid flags dependency.
9379 [(set (match_operand 0 "register_operand" "")
9380 (ashift (match_operand 1 "index_register_operand" "")
9381 (match_operand:QI 2 "const_int_operand" "")))
9382 (clobber (reg:CC FLAGS_REG))]
9384 && true_regnum (operands[0]) != true_regnum (operands[1])"
9388 enum machine_mode mode = GET_MODE (operands[0]);
9391 operands[1] = gen_lowpart (Pmode, operands[1]);
9392 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9394 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9396 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9397 operands[0] = gen_lowpart (SImode, operands[0]);
9399 if (TARGET_64BIT && mode != Pmode)
9400 pat = gen_rtx_SUBREG (SImode, pat, 0);
9402 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9406 ;; Convert lea to the lea pattern to avoid flags dependency.
9408 [(set (match_operand:DI 0 "register_operand" "")
9410 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9411 (match_operand:QI 2 "const_int_operand" ""))))
9412 (clobber (reg:CC FLAGS_REG))]
9413 "TARGET_64BIT && reload_completed
9414 && true_regnum (operands[0]) != true_regnum (operands[1])"
9416 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9418 operands[1] = gen_lowpart (DImode, operands[1]);
9419 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9422 ;; This pattern can't accept a variable shift count, since shifts by
9423 ;; zero don't affect the flags. We assume that shifts by constant
9424 ;; zero are optimized away.
9425 (define_insn "*ashl<mode>3_cmp"
9426 [(set (reg FLAGS_REG)
9428 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9429 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9431 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9432 (ashift:SWI (match_dup 1) (match_dup 2)))]
9433 "(optimize_function_for_size_p (cfun)
9434 || !TARGET_PARTIAL_FLAG_REG_STALL
9435 || (operands[2] == const1_rtx
9437 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9438 && ix86_match_ccmode (insn, CCGOCmode)
9439 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9441 switch (get_attr_type (insn))
9444 gcc_assert (operands[2] == const1_rtx);
9445 return "add{<imodesuffix>}\t%0, %0";
9448 if (operands[2] == const1_rtx
9449 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9450 return "sal{<imodesuffix>}\t%0";
9452 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9456 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9458 (match_operand 0 "register_operand" ""))
9459 (match_operand 2 "const1_operand" ""))
9460 (const_string "alu")
9462 (const_string "ishift")))
9463 (set (attr "length_immediate")
9465 (ior (eq_attr "type" "alu")
9466 (and (eq_attr "type" "ishift")
9467 (and (match_operand 2 "const1_operand" "")
9468 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9471 (const_string "*")))
9472 (set_attr "mode" "<MODE>")])
9474 (define_insn "*ashlsi3_cmp_zext"
9475 [(set (reg FLAGS_REG)
9477 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9478 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9480 (set (match_operand:DI 0 "register_operand" "=r")
9481 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9483 && (optimize_function_for_size_p (cfun)
9484 || !TARGET_PARTIAL_FLAG_REG_STALL
9485 || (operands[2] == const1_rtx
9487 || TARGET_DOUBLE_WITH_ADD)))
9488 && ix86_match_ccmode (insn, CCGOCmode)
9489 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9491 switch (get_attr_type (insn))
9494 gcc_assert (operands[2] == const1_rtx);
9495 return "add{l}\t%k0, %k0";
9498 if (operands[2] == const1_rtx
9499 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9500 return "sal{l}\t%k0";
9502 return "sal{l}\t{%2, %k0|%k0, %2}";
9506 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9508 (match_operand 2 "const1_operand" ""))
9509 (const_string "alu")
9511 (const_string "ishift")))
9512 (set (attr "length_immediate")
9514 (ior (eq_attr "type" "alu")
9515 (and (eq_attr "type" "ishift")
9516 (and (match_operand 2 "const1_operand" "")
9517 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9520 (const_string "*")))
9521 (set_attr "mode" "SI")])
9523 (define_insn "*ashl<mode>3_cconly"
9524 [(set (reg FLAGS_REG)
9526 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9527 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9529 (clobber (match_scratch:SWI 0 "=<r>"))]
9530 "(optimize_function_for_size_p (cfun)
9531 || !TARGET_PARTIAL_FLAG_REG_STALL
9532 || (operands[2] == const1_rtx
9534 || TARGET_DOUBLE_WITH_ADD)))
9535 && ix86_match_ccmode (insn, CCGOCmode)"
9537 switch (get_attr_type (insn))
9540 gcc_assert (operands[2] == const1_rtx);
9541 return "add{<imodesuffix>}\t%0, %0";
9544 if (operands[2] == const1_rtx
9545 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9546 return "sal{<imodesuffix>}\t%0";
9548 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9552 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9554 (match_operand 0 "register_operand" ""))
9555 (match_operand 2 "const1_operand" ""))
9556 (const_string "alu")
9558 (const_string "ishift")))
9559 (set (attr "length_immediate")
9561 (ior (eq_attr "type" "alu")
9562 (and (eq_attr "type" "ishift")
9563 (and (match_operand 2 "const1_operand" "")
9564 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9567 (const_string "*")))
9568 (set_attr "mode" "<MODE>")])
9570 ;; See comment above `ashl<mode>3' about how this works.
9572 (define_expand "<shiftrt_insn><mode>3"
9573 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9574 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9575 (match_operand:QI 2 "nonmemory_operand" "")))]
9577 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9579 ;; Avoid useless masking of count operand.
9580 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9581 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9583 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9586 (match_operand:SI 2 "nonimmediate_operand" "c")
9587 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9588 (clobber (reg:CC FLAGS_REG))]
9589 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9590 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9591 == GET_MODE_BITSIZE (<MODE>mode)-1"
9594 [(parallel [(set (match_dup 0)
9595 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9596 (clobber (reg:CC FLAGS_REG))])]
9598 if (can_create_pseudo_p ())
9599 operands [2] = force_reg (SImode, operands[2]);
9601 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9603 [(set_attr "type" "ishift")
9604 (set_attr "mode" "<MODE>")])
9606 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9607 [(set (match_operand:DWI 0 "register_operand" "=r")
9608 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9609 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9610 (clobber (reg:CC FLAGS_REG))]
9613 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9615 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9616 [(set_attr "type" "multi")])
9618 ;; By default we don't ask for a scratch register, because when DWImode
9619 ;; values are manipulated, registers are already at a premium. But if
9620 ;; we have one handy, we won't turn it away.
9623 [(match_scratch:DWIH 3 "r")
9624 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9626 (match_operand:<DWI> 1 "register_operand" "")
9627 (match_operand:QI 2 "nonmemory_operand" "")))
9628 (clobber (reg:CC FLAGS_REG))])
9632 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9634 (define_insn "x86_64_shrd"
9635 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9636 (ior:DI (ashiftrt:DI (match_dup 0)
9637 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9638 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9639 (minus:QI (const_int 64) (match_dup 2)))))
9640 (clobber (reg:CC FLAGS_REG))]
9642 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9643 [(set_attr "type" "ishift")
9644 (set_attr "prefix_0f" "1")
9645 (set_attr "mode" "DI")
9646 (set_attr "athlon_decode" "vector")
9647 (set_attr "amdfam10_decode" "vector")
9648 (set_attr "bdver1_decode" "vector")])
9650 (define_insn "x86_shrd"
9651 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9652 (ior:SI (ashiftrt:SI (match_dup 0)
9653 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9654 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9655 (minus:QI (const_int 32) (match_dup 2)))))
9656 (clobber (reg:CC FLAGS_REG))]
9658 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9659 [(set_attr "type" "ishift")
9660 (set_attr "prefix_0f" "1")
9661 (set_attr "mode" "SI")
9662 (set_attr "pent_pair" "np")
9663 (set_attr "athlon_decode" "vector")
9664 (set_attr "amdfam10_decode" "vector")
9665 (set_attr "bdver1_decode" "vector")])
9667 (define_insn "ashrdi3_cvt"
9668 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9669 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9670 (match_operand:QI 2 "const_int_operand" "")))
9671 (clobber (reg:CC FLAGS_REG))]
9672 "TARGET_64BIT && INTVAL (operands[2]) == 63
9673 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9674 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9677 sar{q}\t{%2, %0|%0, %2}"
9678 [(set_attr "type" "imovx,ishift")
9679 (set_attr "prefix_0f" "0,*")
9680 (set_attr "length_immediate" "0,*")
9681 (set_attr "modrm" "0,1")
9682 (set_attr "mode" "DI")])
9684 (define_insn "ashrsi3_cvt"
9685 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9686 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9687 (match_operand:QI 2 "const_int_operand" "")))
9688 (clobber (reg:CC FLAGS_REG))]
9689 "INTVAL (operands[2]) == 31
9690 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9691 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9694 sar{l}\t{%2, %0|%0, %2}"
9695 [(set_attr "type" "imovx,ishift")
9696 (set_attr "prefix_0f" "0,*")
9697 (set_attr "length_immediate" "0,*")
9698 (set_attr "modrm" "0,1")
9699 (set_attr "mode" "SI")])
9701 (define_insn "*ashrsi3_cvt_zext"
9702 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9704 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9705 (match_operand:QI 2 "const_int_operand" ""))))
9706 (clobber (reg:CC FLAGS_REG))]
9707 "TARGET_64BIT && INTVAL (operands[2]) == 31
9708 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9709 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9712 sar{l}\t{%2, %k0|%k0, %2}"
9713 [(set_attr "type" "imovx,ishift")
9714 (set_attr "prefix_0f" "0,*")
9715 (set_attr "length_immediate" "0,*")
9716 (set_attr "modrm" "0,1")
9717 (set_attr "mode" "SI")])
9719 (define_expand "x86_shift<mode>_adj_3"
9720 [(use (match_operand:SWI48 0 "register_operand" ""))
9721 (use (match_operand:SWI48 1 "register_operand" ""))
9722 (use (match_operand:QI 2 "register_operand" ""))]
9725 rtx label = gen_label_rtx ();
9728 emit_insn (gen_testqi_ccz_1 (operands[2],
9729 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9731 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9732 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9733 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9734 gen_rtx_LABEL_REF (VOIDmode, label),
9736 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9737 JUMP_LABEL (tmp) = label;
9739 emit_move_insn (operands[0], operands[1]);
9740 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9741 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9743 LABEL_NUSES (label) = 1;
9748 (define_insn "*<shiftrt_insn><mode>3_1"
9749 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9750 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9751 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9752 (clobber (reg:CC FLAGS_REG))]
9753 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9755 if (operands[2] == const1_rtx
9756 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9757 return "<shiftrt>{<imodesuffix>}\t%0";
9759 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9761 [(set_attr "type" "ishift")
9762 (set (attr "length_immediate")
9764 (and (match_operand 2 "const1_operand" "")
9765 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9768 (const_string "*")))
9769 (set_attr "mode" "<MODE>")])
9771 (define_insn "*<shiftrt_insn>si3_1_zext"
9772 [(set (match_operand:DI 0 "register_operand" "=r")
9774 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9775 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9776 (clobber (reg:CC FLAGS_REG))]
9777 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9779 if (operands[2] == const1_rtx
9780 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9781 return "<shiftrt>{l}\t%k0";
9783 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9785 [(set_attr "type" "ishift")
9786 (set (attr "length_immediate")
9788 (and (match_operand 2 "const1_operand" "")
9789 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9792 (const_string "*")))
9793 (set_attr "mode" "SI")])
9795 (define_insn "*<shiftrt_insn>qi3_1_slp"
9796 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9797 (any_shiftrt:QI (match_dup 0)
9798 (match_operand:QI 1 "nonmemory_operand" "cI")))
9799 (clobber (reg:CC FLAGS_REG))]
9800 "(optimize_function_for_size_p (cfun)
9801 || !TARGET_PARTIAL_REG_STALL
9802 || (operands[1] == const1_rtx
9805 if (operands[1] == const1_rtx
9806 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9807 return "<shiftrt>{b}\t%0";
9809 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9811 [(set_attr "type" "ishift1")
9812 (set (attr "length_immediate")
9814 (and (match_operand 1 "const1_operand" "")
9815 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9818 (const_string "*")))
9819 (set_attr "mode" "QI")])
9821 ;; This pattern can't accept a variable shift count, since shifts by
9822 ;; zero don't affect the flags. We assume that shifts by constant
9823 ;; zero are optimized away.
9824 (define_insn "*<shiftrt_insn><mode>3_cmp"
9825 [(set (reg FLAGS_REG)
9828 (match_operand:SWI 1 "nonimmediate_operand" "0")
9829 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9831 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9832 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9833 "(optimize_function_for_size_p (cfun)
9834 || !TARGET_PARTIAL_FLAG_REG_STALL
9835 || (operands[2] == const1_rtx
9837 && ix86_match_ccmode (insn, CCGOCmode)
9838 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9840 if (operands[2] == const1_rtx
9841 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9842 return "<shiftrt>{<imodesuffix>}\t%0";
9844 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9846 [(set_attr "type" "ishift")
9847 (set (attr "length_immediate")
9849 (and (match_operand 2 "const1_operand" "")
9850 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9853 (const_string "*")))
9854 (set_attr "mode" "<MODE>")])
9856 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9857 [(set (reg FLAGS_REG)
9859 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9860 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9862 (set (match_operand:DI 0 "register_operand" "=r")
9863 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9865 && (optimize_function_for_size_p (cfun)
9866 || !TARGET_PARTIAL_FLAG_REG_STALL
9867 || (operands[2] == const1_rtx
9869 && ix86_match_ccmode (insn, CCGOCmode)
9870 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9872 if (operands[2] == const1_rtx
9873 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9874 return "<shiftrt>{l}\t%k0";
9876 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9878 [(set_attr "type" "ishift")
9879 (set (attr "length_immediate")
9881 (and (match_operand 2 "const1_operand" "")
9882 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9885 (const_string "*")))
9886 (set_attr "mode" "SI")])
9888 (define_insn "*<shiftrt_insn><mode>3_cconly"
9889 [(set (reg FLAGS_REG)
9892 (match_operand:SWI 1 "register_operand" "0")
9893 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9895 (clobber (match_scratch:SWI 0 "=<r>"))]
9896 "(optimize_function_for_size_p (cfun)
9897 || !TARGET_PARTIAL_FLAG_REG_STALL
9898 || (operands[2] == const1_rtx
9900 && ix86_match_ccmode (insn, CCGOCmode)"
9902 if (operands[2] == const1_rtx
9903 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9904 return "<shiftrt>{<imodesuffix>}\t%0";
9906 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9908 [(set_attr "type" "ishift")
9909 (set (attr "length_immediate")
9911 (and (match_operand 2 "const1_operand" "")
9912 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9915 (const_string "*")))
9916 (set_attr "mode" "<MODE>")])
9918 ;; Rotate instructions
9920 (define_expand "<rotate_insn>ti3"
9921 [(set (match_operand:TI 0 "register_operand" "")
9922 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9923 (match_operand:QI 2 "nonmemory_operand" "")))]
9926 if (const_1_to_63_operand (operands[2], VOIDmode))
9927 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9928 (operands[0], operands[1], operands[2]));
9935 (define_expand "<rotate_insn>di3"
9936 [(set (match_operand:DI 0 "shiftdi_operand" "")
9937 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9938 (match_operand:QI 2 "nonmemory_operand" "")))]
9942 ix86_expand_binary_operator (<CODE>, DImode, operands);
9943 else if (const_1_to_31_operand (operands[2], VOIDmode))
9944 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9945 (operands[0], operands[1], operands[2]));
9952 (define_expand "<rotate_insn><mode>3"
9953 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9954 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9955 (match_operand:QI 2 "nonmemory_operand" "")))]
9957 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9959 ;; Avoid useless masking of count operand.
9960 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9961 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9963 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9966 (match_operand:SI 2 "nonimmediate_operand" "c")
9967 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9968 (clobber (reg:CC FLAGS_REG))]
9969 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9970 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9971 == GET_MODE_BITSIZE (<MODE>mode)-1"
9974 [(parallel [(set (match_dup 0)
9975 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9976 (clobber (reg:CC FLAGS_REG))])]
9978 if (can_create_pseudo_p ())
9979 operands [2] = force_reg (SImode, operands[2]);
9981 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9983 [(set_attr "type" "rotate")
9984 (set_attr "mode" "<MODE>")])
9986 ;; Implement rotation using two double-precision
9987 ;; shift instructions and a scratch register.
9989 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9990 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9991 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9992 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9993 (clobber (reg:CC FLAGS_REG))
9994 (clobber (match_scratch:DWIH 3 "=&r"))]
9998 [(set (match_dup 3) (match_dup 4))
10000 [(set (match_dup 4)
10001 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10002 (lshiftrt:DWIH (match_dup 5)
10003 (minus:QI (match_dup 6) (match_dup 2)))))
10004 (clobber (reg:CC FLAGS_REG))])
10006 [(set (match_dup 5)
10007 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10008 (lshiftrt:DWIH (match_dup 3)
10009 (minus:QI (match_dup 6) (match_dup 2)))))
10010 (clobber (reg:CC FLAGS_REG))])]
10012 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10014 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10017 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10018 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10019 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10020 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10021 (clobber (reg:CC FLAGS_REG))
10022 (clobber (match_scratch:DWIH 3 "=&r"))]
10026 [(set (match_dup 3) (match_dup 4))
10028 [(set (match_dup 4)
10029 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10030 (ashift:DWIH (match_dup 5)
10031 (minus:QI (match_dup 6) (match_dup 2)))))
10032 (clobber (reg:CC FLAGS_REG))])
10034 [(set (match_dup 5)
10035 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10036 (ashift:DWIH (match_dup 3)
10037 (minus:QI (match_dup 6) (match_dup 2)))))
10038 (clobber (reg:CC FLAGS_REG))])]
10040 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10042 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10045 (define_insn "*<rotate_insn><mode>3_1"
10046 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10047 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10048 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10049 (clobber (reg:CC FLAGS_REG))]
10050 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10052 if (operands[2] == const1_rtx
10053 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10054 return "<rotate>{<imodesuffix>}\t%0";
10056 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10058 [(set_attr "type" "rotate")
10059 (set (attr "length_immediate")
10061 (and (match_operand 2 "const1_operand" "")
10062 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10065 (const_string "*")))
10066 (set_attr "mode" "<MODE>")])
10068 (define_insn "*<rotate_insn>si3_1_zext"
10069 [(set (match_operand:DI 0 "register_operand" "=r")
10071 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10072 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10073 (clobber (reg:CC FLAGS_REG))]
10074 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10076 if (operands[2] == const1_rtx
10077 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10078 return "<rotate>{l}\t%k0";
10080 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10082 [(set_attr "type" "rotate")
10083 (set (attr "length_immediate")
10085 (and (match_operand 2 "const1_operand" "")
10086 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10089 (const_string "*")))
10090 (set_attr "mode" "SI")])
10092 (define_insn "*<rotate_insn>qi3_1_slp"
10093 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10094 (any_rotate:QI (match_dup 0)
10095 (match_operand:QI 1 "nonmemory_operand" "cI")))
10096 (clobber (reg:CC FLAGS_REG))]
10097 "(optimize_function_for_size_p (cfun)
10098 || !TARGET_PARTIAL_REG_STALL
10099 || (operands[1] == const1_rtx
10100 && TARGET_SHIFT1))"
10102 if (operands[1] == const1_rtx
10103 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10104 return "<rotate>{b}\t%0";
10106 return "<rotate>{b}\t{%1, %0|%0, %1}";
10108 [(set_attr "type" "rotate1")
10109 (set (attr "length_immediate")
10111 (and (match_operand 1 "const1_operand" "")
10112 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10115 (const_string "*")))
10116 (set_attr "mode" "QI")])
10119 [(set (match_operand:HI 0 "register_operand" "")
10120 (any_rotate:HI (match_dup 0) (const_int 8)))
10121 (clobber (reg:CC FLAGS_REG))]
10123 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10124 [(parallel [(set (strict_low_part (match_dup 0))
10125 (bswap:HI (match_dup 0)))
10126 (clobber (reg:CC FLAGS_REG))])])
10128 ;; Bit set / bit test instructions
10130 (define_expand "extv"
10131 [(set (match_operand:SI 0 "register_operand" "")
10132 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10133 (match_operand:SI 2 "const8_operand" "")
10134 (match_operand:SI 3 "const8_operand" "")))]
10137 /* Handle extractions from %ah et al. */
10138 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10141 /* From mips.md: extract_bit_field doesn't verify that our source
10142 matches the predicate, so check it again here. */
10143 if (! ext_register_operand (operands[1], VOIDmode))
10147 (define_expand "extzv"
10148 [(set (match_operand:SI 0 "register_operand" "")
10149 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10150 (match_operand:SI 2 "const8_operand" "")
10151 (match_operand:SI 3 "const8_operand" "")))]
10154 /* Handle extractions from %ah et al. */
10155 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10158 /* From mips.md: extract_bit_field doesn't verify that our source
10159 matches the predicate, so check it again here. */
10160 if (! ext_register_operand (operands[1], VOIDmode))
10164 (define_expand "insv"
10165 [(set (zero_extract (match_operand 0 "register_operand" "")
10166 (match_operand 1 "const_int_operand" "")
10167 (match_operand 2 "const_int_operand" ""))
10168 (match_operand 3 "register_operand" ""))]
10171 rtx (*gen_mov_insv_1) (rtx, rtx);
10173 if (ix86_expand_pinsr (operands))
10176 /* Handle insertions to %ah et al. */
10177 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10180 /* From mips.md: insert_bit_field doesn't verify that our source
10181 matches the predicate, so check it again here. */
10182 if (! ext_register_operand (operands[0], VOIDmode))
10185 gen_mov_insv_1 = (TARGET_64BIT
10186 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10188 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10192 ;; %%% bts, btr, btc, bt.
10193 ;; In general these instructions are *slow* when applied to memory,
10194 ;; since they enforce atomic operation. When applied to registers,
10195 ;; it depends on the cpu implementation. They're never faster than
10196 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10197 ;; no point. But in 64-bit, we can't hold the relevant immediates
10198 ;; within the instruction itself, so operating on bits in the high
10199 ;; 32-bits of a register becomes easier.
10201 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10202 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10203 ;; negdf respectively, so they can never be disabled entirely.
10205 (define_insn "*btsq"
10206 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10208 (match_operand:DI 1 "const_0_to_63_operand" ""))
10210 (clobber (reg:CC FLAGS_REG))]
10211 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10212 "bts{q}\t{%1, %0|%0, %1}"
10213 [(set_attr "type" "alu1")
10214 (set_attr "prefix_0f" "1")
10215 (set_attr "mode" "DI")])
10217 (define_insn "*btrq"
10218 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10220 (match_operand:DI 1 "const_0_to_63_operand" ""))
10222 (clobber (reg:CC FLAGS_REG))]
10223 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10224 "btr{q}\t{%1, %0|%0, %1}"
10225 [(set_attr "type" "alu1")
10226 (set_attr "prefix_0f" "1")
10227 (set_attr "mode" "DI")])
10229 (define_insn "*btcq"
10230 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10232 (match_operand:DI 1 "const_0_to_63_operand" ""))
10233 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10234 (clobber (reg:CC FLAGS_REG))]
10235 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10236 "btc{q}\t{%1, %0|%0, %1}"
10237 [(set_attr "type" "alu1")
10238 (set_attr "prefix_0f" "1")
10239 (set_attr "mode" "DI")])
10241 ;; Allow Nocona to avoid these instructions if a register is available.
10244 [(match_scratch:DI 2 "r")
10245 (parallel [(set (zero_extract:DI
10246 (match_operand:DI 0 "register_operand" "")
10248 (match_operand:DI 1 "const_0_to_63_operand" ""))
10250 (clobber (reg:CC FLAGS_REG))])]
10251 "TARGET_64BIT && !TARGET_USE_BT"
10254 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10257 if (HOST_BITS_PER_WIDE_INT >= 64)
10258 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10259 else if (i < HOST_BITS_PER_WIDE_INT)
10260 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10262 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10264 op1 = immed_double_const (lo, hi, DImode);
10267 emit_move_insn (operands[2], op1);
10271 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10276 [(match_scratch:DI 2 "r")
10277 (parallel [(set (zero_extract:DI
10278 (match_operand:DI 0 "register_operand" "")
10280 (match_operand:DI 1 "const_0_to_63_operand" ""))
10282 (clobber (reg:CC FLAGS_REG))])]
10283 "TARGET_64BIT && !TARGET_USE_BT"
10286 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10289 if (HOST_BITS_PER_WIDE_INT >= 64)
10290 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10291 else if (i < HOST_BITS_PER_WIDE_INT)
10292 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10294 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10296 op1 = immed_double_const (~lo, ~hi, DImode);
10299 emit_move_insn (operands[2], op1);
10303 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10308 [(match_scratch:DI 2 "r")
10309 (parallel [(set (zero_extract:DI
10310 (match_operand:DI 0 "register_operand" "")
10312 (match_operand:DI 1 "const_0_to_63_operand" ""))
10313 (not:DI (zero_extract:DI
10314 (match_dup 0) (const_int 1) (match_dup 1))))
10315 (clobber (reg:CC FLAGS_REG))])]
10316 "TARGET_64BIT && !TARGET_USE_BT"
10319 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10322 if (HOST_BITS_PER_WIDE_INT >= 64)
10323 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10324 else if (i < HOST_BITS_PER_WIDE_INT)
10325 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10327 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10329 op1 = immed_double_const (lo, hi, DImode);
10332 emit_move_insn (operands[2], op1);
10336 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10340 (define_insn "*bt<mode>"
10341 [(set (reg:CCC FLAGS_REG)
10343 (zero_extract:SWI48
10344 (match_operand:SWI48 0 "register_operand" "r")
10346 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10348 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10349 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10350 [(set_attr "type" "alu1")
10351 (set_attr "prefix_0f" "1")
10352 (set_attr "mode" "<MODE>")])
10354 ;; Store-flag instructions.
10356 ;; For all sCOND expanders, also expand the compare or test insn that
10357 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10359 (define_insn_and_split "*setcc_di_1"
10360 [(set (match_operand:DI 0 "register_operand" "=q")
10361 (match_operator:DI 1 "ix86_comparison_operator"
10362 [(reg FLAGS_REG) (const_int 0)]))]
10363 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10365 "&& reload_completed"
10366 [(set (match_dup 2) (match_dup 1))
10367 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10369 PUT_MODE (operands[1], QImode);
10370 operands[2] = gen_lowpart (QImode, operands[0]);
10373 (define_insn_and_split "*setcc_si_1_and"
10374 [(set (match_operand:SI 0 "register_operand" "=q")
10375 (match_operator:SI 1 "ix86_comparison_operator"
10376 [(reg FLAGS_REG) (const_int 0)]))
10377 (clobber (reg:CC FLAGS_REG))]
10378 "!TARGET_PARTIAL_REG_STALL
10379 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10381 "&& reload_completed"
10382 [(set (match_dup 2) (match_dup 1))
10383 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10384 (clobber (reg:CC FLAGS_REG))])]
10386 PUT_MODE (operands[1], QImode);
10387 operands[2] = gen_lowpart (QImode, operands[0]);
10390 (define_insn_and_split "*setcc_si_1_movzbl"
10391 [(set (match_operand:SI 0 "register_operand" "=q")
10392 (match_operator:SI 1 "ix86_comparison_operator"
10393 [(reg FLAGS_REG) (const_int 0)]))]
10394 "!TARGET_PARTIAL_REG_STALL
10395 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10397 "&& reload_completed"
10398 [(set (match_dup 2) (match_dup 1))
10399 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10401 PUT_MODE (operands[1], QImode);
10402 operands[2] = gen_lowpart (QImode, operands[0]);
10405 (define_insn "*setcc_qi"
10406 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10407 (match_operator:QI 1 "ix86_comparison_operator"
10408 [(reg FLAGS_REG) (const_int 0)]))]
10411 [(set_attr "type" "setcc")
10412 (set_attr "mode" "QI")])
10414 (define_insn "*setcc_qi_slp"
10415 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10416 (match_operator:QI 1 "ix86_comparison_operator"
10417 [(reg FLAGS_REG) (const_int 0)]))]
10420 [(set_attr "type" "setcc")
10421 (set_attr "mode" "QI")])
10423 ;; In general it is not safe to assume too much about CCmode registers,
10424 ;; so simplify-rtx stops when it sees a second one. Under certain
10425 ;; conditions this is safe on x86, so help combine not create
10432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10433 (ne:QI (match_operator 1 "ix86_comparison_operator"
10434 [(reg FLAGS_REG) (const_int 0)])
10437 [(set (match_dup 0) (match_dup 1))]
10438 "PUT_MODE (operands[1], QImode);")
10441 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10442 (ne:QI (match_operator 1 "ix86_comparison_operator"
10443 [(reg FLAGS_REG) (const_int 0)])
10446 [(set (match_dup 0) (match_dup 1))]
10447 "PUT_MODE (operands[1], QImode);")
10450 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10451 (eq:QI (match_operator 1 "ix86_comparison_operator"
10452 [(reg FLAGS_REG) (const_int 0)])
10455 [(set (match_dup 0) (match_dup 1))]
10457 rtx new_op1 = copy_rtx (operands[1]);
10458 operands[1] = new_op1;
10459 PUT_MODE (new_op1, QImode);
10460 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10461 GET_MODE (XEXP (new_op1, 0))));
10463 /* Make sure that (a) the CCmode we have for the flags is strong
10464 enough for the reversed compare or (b) we have a valid FP compare. */
10465 if (! ix86_comparison_operator (new_op1, VOIDmode))
10470 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10471 (eq:QI (match_operator 1 "ix86_comparison_operator"
10472 [(reg FLAGS_REG) (const_int 0)])
10475 [(set (match_dup 0) (match_dup 1))]
10477 rtx new_op1 = copy_rtx (operands[1]);
10478 operands[1] = new_op1;
10479 PUT_MODE (new_op1, QImode);
10480 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10481 GET_MODE (XEXP (new_op1, 0))));
10483 /* Make sure that (a) the CCmode we have for the flags is strong
10484 enough for the reversed compare or (b) we have a valid FP compare. */
10485 if (! ix86_comparison_operator (new_op1, VOIDmode))
10489 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10490 ;; subsequent logical operations are used to imitate conditional moves.
10491 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10494 (define_insn "setcc_<mode>_sse"
10495 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10496 (match_operator:MODEF 3 "sse_comparison_operator"
10497 [(match_operand:MODEF 1 "register_operand" "0,x")
10498 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10499 "SSE_FLOAT_MODE_P (<MODE>mode)"
10501 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10502 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10503 [(set_attr "isa" "noavx,avx")
10504 (set_attr "type" "ssecmp")
10505 (set_attr "length_immediate" "1")
10506 (set_attr "prefix" "orig,vex")
10507 (set_attr "mode" "<MODE>")])
10509 ;; Basic conditional jump instructions.
10510 ;; We ignore the overflow flag for signed branch instructions.
10512 (define_insn "*jcc_1"
10514 (if_then_else (match_operator 1 "ix86_comparison_operator"
10515 [(reg FLAGS_REG) (const_int 0)])
10516 (label_ref (match_operand 0 "" ""))
10520 [(set_attr "type" "ibr")
10521 (set_attr "modrm" "0")
10522 (set (attr "length")
10523 (if_then_else (and (ge (minus (match_dup 0) (pc))
10525 (lt (minus (match_dup 0) (pc))
10530 (define_insn "*jcc_2"
10532 (if_then_else (match_operator 1 "ix86_comparison_operator"
10533 [(reg FLAGS_REG) (const_int 0)])
10535 (label_ref (match_operand 0 "" ""))))]
10538 [(set_attr "type" "ibr")
10539 (set_attr "modrm" "0")
10540 (set (attr "length")
10541 (if_then_else (and (ge (minus (match_dup 0) (pc))
10543 (lt (minus (match_dup 0) (pc))
10548 ;; In general it is not safe to assume too much about CCmode registers,
10549 ;; so simplify-rtx stops when it sees a second one. Under certain
10550 ;; conditions this is safe on x86, so help combine not create
10558 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10559 [(reg FLAGS_REG) (const_int 0)])
10561 (label_ref (match_operand 1 "" ""))
10565 (if_then_else (match_dup 0)
10566 (label_ref (match_dup 1))
10568 "PUT_MODE (operands[0], VOIDmode);")
10572 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10573 [(reg FLAGS_REG) (const_int 0)])
10575 (label_ref (match_operand 1 "" ""))
10579 (if_then_else (match_dup 0)
10580 (label_ref (match_dup 1))
10583 rtx new_op0 = copy_rtx (operands[0]);
10584 operands[0] = new_op0;
10585 PUT_MODE (new_op0, VOIDmode);
10586 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10587 GET_MODE (XEXP (new_op0, 0))));
10589 /* Make sure that (a) the CCmode we have for the flags is strong
10590 enough for the reversed compare or (b) we have a valid FP compare. */
10591 if (! ix86_comparison_operator (new_op0, VOIDmode))
10595 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10596 ;; pass generates from shift insn with QImode operand. Actually, the mode
10597 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10598 ;; appropriate modulo of the bit offset value.
10600 (define_insn_and_split "*jcc_bt<mode>"
10602 (if_then_else (match_operator 0 "bt_comparison_operator"
10603 [(zero_extract:SWI48
10604 (match_operand:SWI48 1 "register_operand" "r")
10607 (match_operand:QI 2 "register_operand" "r")))
10609 (label_ref (match_operand 3 "" ""))
10611 (clobber (reg:CC FLAGS_REG))]
10612 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10615 [(set (reg:CCC FLAGS_REG)
10617 (zero_extract:SWI48
10623 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10624 (label_ref (match_dup 3))
10627 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10629 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10632 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10633 ;; also for DImode, this is what combine produces.
10634 (define_insn_and_split "*jcc_bt<mode>_mask"
10636 (if_then_else (match_operator 0 "bt_comparison_operator"
10637 [(zero_extract:SWI48
10638 (match_operand:SWI48 1 "register_operand" "r")
10641 (match_operand:SI 2 "register_operand" "r")
10642 (match_operand:SI 3 "const_int_operand" "n")))])
10643 (label_ref (match_operand 4 "" ""))
10645 (clobber (reg:CC FLAGS_REG))]
10646 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10647 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10648 == GET_MODE_BITSIZE (<MODE>mode)-1"
10651 [(set (reg:CCC FLAGS_REG)
10653 (zero_extract:SWI48
10659 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10660 (label_ref (match_dup 4))
10663 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10665 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10668 (define_insn_and_split "*jcc_btsi_1"
10670 (if_then_else (match_operator 0 "bt_comparison_operator"
10673 (match_operand:SI 1 "register_operand" "r")
10674 (match_operand:QI 2 "register_operand" "r"))
10677 (label_ref (match_operand 3 "" ""))
10679 (clobber (reg:CC FLAGS_REG))]
10680 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10683 [(set (reg:CCC FLAGS_REG)
10691 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10692 (label_ref (match_dup 3))
10695 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10697 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10700 ;; avoid useless masking of bit offset operand
10701 (define_insn_and_split "*jcc_btsi_mask_1"
10704 (match_operator 0 "bt_comparison_operator"
10707 (match_operand:SI 1 "register_operand" "r")
10710 (match_operand:SI 2 "register_operand" "r")
10711 (match_operand:SI 3 "const_int_operand" "n")) 0))
10714 (label_ref (match_operand 4 "" ""))
10716 (clobber (reg:CC FLAGS_REG))]
10717 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10718 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10721 [(set (reg:CCC FLAGS_REG)
10729 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10730 (label_ref (match_dup 4))
10732 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10734 ;; Define combination compare-and-branch fp compare instructions to help
10737 (define_insn "*fp_jcc_1_387"
10739 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10740 [(match_operand 1 "register_operand" "f")
10741 (match_operand 2 "nonimmediate_operand" "fm")])
10742 (label_ref (match_operand 3 "" ""))
10744 (clobber (reg:CCFP FPSR_REG))
10745 (clobber (reg:CCFP FLAGS_REG))
10746 (clobber (match_scratch:HI 4 "=a"))]
10748 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10749 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10750 && SELECT_CC_MODE (GET_CODE (operands[0]),
10751 operands[1], operands[2]) == CCFPmode
10755 (define_insn "*fp_jcc_1r_387"
10757 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10758 [(match_operand 1 "register_operand" "f")
10759 (match_operand 2 "nonimmediate_operand" "fm")])
10761 (label_ref (match_operand 3 "" ""))))
10762 (clobber (reg:CCFP FPSR_REG))
10763 (clobber (reg:CCFP FLAGS_REG))
10764 (clobber (match_scratch:HI 4 "=a"))]
10766 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10767 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10768 && SELECT_CC_MODE (GET_CODE (operands[0]),
10769 operands[1], operands[2]) == CCFPmode
10773 (define_insn "*fp_jcc_2_387"
10775 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10776 [(match_operand 1 "register_operand" "f")
10777 (match_operand 2 "register_operand" "f")])
10778 (label_ref (match_operand 3 "" ""))
10780 (clobber (reg:CCFP FPSR_REG))
10781 (clobber (reg:CCFP FLAGS_REG))
10782 (clobber (match_scratch:HI 4 "=a"))]
10783 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10784 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10788 (define_insn "*fp_jcc_2r_387"
10790 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10791 [(match_operand 1 "register_operand" "f")
10792 (match_operand 2 "register_operand" "f")])
10794 (label_ref (match_operand 3 "" ""))))
10795 (clobber (reg:CCFP FPSR_REG))
10796 (clobber (reg:CCFP FLAGS_REG))
10797 (clobber (match_scratch:HI 4 "=a"))]
10798 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10799 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10803 (define_insn "*fp_jcc_3_387"
10805 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10806 [(match_operand 1 "register_operand" "f")
10807 (match_operand 2 "const0_operand" "")])
10808 (label_ref (match_operand 3 "" ""))
10810 (clobber (reg:CCFP FPSR_REG))
10811 (clobber (reg:CCFP FLAGS_REG))
10812 (clobber (match_scratch:HI 4 "=a"))]
10813 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10814 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10815 && SELECT_CC_MODE (GET_CODE (operands[0]),
10816 operands[1], operands[2]) == CCFPmode
10822 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10823 [(match_operand 1 "register_operand" "")
10824 (match_operand 2 "nonimmediate_operand" "")])
10825 (match_operand 3 "" "")
10826 (match_operand 4 "" "")))
10827 (clobber (reg:CCFP FPSR_REG))
10828 (clobber (reg:CCFP FLAGS_REG))]
10832 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10833 operands[3], operands[4], NULL_RTX, NULL_RTX);
10839 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10840 [(match_operand 1 "register_operand" "")
10841 (match_operand 2 "general_operand" "")])
10842 (match_operand 3 "" "")
10843 (match_operand 4 "" "")))
10844 (clobber (reg:CCFP FPSR_REG))
10845 (clobber (reg:CCFP FLAGS_REG))
10846 (clobber (match_scratch:HI 5 "=a"))]
10850 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10851 operands[3], operands[4], operands[5], NULL_RTX);
10855 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10856 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10857 ;; with a precedence over other operators and is always put in the first
10858 ;; place. Swap condition and operands to match ficom instruction.
10860 (define_insn "*fp_jcc_4_<mode>_387"
10863 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10864 [(match_operator 1 "float_operator"
10865 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10866 (match_operand 3 "register_operand" "f,f")])
10867 (label_ref (match_operand 4 "" ""))
10869 (clobber (reg:CCFP FPSR_REG))
10870 (clobber (reg:CCFP FLAGS_REG))
10871 (clobber (match_scratch:HI 5 "=a,a"))]
10872 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10873 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10874 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10875 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10882 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10883 [(match_operator 1 "float_operator"
10884 [(match_operand:SWI24 2 "memory_operand" "")])
10885 (match_operand 3 "register_operand" "")])
10886 (match_operand 4 "" "")
10887 (match_operand 5 "" "")))
10888 (clobber (reg:CCFP FPSR_REG))
10889 (clobber (reg:CCFP FLAGS_REG))
10890 (clobber (match_scratch:HI 6 "=a"))]
10894 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10896 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10897 operands[3], operands[7],
10898 operands[4], operands[5], operands[6], NULL_RTX);
10902 ;; %%% Kill this when reload knows how to do it.
10906 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10907 [(match_operator 1 "float_operator"
10908 [(match_operand:SWI24 2 "register_operand" "")])
10909 (match_operand 3 "register_operand" "")])
10910 (match_operand 4 "" "")
10911 (match_operand 5 "" "")))
10912 (clobber (reg:CCFP FPSR_REG))
10913 (clobber (reg:CCFP FLAGS_REG))
10914 (clobber (match_scratch:HI 6 "=a"))]
10918 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10919 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10921 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10922 operands[3], operands[7],
10923 operands[4], operands[5], operands[6], operands[2]);
10927 ;; Unconditional and other jump instructions
10929 (define_insn "jump"
10931 (label_ref (match_operand 0 "" "")))]
10934 [(set_attr "type" "ibr")
10935 (set (attr "length")
10936 (if_then_else (and (ge (minus (match_dup 0) (pc))
10938 (lt (minus (match_dup 0) (pc))
10942 (set_attr "modrm" "0")])
10944 (define_expand "indirect_jump"
10945 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10949 (define_insn "*indirect_jump"
10950 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10953 [(set_attr "type" "ibr")
10954 (set_attr "length_immediate" "0")])
10956 (define_expand "tablejump"
10957 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10958 (use (label_ref (match_operand 1 "" "")))])]
10961 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10962 relative. Convert the relative address to an absolute address. */
10966 enum rtx_code code;
10968 /* We can't use @GOTOFF for text labels on VxWorks;
10969 see gotoff_operand. */
10970 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10974 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10976 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10980 op1 = pic_offset_table_rtx;
10985 op0 = pic_offset_table_rtx;
10989 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10994 (define_insn "*tablejump_1"
10995 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
10996 (use (label_ref (match_operand 1 "" "")))]
10999 [(set_attr "type" "ibr")
11000 (set_attr "length_immediate" "0")])
11002 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11005 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11006 (set (match_operand:QI 1 "register_operand" "")
11007 (match_operator:QI 2 "ix86_comparison_operator"
11008 [(reg FLAGS_REG) (const_int 0)]))
11009 (set (match_operand 3 "q_regs_operand" "")
11010 (zero_extend (match_dup 1)))]
11011 "(peep2_reg_dead_p (3, operands[1])
11012 || operands_match_p (operands[1], operands[3]))
11013 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11014 [(set (match_dup 4) (match_dup 0))
11015 (set (strict_low_part (match_dup 5))
11018 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11019 operands[5] = gen_lowpart (QImode, operands[3]);
11020 ix86_expand_clear (operands[3]);
11023 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11026 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11027 (set (match_operand:QI 1 "register_operand" "")
11028 (match_operator:QI 2 "ix86_comparison_operator"
11029 [(reg FLAGS_REG) (const_int 0)]))
11030 (parallel [(set (match_operand 3 "q_regs_operand" "")
11031 (zero_extend (match_dup 1)))
11032 (clobber (reg:CC FLAGS_REG))])]
11033 "(peep2_reg_dead_p (3, operands[1])
11034 || operands_match_p (operands[1], operands[3]))
11035 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11036 [(set (match_dup 4) (match_dup 0))
11037 (set (strict_low_part (match_dup 5))
11040 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11041 operands[5] = gen_lowpart (QImode, operands[3]);
11042 ix86_expand_clear (operands[3]);
11045 ;; Call instructions.
11047 ;; The predicates normally associated with named expanders are not properly
11048 ;; checked for calls. This is a bug in the generic code, but it isn't that
11049 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11051 ;; P6 processors will jump to the address after the decrement when %esp
11052 ;; is used as a call operand, so they will execute return address as a code.
11053 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11055 ;; Register constraint for call instruction.
11056 (define_mode_attr c [(SI "l") (DI "r")])
11058 ;; Call subroutine returning no value.
11060 (define_expand "call"
11061 [(call (match_operand:QI 0 "" "")
11062 (match_operand 1 "" ""))
11063 (use (match_operand 2 "" ""))]
11066 ix86_expand_call (NULL, operands[0], operands[1],
11067 operands[2], NULL, false);
11071 (define_expand "sibcall"
11072 [(call (match_operand:QI 0 "" "")
11073 (match_operand 1 "" ""))
11074 (use (match_operand 2 "" ""))]
11077 ix86_expand_call (NULL, operands[0], operands[1],
11078 operands[2], NULL, true);
11082 (define_insn_and_split "*call_vzeroupper"
11083 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11084 (match_operand 1 "" ""))
11085 (unspec [(match_operand 2 "const_int_operand" "")]
11086 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11087 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11089 "&& reload_completed"
11091 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11092 [(set_attr "type" "call")])
11094 (define_insn "*call"
11095 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11096 (match_operand 1 "" ""))]
11097 "!SIBLING_CALL_P (insn)"
11098 "* return ix86_output_call_insn (insn, operands[0]);"
11099 [(set_attr "type" "call")])
11101 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11103 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11104 (match_operand 1 "" ""))
11105 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11106 (clobber (reg:TI XMM6_REG))
11107 (clobber (reg:TI XMM7_REG))
11108 (clobber (reg:TI XMM8_REG))
11109 (clobber (reg:TI XMM9_REG))
11110 (clobber (reg:TI XMM10_REG))
11111 (clobber (reg:TI XMM11_REG))
11112 (clobber (reg:TI XMM12_REG))
11113 (clobber (reg:TI XMM13_REG))
11114 (clobber (reg:TI XMM14_REG))
11115 (clobber (reg:TI XMM15_REG))
11116 (clobber (reg:DI SI_REG))
11117 (clobber (reg:DI DI_REG))])
11118 (unspec [(match_operand 2 "const_int_operand" "")]
11119 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11120 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11122 "&& reload_completed"
11124 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11125 [(set_attr "type" "call")])
11127 (define_insn "*call_rex64_ms_sysv"
11128 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11129 (match_operand 1 "" ""))
11130 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11131 (clobber (reg:TI XMM6_REG))
11132 (clobber (reg:TI XMM7_REG))
11133 (clobber (reg:TI XMM8_REG))
11134 (clobber (reg:TI XMM9_REG))
11135 (clobber (reg:TI XMM10_REG))
11136 (clobber (reg:TI XMM11_REG))
11137 (clobber (reg:TI XMM12_REG))
11138 (clobber (reg:TI XMM13_REG))
11139 (clobber (reg:TI XMM14_REG))
11140 (clobber (reg:TI XMM15_REG))
11141 (clobber (reg:DI SI_REG))
11142 (clobber (reg:DI DI_REG))]
11143 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11144 "* return ix86_output_call_insn (insn, operands[0]);"
11145 [(set_attr "type" "call")])
11147 (define_insn_and_split "*sibcall_vzeroupper"
11148 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11149 (match_operand 1 "" ""))
11150 (unspec [(match_operand 2 "const_int_operand" "")]
11151 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11152 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11154 "&& reload_completed"
11156 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11157 [(set_attr "type" "call")])
11159 (define_insn "*sibcall"
11160 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11161 (match_operand 1 "" ""))]
11162 "SIBLING_CALL_P (insn)"
11163 "* return ix86_output_call_insn (insn, operands[0]);"
11164 [(set_attr "type" "call")])
11166 (define_expand "call_pop"
11167 [(parallel [(call (match_operand:QI 0 "" "")
11168 (match_operand:SI 1 "" ""))
11169 (set (reg:SI SP_REG)
11170 (plus:SI (reg:SI SP_REG)
11171 (match_operand:SI 3 "" "")))])]
11174 ix86_expand_call (NULL, operands[0], operands[1],
11175 operands[2], operands[3], false);
11179 (define_insn_and_split "*call_pop_vzeroupper"
11181 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11182 (match_operand:SI 1 "" ""))
11183 (set (reg:SI SP_REG)
11184 (plus:SI (reg:SI SP_REG)
11185 (match_operand:SI 2 "immediate_operand" "i")))])
11186 (unspec [(match_operand 3 "const_int_operand" "")]
11187 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11188 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11190 "&& reload_completed"
11192 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11193 [(set_attr "type" "call")])
11195 (define_insn "*call_pop"
11196 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11197 (match_operand 1 "" ""))
11198 (set (reg:SI SP_REG)
11199 (plus:SI (reg:SI SP_REG)
11200 (match_operand:SI 2 "immediate_operand" "i")))]
11201 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11202 "* return ix86_output_call_insn (insn, operands[0]);"
11203 [(set_attr "type" "call")])
11205 (define_insn_and_split "*sibcall_pop_vzeroupper"
11207 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11208 (match_operand 1 "" ""))
11209 (set (reg:SI SP_REG)
11210 (plus:SI (reg:SI SP_REG)
11211 (match_operand:SI 2 "immediate_operand" "i")))])
11212 (unspec [(match_operand 3 "const_int_operand" "")]
11213 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11214 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11216 "&& reload_completed"
11218 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11219 [(set_attr "type" "call")])
11221 (define_insn "*sibcall_pop"
11222 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11223 (match_operand 1 "" ""))
11224 (set (reg:SI SP_REG)
11225 (plus:SI (reg:SI SP_REG)
11226 (match_operand:SI 2 "immediate_operand" "i")))]
11227 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11228 "* return ix86_output_call_insn (insn, operands[0]);"
11229 [(set_attr "type" "call")])
11231 ;; Call subroutine, returning value in operand 0
11233 (define_expand "call_value"
11234 [(set (match_operand 0 "" "")
11235 (call (match_operand:QI 1 "" "")
11236 (match_operand 2 "" "")))
11237 (use (match_operand 3 "" ""))]
11240 ix86_expand_call (operands[0], operands[1], operands[2],
11241 operands[3], NULL, false);
11245 (define_expand "sibcall_value"
11246 [(set (match_operand 0 "" "")
11247 (call (match_operand:QI 1 "" "")
11248 (match_operand 2 "" "")))
11249 (use (match_operand 3 "" ""))]
11252 ix86_expand_call (operands[0], operands[1], operands[2],
11253 operands[3], NULL, true);
11257 (define_insn_and_split "*call_value_vzeroupper"
11258 [(set (match_operand 0 "" "")
11259 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11260 (match_operand 2 "" "")))
11261 (unspec [(match_operand 3 "const_int_operand" "")]
11262 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11263 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11265 "&& reload_completed"
11267 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11268 [(set_attr "type" "callv")])
11270 (define_insn "*call_value"
11271 [(set (match_operand 0 "" "")
11272 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11273 (match_operand 2 "" "")))]
11274 "!SIBLING_CALL_P (insn)"
11275 "* return ix86_output_call_insn (insn, operands[1]);"
11276 [(set_attr "type" "callv")])
11278 (define_insn_and_split "*sibcall_value_vzeroupper"
11279 [(set (match_operand 0 "" "")
11280 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11281 (match_operand 2 "" "")))
11282 (unspec [(match_operand 3 "const_int_operand" "")]
11283 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11284 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11286 "&& reload_completed"
11288 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11289 [(set_attr "type" "callv")])
11291 (define_insn "*sibcall_value"
11292 [(set (match_operand 0 "" "")
11293 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11294 (match_operand 2 "" "")))]
11295 "SIBLING_CALL_P (insn)"
11296 "* return ix86_output_call_insn (insn, operands[1]);"
11297 [(set_attr "type" "callv")])
11299 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11301 [(set (match_operand 0 "" "")
11302 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11303 (match_operand 2 "" "")))
11304 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11305 (clobber (reg:TI XMM6_REG))
11306 (clobber (reg:TI XMM7_REG))
11307 (clobber (reg:TI XMM8_REG))
11308 (clobber (reg:TI XMM9_REG))
11309 (clobber (reg:TI XMM10_REG))
11310 (clobber (reg:TI XMM11_REG))
11311 (clobber (reg:TI XMM12_REG))
11312 (clobber (reg:TI XMM13_REG))
11313 (clobber (reg:TI XMM14_REG))
11314 (clobber (reg:TI XMM15_REG))
11315 (clobber (reg:DI SI_REG))
11316 (clobber (reg:DI DI_REG))])
11317 (unspec [(match_operand 3 "const_int_operand" "")]
11318 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11319 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11321 "&& reload_completed"
11323 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11324 [(set_attr "type" "callv")])
11326 (define_insn "*call_value_rex64_ms_sysv"
11327 [(set (match_operand 0 "" "")
11328 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11329 (match_operand 2 "" "")))
11330 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11331 (clobber (reg:TI XMM6_REG))
11332 (clobber (reg:TI XMM7_REG))
11333 (clobber (reg:TI XMM8_REG))
11334 (clobber (reg:TI XMM9_REG))
11335 (clobber (reg:TI XMM10_REG))
11336 (clobber (reg:TI XMM11_REG))
11337 (clobber (reg:TI XMM12_REG))
11338 (clobber (reg:TI XMM13_REG))
11339 (clobber (reg:TI XMM14_REG))
11340 (clobber (reg:TI XMM15_REG))
11341 (clobber (reg:DI SI_REG))
11342 (clobber (reg:DI DI_REG))]
11343 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11344 "* return ix86_output_call_insn (insn, operands[1]);"
11345 [(set_attr "type" "callv")])
11347 (define_expand "call_value_pop"
11348 [(parallel [(set (match_operand 0 "" "")
11349 (call (match_operand:QI 1 "" "")
11350 (match_operand:SI 2 "" "")))
11351 (set (reg:SI SP_REG)
11352 (plus:SI (reg:SI SP_REG)
11353 (match_operand:SI 4 "" "")))])]
11356 ix86_expand_call (operands[0], operands[1], operands[2],
11357 operands[3], operands[4], false);
11361 (define_insn_and_split "*call_value_pop_vzeroupper"
11363 [(set (match_operand 0 "" "")
11364 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11365 (match_operand 2 "" "")))
11366 (set (reg:SI SP_REG)
11367 (plus:SI (reg:SI SP_REG)
11368 (match_operand:SI 3 "immediate_operand" "i")))])
11369 (unspec [(match_operand 4 "const_int_operand" "")]
11370 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11371 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11373 "&& reload_completed"
11375 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11376 [(set_attr "type" "callv")])
11378 (define_insn "*call_value_pop"
11379 [(set (match_operand 0 "" "")
11380 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11381 (match_operand 2 "" "")))
11382 (set (reg:SI SP_REG)
11383 (plus:SI (reg:SI SP_REG)
11384 (match_operand:SI 3 "immediate_operand" "i")))]
11385 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11386 "* return ix86_output_call_insn (insn, operands[1]);"
11387 [(set_attr "type" "callv")])
11389 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11391 [(set (match_operand 0 "" "")
11392 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11393 (match_operand 2 "" "")))
11394 (set (reg:SI SP_REG)
11395 (plus:SI (reg:SI SP_REG)
11396 (match_operand:SI 3 "immediate_operand" "i")))])
11397 (unspec [(match_operand 4 "const_int_operand" "")]
11398 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11399 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11401 "&& reload_completed"
11403 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11404 [(set_attr "type" "callv")])
11406 (define_insn "*sibcall_value_pop"
11407 [(set (match_operand 0 "" "")
11408 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11409 (match_operand 2 "" "")))
11410 (set (reg:SI SP_REG)
11411 (plus:SI (reg:SI SP_REG)
11412 (match_operand:SI 3 "immediate_operand" "i")))]
11413 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11414 "* return ix86_output_call_insn (insn, operands[1]);"
11415 [(set_attr "type" "callv")])
11417 ;; Call subroutine returning any type.
11419 (define_expand "untyped_call"
11420 [(parallel [(call (match_operand 0 "" "")
11422 (match_operand 1 "" "")
11423 (match_operand 2 "" "")])]
11428 /* In order to give reg-stack an easier job in validating two
11429 coprocessor registers as containing a possible return value,
11430 simply pretend the untyped call returns a complex long double
11433 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11434 and should have the default ABI. */
11436 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11437 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11438 operands[0], const0_rtx,
11439 GEN_INT ((TARGET_64BIT
11440 ? (ix86_abi == SYSV_ABI
11441 ? X86_64_SSE_REGPARM_MAX
11442 : X86_64_MS_SSE_REGPARM_MAX)
11443 : X86_32_SSE_REGPARM_MAX)
11447 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11449 rtx set = XVECEXP (operands[2], 0, i);
11450 emit_move_insn (SET_DEST (set), SET_SRC (set));
11453 /* The optimizer does not know that the call sets the function value
11454 registers we stored in the result block. We avoid problems by
11455 claiming that all hard registers are used and clobbered at this
11457 emit_insn (gen_blockage ());
11462 ;; Prologue and epilogue instructions
11464 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11465 ;; all of memory. This blocks insns from being moved across this point.
11467 (define_insn "blockage"
11468 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11471 [(set_attr "length" "0")])
11473 ;; Do not schedule instructions accessing memory across this point.
11475 (define_expand "memory_blockage"
11476 [(set (match_dup 0)
11477 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11480 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11481 MEM_VOLATILE_P (operands[0]) = 1;
11484 (define_insn "*memory_blockage"
11485 [(set (match_operand:BLK 0 "" "")
11486 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11489 [(set_attr "length" "0")])
11491 ;; As USE insns aren't meaningful after reload, this is used instead
11492 ;; to prevent deleting instructions setting registers for PIC code
11493 (define_insn "prologue_use"
11494 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11497 [(set_attr "length" "0")])
11499 ;; Insn emitted into the body of a function to return from a function.
11500 ;; This is only done if the function's epilogue is known to be simple.
11501 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11503 (define_expand "return"
11505 "ix86_can_use_return_insn_p ()"
11507 if (crtl->args.pops_args)
11509 rtx popc = GEN_INT (crtl->args.pops_args);
11510 emit_jump_insn (gen_return_pop_internal (popc));
11515 (define_insn "return_internal"
11519 [(set_attr "length" "1")
11520 (set_attr "atom_unit" "jeu")
11521 (set_attr "length_immediate" "0")
11522 (set_attr "modrm" "0")])
11524 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11525 ;; instruction Athlon and K8 have.
11527 (define_insn "return_internal_long"
11529 (unspec [(const_int 0)] UNSPEC_REP)]
11532 [(set_attr "length" "2")
11533 (set_attr "atom_unit" "jeu")
11534 (set_attr "length_immediate" "0")
11535 (set_attr "prefix_rep" "1")
11536 (set_attr "modrm" "0")])
11538 (define_insn "return_pop_internal"
11540 (use (match_operand:SI 0 "const_int_operand" ""))]
11543 [(set_attr "length" "3")
11544 (set_attr "atom_unit" "jeu")
11545 (set_attr "length_immediate" "2")
11546 (set_attr "modrm" "0")])
11548 (define_insn "return_indirect_internal"
11550 (use (match_operand:SI 0 "register_operand" "r"))]
11553 [(set_attr "type" "ibr")
11554 (set_attr "length_immediate" "0")])
11560 [(set_attr "length" "1")
11561 (set_attr "length_immediate" "0")
11562 (set_attr "modrm" "0")])
11564 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11565 (define_insn "nops"
11566 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11570 int num = INTVAL (operands[0]);
11572 gcc_assert (num >= 1 && num <= 8);
11575 fputs ("\tnop\n", asm_out_file);
11579 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11580 (set_attr "length_immediate" "0")
11581 (set_attr "modrm" "0")])
11583 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11584 ;; branch prediction penalty for the third jump in a 16-byte
11588 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11591 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11592 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11594 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11595 The align insn is used to avoid 3 jump instructions in the row to improve
11596 branch prediction and the benefits hardly outweigh the cost of extra 8
11597 nops on the average inserted by full alignment pseudo operation. */
11601 [(set_attr "length" "16")])
11603 (define_expand "prologue"
11606 "ix86_expand_prologue (); DONE;")
11608 (define_insn "set_got"
11609 [(set (match_operand:SI 0 "register_operand" "=r")
11610 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11611 (clobber (reg:CC FLAGS_REG))]
11613 "* return output_set_got (operands[0], NULL_RTX);"
11614 [(set_attr "type" "multi")
11615 (set_attr "length" "12")])
11617 (define_insn "set_got_labelled"
11618 [(set (match_operand:SI 0 "register_operand" "=r")
11619 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11621 (clobber (reg:CC FLAGS_REG))]
11623 "* return output_set_got (operands[0], operands[1]);"
11624 [(set_attr "type" "multi")
11625 (set_attr "length" "12")])
11627 (define_insn "set_got_rex64"
11628 [(set (match_operand:DI 0 "register_operand" "=r")
11629 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11631 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11632 [(set_attr "type" "lea")
11633 (set_attr "length_address" "4")
11634 (set_attr "mode" "DI")])
11636 (define_insn "set_rip_rex64"
11637 [(set (match_operand:DI 0 "register_operand" "=r")
11638 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11640 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11641 [(set_attr "type" "lea")
11642 (set_attr "length_address" "4")
11643 (set_attr "mode" "DI")])
11645 (define_insn "set_got_offset_rex64"
11646 [(set (match_operand:DI 0 "register_operand" "=r")
11648 [(label_ref (match_operand 1 "" ""))]
11649 UNSPEC_SET_GOT_OFFSET))]
11651 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11652 [(set_attr "type" "imov")
11653 (set_attr "length_immediate" "0")
11654 (set_attr "length_address" "8")
11655 (set_attr "mode" "DI")])
11657 (define_expand "epilogue"
11660 "ix86_expand_epilogue (1); DONE;")
11662 (define_expand "sibcall_epilogue"
11665 "ix86_expand_epilogue (0); DONE;")
11667 (define_expand "eh_return"
11668 [(use (match_operand 0 "register_operand" ""))]
11671 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11673 /* Tricky bit: we write the address of the handler to which we will
11674 be returning into someone else's stack frame, one word below the
11675 stack address we wish to restore. */
11676 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11677 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11678 tmp = gen_rtx_MEM (Pmode, tmp);
11679 emit_move_insn (tmp, ra);
11681 emit_jump_insn (gen_eh_return_internal ());
11686 (define_insn_and_split "eh_return_internal"
11690 "epilogue_completed"
11692 "ix86_expand_epilogue (2); DONE;")
11694 (define_insn "leave"
11695 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11696 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11697 (clobber (mem:BLK (scratch)))]
11700 [(set_attr "type" "leave")])
11702 (define_insn "leave_rex64"
11703 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11704 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11705 (clobber (mem:BLK (scratch)))]
11708 [(set_attr "type" "leave")])
11710 ;; Handle -fsplit-stack.
11712 (define_expand "split_stack_prologue"
11716 ix86_expand_split_stack_prologue ();
11720 ;; In order to support the call/return predictor, we use a return
11721 ;; instruction which the middle-end doesn't see.
11722 (define_insn "split_stack_return"
11723 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11724 UNSPECV_SPLIT_STACK_RETURN)]
11727 if (operands[0] == const0_rtx)
11732 [(set_attr "atom_unit" "jeu")
11733 (set_attr "modrm" "0")
11734 (set (attr "length")
11735 (if_then_else (match_operand:SI 0 "const0_operand" "")
11738 (set (attr "length_immediate")
11739 (if_then_else (match_operand:SI 0 "const0_operand" "")
11743 ;; If there are operand 0 bytes available on the stack, jump to
11746 (define_expand "split_stack_space_check"
11747 [(set (pc) (if_then_else
11748 (ltu (minus (reg SP_REG)
11749 (match_operand 0 "register_operand" ""))
11750 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11751 (label_ref (match_operand 1 "" ""))
11755 rtx reg, size, limit;
11757 reg = gen_reg_rtx (Pmode);
11758 size = force_reg (Pmode, operands[0]);
11759 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11760 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11761 UNSPEC_STACK_CHECK);
11762 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11763 ix86_expand_branch (GEU, reg, limit, operands[1]);
11768 ;; Bit manipulation instructions.
11770 (define_expand "ffs<mode>2"
11771 [(set (match_dup 2) (const_int -1))
11772 (parallel [(set (reg:CCZ FLAGS_REG)
11774 (match_operand:SWI48 1 "nonimmediate_operand" "")
11776 (set (match_operand:SWI48 0 "register_operand" "")
11777 (ctz:SWI48 (match_dup 1)))])
11778 (set (match_dup 0) (if_then_else:SWI48
11779 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11782 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11783 (clobber (reg:CC FLAGS_REG))])]
11786 if (<MODE>mode == SImode && !TARGET_CMOVE)
11788 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11791 operands[2] = gen_reg_rtx (<MODE>mode);
11794 (define_insn_and_split "ffssi2_no_cmove"
11795 [(set (match_operand:SI 0 "register_operand" "=r")
11796 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11797 (clobber (match_scratch:SI 2 "=&q"))
11798 (clobber (reg:CC FLAGS_REG))]
11801 "&& reload_completed"
11802 [(parallel [(set (reg:CCZ FLAGS_REG)
11803 (compare:CCZ (match_dup 1) (const_int 0)))
11804 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11805 (set (strict_low_part (match_dup 3))
11806 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11807 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11808 (clobber (reg:CC FLAGS_REG))])
11809 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11810 (clobber (reg:CC FLAGS_REG))])
11811 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11812 (clobber (reg:CC FLAGS_REG))])]
11814 operands[3] = gen_lowpart (QImode, operands[2]);
11815 ix86_expand_clear (operands[2]);
11818 (define_insn "*ffs<mode>_1"
11819 [(set (reg:CCZ FLAGS_REG)
11820 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11822 (set (match_operand:SWI48 0 "register_operand" "=r")
11823 (ctz:SWI48 (match_dup 1)))]
11825 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11826 [(set_attr "type" "alu1")
11827 (set_attr "prefix_0f" "1")
11828 (set_attr "mode" "<MODE>")])
11830 (define_insn "ctz<mode>2"
11831 [(set (match_operand:SWI248 0 "register_operand" "=r")
11832 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11833 (clobber (reg:CC FLAGS_REG))]
11837 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11839 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11841 [(set_attr "type" "alu1")
11842 (set_attr "prefix_0f" "1")
11843 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11844 (set_attr "mode" "<MODE>")])
11846 (define_expand "clz<mode>2"
11848 [(set (match_operand:SWI248 0 "register_operand" "")
11851 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11852 (clobber (reg:CC FLAGS_REG))])
11854 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11855 (clobber (reg:CC FLAGS_REG))])]
11860 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11863 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11866 (define_insn "clz<mode>2_abm"
11867 [(set (match_operand:SWI248 0 "register_operand" "=r")
11868 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11869 (clobber (reg:CC FLAGS_REG))]
11870 "TARGET_ABM || TARGET_BMI"
11871 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11872 [(set_attr "prefix_rep" "1")
11873 (set_attr "type" "bitmanip")
11874 (set_attr "mode" "<MODE>")])
11876 ;; BMI instructions.
11877 (define_insn "*bmi_andn_<mode>"
11878 [(set (match_operand:SWI48 0 "register_operand" "=r")
11881 (match_operand:SWI48 1 "register_operand" "r"))
11882 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11883 (clobber (reg:CC FLAGS_REG))]
11885 "andn\t{%2, %1, %0|%0, %1, %2}"
11886 [(set_attr "type" "bitmanip")
11887 (set_attr "mode" "<MODE>")])
11889 (define_insn "bmi_bextr_<mode>"
11890 [(set (match_operand:SWI48 0 "register_operand" "=r")
11891 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11892 (match_operand:SWI48 2 "register_operand" "r")]
11894 (clobber (reg:CC FLAGS_REG))]
11896 "bextr\t{%2, %1, %0|%0, %1, %2}"
11897 [(set_attr "type" "bitmanip")
11898 (set_attr "mode" "<MODE>")])
11900 (define_insn "*bmi_blsi_<mode>"
11901 [(set (match_operand:SWI48 0 "register_operand" "=r")
11904 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11906 (clobber (reg:CC FLAGS_REG))]
11908 "blsi\t{%1, %0|%0, %1}"
11909 [(set_attr "type" "bitmanip")
11910 (set_attr "mode" "<MODE>")])
11912 (define_insn "*bmi_blsmsk_<mode>"
11913 [(set (match_operand:SWI48 0 "register_operand" "=r")
11916 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11919 (clobber (reg:CC FLAGS_REG))]
11921 "blsmsk\t{%1, %0|%0, %1}"
11922 [(set_attr "type" "bitmanip")
11923 (set_attr "mode" "<MODE>")])
11925 (define_insn "*bmi_blsr_<mode>"
11926 [(set (match_operand:SWI48 0 "register_operand" "=r")
11929 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11932 (clobber (reg:CC FLAGS_REG))]
11934 "blsr\t{%1, %0|%0, %1}"
11935 [(set_attr "type" "bitmanip")
11936 (set_attr "mode" "<MODE>")])
11938 ;; TBM instructions.
11939 (define_insn "tbm_bextri_<mode>"
11940 [(set (match_operand:SWI48 0 "register_operand" "=r")
11941 (zero_extract:SWI48
11942 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11943 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11944 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11945 (clobber (reg:CC FLAGS_REG))]
11948 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11949 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11951 [(set_attr "type" "bitmanip")
11952 (set_attr "mode" "<MODE>")])
11954 (define_insn "*tbm_blcfill_<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 "blcfill\t{%1, %0|%0, %1}"
11964 [(set_attr "type" "bitmanip")
11965 (set_attr "mode" "<MODE>")])
11967 (define_insn "*tbm_blci_<mode>"
11968 [(set (match_operand:SWI48 0 "register_operand" "=r")
11972 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11975 (clobber (reg:CC FLAGS_REG))]
11977 "blci\t{%1, %0|%0, %1}"
11978 [(set_attr "type" "bitmanip")
11979 (set_attr "mode" "<MODE>")])
11981 (define_insn "*tbm_blcic_<mode>"
11982 [(set (match_operand:SWI48 0 "register_operand" "=r")
11985 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11989 (clobber (reg:CC FLAGS_REG))]
11991 "blcic\t{%1, %0|%0, %1}"
11992 [(set_attr "type" "bitmanip")
11993 (set_attr "mode" "<MODE>")])
11995 (define_insn "*tbm_blcmsk_<mode>"
11996 [(set (match_operand:SWI48 0 "register_operand" "=r")
11999 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12002 (clobber (reg:CC FLAGS_REG))]
12004 "blcmsk\t{%1, %0|%0, %1}"
12005 [(set_attr "type" "bitmanip")
12006 (set_attr "mode" "<MODE>")])
12008 (define_insn "*tbm_blcs_<mode>"
12009 [(set (match_operand:SWI48 0 "register_operand" "=r")
12012 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12015 (clobber (reg:CC FLAGS_REG))]
12017 "blcs\t{%1, %0|%0, %1}"
12018 [(set_attr "type" "bitmanip")
12019 (set_attr "mode" "<MODE>")])
12021 (define_insn "*tbm_blsfill_<mode>"
12022 [(set (match_operand:SWI48 0 "register_operand" "=r")
12025 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12028 (clobber (reg:CC FLAGS_REG))]
12030 "blsfill\t{%1, %0|%0, %1}"
12031 [(set_attr "type" "bitmanip")
12032 (set_attr "mode" "<MODE>")])
12034 (define_insn "*tbm_blsic_<mode>"
12035 [(set (match_operand:SWI48 0 "register_operand" "=r")
12038 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12042 (clobber (reg:CC FLAGS_REG))]
12044 "blsic\t{%1, %0|%0, %1}"
12045 [(set_attr "type" "bitmanip")
12046 (set_attr "mode" "<MODE>")])
12048 (define_insn "*tbm_t1mskc_<mode>"
12049 [(set (match_operand:SWI48 0 "register_operand" "=r")
12052 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12056 (clobber (reg:CC FLAGS_REG))]
12058 "t1mskc\t{%1, %0|%0, %1}"
12059 [(set_attr "type" "bitmanip")
12060 (set_attr "mode" "<MODE>")])
12062 (define_insn "*tbm_tzmsk_<mode>"
12063 [(set (match_operand:SWI48 0 "register_operand" "=r")
12066 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12070 (clobber (reg:CC FLAGS_REG))]
12072 "tzmsk\t{%1, %0|%0, %1}"
12073 [(set_attr "type" "bitmanip")
12074 (set_attr "mode" "<MODE>")])
12076 (define_insn "bsr_rex64"
12077 [(set (match_operand:DI 0 "register_operand" "=r")
12078 (minus:DI (const_int 63)
12079 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12080 (clobber (reg:CC FLAGS_REG))]
12082 "bsr{q}\t{%1, %0|%0, %1}"
12083 [(set_attr "type" "alu1")
12084 (set_attr "prefix_0f" "1")
12085 (set_attr "mode" "DI")])
12088 [(set (match_operand:SI 0 "register_operand" "=r")
12089 (minus:SI (const_int 31)
12090 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12091 (clobber (reg:CC FLAGS_REG))]
12093 "bsr{l}\t{%1, %0|%0, %1}"
12094 [(set_attr "type" "alu1")
12095 (set_attr "prefix_0f" "1")
12096 (set_attr "mode" "SI")])
12098 (define_insn "*bsrhi"
12099 [(set (match_operand:HI 0 "register_operand" "=r")
12100 (minus:HI (const_int 15)
12101 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12102 (clobber (reg:CC FLAGS_REG))]
12104 "bsr{w}\t{%1, %0|%0, %1}"
12105 [(set_attr "type" "alu1")
12106 (set_attr "prefix_0f" "1")
12107 (set_attr "mode" "HI")])
12109 (define_insn "popcount<mode>2"
12110 [(set (match_operand:SWI248 0 "register_operand" "=r")
12112 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12113 (clobber (reg:CC FLAGS_REG))]
12117 return "popcnt\t{%1, %0|%0, %1}";
12119 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12122 [(set_attr "prefix_rep" "1")
12123 (set_attr "type" "bitmanip")
12124 (set_attr "mode" "<MODE>")])
12126 (define_insn "*popcount<mode>2_cmp"
12127 [(set (reg FLAGS_REG)
12130 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12132 (set (match_operand:SWI248 0 "register_operand" "=r")
12133 (popcount:SWI248 (match_dup 1)))]
12134 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12137 return "popcnt\t{%1, %0|%0, %1}";
12139 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12142 [(set_attr "prefix_rep" "1")
12143 (set_attr "type" "bitmanip")
12144 (set_attr "mode" "<MODE>")])
12146 (define_insn "*popcountsi2_cmp_zext"
12147 [(set (reg FLAGS_REG)
12149 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12151 (set (match_operand:DI 0 "register_operand" "=r")
12152 (zero_extend:DI(popcount:SI (match_dup 1))))]
12153 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12156 return "popcnt\t{%1, %0|%0, %1}";
12158 return "popcnt{l}\t{%1, %0|%0, %1}";
12161 [(set_attr "prefix_rep" "1")
12162 (set_attr "type" "bitmanip")
12163 (set_attr "mode" "SI")])
12165 (define_expand "bswap<mode>2"
12166 [(set (match_operand:SWI48 0 "register_operand" "")
12167 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12170 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12172 rtx x = operands[0];
12174 emit_move_insn (x, operands[1]);
12175 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12176 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12177 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12182 (define_insn "*bswap<mode>2_movbe"
12183 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12184 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12186 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12189 movbe\t{%1, %0|%0, %1}
12190 movbe\t{%1, %0|%0, %1}"
12191 [(set_attr "type" "bitmanip,imov,imov")
12192 (set_attr "modrm" "0,1,1")
12193 (set_attr "prefix_0f" "*,1,1")
12194 (set_attr "prefix_extra" "*,1,1")
12195 (set_attr "mode" "<MODE>")])
12197 (define_insn "*bswap<mode>2_1"
12198 [(set (match_operand:SWI48 0 "register_operand" "=r")
12199 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12202 [(set_attr "type" "bitmanip")
12203 (set_attr "modrm" "0")
12204 (set_attr "mode" "<MODE>")])
12206 (define_insn "*bswaphi_lowpart_1"
12207 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12208 (bswap:HI (match_dup 0)))
12209 (clobber (reg:CC FLAGS_REG))]
12210 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12212 xchg{b}\t{%h0, %b0|%b0, %h0}
12213 rol{w}\t{$8, %0|%0, 8}"
12214 [(set_attr "length" "2,4")
12215 (set_attr "mode" "QI,HI")])
12217 (define_insn "bswaphi_lowpart"
12218 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12219 (bswap:HI (match_dup 0)))
12220 (clobber (reg:CC FLAGS_REG))]
12222 "rol{w}\t{$8, %0|%0, 8}"
12223 [(set_attr "length" "4")
12224 (set_attr "mode" "HI")])
12226 (define_expand "paritydi2"
12227 [(set (match_operand:DI 0 "register_operand" "")
12228 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12231 rtx scratch = gen_reg_rtx (QImode);
12234 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12235 NULL_RTX, operands[1]));
12237 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12238 gen_rtx_REG (CCmode, FLAGS_REG),
12240 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12243 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12246 rtx tmp = gen_reg_rtx (SImode);
12248 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12249 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12254 (define_expand "paritysi2"
12255 [(set (match_operand:SI 0 "register_operand" "")
12256 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12259 rtx scratch = gen_reg_rtx (QImode);
12262 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12264 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12265 gen_rtx_REG (CCmode, FLAGS_REG),
12267 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12269 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12273 (define_insn_and_split "paritydi2_cmp"
12274 [(set (reg:CC FLAGS_REG)
12275 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12277 (clobber (match_scratch:DI 0 "=r"))
12278 (clobber (match_scratch:SI 1 "=&r"))
12279 (clobber (match_scratch:HI 2 "=Q"))]
12282 "&& reload_completed"
12284 [(set (match_dup 1)
12285 (xor:SI (match_dup 1) (match_dup 4)))
12286 (clobber (reg:CC FLAGS_REG))])
12288 [(set (reg:CC FLAGS_REG)
12289 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12290 (clobber (match_dup 1))
12291 (clobber (match_dup 2))])]
12293 operands[4] = gen_lowpart (SImode, operands[3]);
12297 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12298 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12301 operands[1] = gen_highpart (SImode, operands[3]);
12304 (define_insn_and_split "paritysi2_cmp"
12305 [(set (reg:CC FLAGS_REG)
12306 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12308 (clobber (match_scratch:SI 0 "=r"))
12309 (clobber (match_scratch:HI 1 "=&Q"))]
12312 "&& reload_completed"
12314 [(set (match_dup 1)
12315 (xor:HI (match_dup 1) (match_dup 3)))
12316 (clobber (reg:CC FLAGS_REG))])
12318 [(set (reg:CC FLAGS_REG)
12319 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12320 (clobber (match_dup 1))])]
12322 operands[3] = gen_lowpart (HImode, operands[2]);
12324 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12325 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12328 (define_insn "*parityhi2_cmp"
12329 [(set (reg:CC FLAGS_REG)
12330 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12332 (clobber (match_scratch:HI 0 "=Q"))]
12334 "xor{b}\t{%h0, %b0|%b0, %h0}"
12335 [(set_attr "length" "2")
12336 (set_attr "mode" "HI")])
12338 ;; Thread-local storage patterns for ELF.
12340 ;; Note that these code sequences must appear exactly as shown
12341 ;; in order to allow linker relaxation.
12343 (define_insn "*tls_global_dynamic_32_gnu"
12344 [(set (match_operand:SI 0 "register_operand" "=a")
12346 [(match_operand:SI 1 "register_operand" "b")
12347 (match_operand:SI 2 "tls_symbolic_operand" "")
12348 (match_operand:SI 3 "constant_call_address_operand" "z")]
12350 (clobber (match_scratch:SI 4 "=d"))
12351 (clobber (match_scratch:SI 5 "=c"))
12352 (clobber (reg:CC FLAGS_REG))]
12353 "!TARGET_64BIT && TARGET_GNU_TLS"
12356 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12357 if (TARGET_SUN_TLS)
12358 #ifdef HAVE_AS_IX86_TLSGDPLT
12359 return "call\t%a2@tlsgdplt";
12361 return "call\t%p3@plt";
12363 return "call\t%P3";
12365 [(set_attr "type" "multi")
12366 (set_attr "length" "12")])
12368 (define_expand "tls_global_dynamic_32"
12370 [(set (match_operand:SI 0 "register_operand" "")
12371 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12372 (match_operand:SI 1 "tls_symbolic_operand" "")
12373 (match_operand:SI 3 "constant_call_address_operand" "")]
12375 (clobber (match_scratch:SI 4 ""))
12376 (clobber (match_scratch:SI 5 ""))
12377 (clobber (reg:CC FLAGS_REG))])])
12379 (define_insn "*tls_global_dynamic_64"
12380 [(set (match_operand:DI 0 "register_operand" "=a")
12382 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12383 (match_operand:DI 3 "" "")))
12384 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12388 fputs (ASM_BYTE "0x66\n", asm_out_file);
12390 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12391 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12392 fputs ("\trex64\n", asm_out_file);
12393 if (TARGET_SUN_TLS)
12394 return "call\t%p2@plt";
12395 return "call\t%P2";
12397 [(set_attr "type" "multi")
12398 (set_attr "length" "16")])
12400 (define_expand "tls_global_dynamic_64"
12402 [(set (match_operand:DI 0 "register_operand" "")
12404 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12406 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12409 (define_insn "*tls_local_dynamic_base_32_gnu"
12410 [(set (match_operand:SI 0 "register_operand" "=a")
12412 [(match_operand:SI 1 "register_operand" "b")
12413 (match_operand:SI 2 "constant_call_address_operand" "z")]
12414 UNSPEC_TLS_LD_BASE))
12415 (clobber (match_scratch:SI 3 "=d"))
12416 (clobber (match_scratch:SI 4 "=c"))
12417 (clobber (reg:CC FLAGS_REG))]
12418 "!TARGET_64BIT && TARGET_GNU_TLS"
12421 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12422 if (TARGET_SUN_TLS)
12423 #ifdef HAVE_AS_IX86_TLSLDMPLT
12424 return "call\t%&@tlsldmplt";
12426 return "call\t%p2@plt";
12428 return "call\t%P2";
12430 [(set_attr "type" "multi")
12431 (set_attr "length" "11")])
12433 (define_expand "tls_local_dynamic_base_32"
12435 [(set (match_operand:SI 0 "register_operand" "")
12437 [(match_operand:SI 1 "register_operand" "")
12438 (match_operand:SI 2 "constant_call_address_operand" "")]
12439 UNSPEC_TLS_LD_BASE))
12440 (clobber (match_scratch:SI 3 ""))
12441 (clobber (match_scratch:SI 4 ""))
12442 (clobber (reg:CC FLAGS_REG))])])
12444 (define_insn "*tls_local_dynamic_base_64"
12445 [(set (match_operand:DI 0 "register_operand" "=a")
12447 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12448 (match_operand:DI 2 "" "")))
12449 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12453 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12454 if (TARGET_SUN_TLS)
12455 return "call\t%p1@plt";
12456 return "call\t%P1";
12458 [(set_attr "type" "multi")
12459 (set_attr "length" "12")])
12461 (define_expand "tls_local_dynamic_base_64"
12463 [(set (match_operand:DI 0 "register_operand" "")
12465 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12467 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12469 ;; Local dynamic of a single variable is a lose. Show combine how
12470 ;; to convert that back to global dynamic.
12472 (define_insn_and_split "*tls_local_dynamic_32_once"
12473 [(set (match_operand:SI 0 "register_operand" "=a")
12475 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12476 (match_operand:SI 2 "constant_call_address_operand" "z")]
12477 UNSPEC_TLS_LD_BASE)
12478 (const:SI (unspec:SI
12479 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12481 (clobber (match_scratch:SI 4 "=d"))
12482 (clobber (match_scratch:SI 5 "=c"))
12483 (clobber (reg:CC FLAGS_REG))]
12488 [(set (match_dup 0)
12489 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12491 (clobber (match_dup 4))
12492 (clobber (match_dup 5))
12493 (clobber (reg:CC FLAGS_REG))])])
12495 ;; Segment register for the thread base ptr load
12496 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12498 ;; Load and add the thread base pointer from %<tp_seg>:0.
12499 (define_insn "*load_tp_<mode>"
12500 [(set (match_operand:P 0 "register_operand" "=r")
12501 (unspec:P [(const_int 0)] UNSPEC_TP))]
12503 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12504 [(set_attr "type" "imov")
12505 (set_attr "modrm" "0")
12506 (set_attr "length" "7")
12507 (set_attr "memory" "load")
12508 (set_attr "imm_disp" "false")])
12510 (define_insn "*add_tp_<mode>"
12511 [(set (match_operand:P 0 "register_operand" "=r")
12512 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12513 (match_operand:P 1 "register_operand" "0")))
12514 (clobber (reg:CC FLAGS_REG))]
12516 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12517 [(set_attr "type" "alu")
12518 (set_attr "modrm" "0")
12519 (set_attr "length" "7")
12520 (set_attr "memory" "load")
12521 (set_attr "imm_disp" "false")])
12523 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12524 ;; %rax as destination of the initial executable code sequence.
12525 (define_insn "tls_initial_exec_64_sun"
12526 [(set (match_operand:DI 0 "register_operand" "=a")
12528 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12529 UNSPEC_TLS_IE_SUN))
12530 (clobber (reg:CC FLAGS_REG))]
12531 "TARGET_64BIT && TARGET_SUN_TLS"
12534 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12535 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12537 [(set_attr "type" "multi")])
12539 ;; GNU2 TLS patterns can be split.
12541 (define_expand "tls_dynamic_gnu2_32"
12542 [(set (match_dup 3)
12543 (plus:SI (match_operand:SI 2 "register_operand" "")
12545 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12548 [(set (match_operand:SI 0 "register_operand" "")
12549 (unspec:SI [(match_dup 1) (match_dup 3)
12550 (match_dup 2) (reg:SI SP_REG)]
12552 (clobber (reg:CC FLAGS_REG))])]
12553 "!TARGET_64BIT && TARGET_GNU2_TLS"
12555 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12556 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12559 (define_insn "*tls_dynamic_lea_32"
12560 [(set (match_operand:SI 0 "register_operand" "=r")
12561 (plus:SI (match_operand:SI 1 "register_operand" "b")
12563 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12564 UNSPEC_TLSDESC))))]
12565 "!TARGET_64BIT && TARGET_GNU2_TLS"
12566 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12567 [(set_attr "type" "lea")
12568 (set_attr "mode" "SI")
12569 (set_attr "length" "6")
12570 (set_attr "length_address" "4")])
12572 (define_insn "*tls_dynamic_call_32"
12573 [(set (match_operand:SI 0 "register_operand" "=a")
12574 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12575 (match_operand:SI 2 "register_operand" "0")
12576 ;; we have to make sure %ebx still points to the GOT
12577 (match_operand:SI 3 "register_operand" "b")
12580 (clobber (reg:CC FLAGS_REG))]
12581 "!TARGET_64BIT && TARGET_GNU2_TLS"
12582 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12583 [(set_attr "type" "call")
12584 (set_attr "length" "2")
12585 (set_attr "length_address" "0")])
12587 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12588 [(set (match_operand:SI 0 "register_operand" "=&a")
12590 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12591 (match_operand:SI 4 "" "")
12592 (match_operand:SI 2 "register_operand" "b")
12595 (const:SI (unspec:SI
12596 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12598 (clobber (reg:CC FLAGS_REG))]
12599 "!TARGET_64BIT && TARGET_GNU2_TLS"
12602 [(set (match_dup 0) (match_dup 5))]
12604 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12605 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12608 (define_expand "tls_dynamic_gnu2_64"
12609 [(set (match_dup 2)
12610 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12613 [(set (match_operand:DI 0 "register_operand" "")
12614 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12616 (clobber (reg:CC FLAGS_REG))])]
12617 "TARGET_64BIT && TARGET_GNU2_TLS"
12619 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12620 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12623 (define_insn "*tls_dynamic_lea_64"
12624 [(set (match_operand:DI 0 "register_operand" "=r")
12625 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12627 "TARGET_64BIT && TARGET_GNU2_TLS"
12628 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12629 [(set_attr "type" "lea")
12630 (set_attr "mode" "DI")
12631 (set_attr "length" "7")
12632 (set_attr "length_address" "4")])
12634 (define_insn "*tls_dynamic_call_64"
12635 [(set (match_operand:DI 0 "register_operand" "=a")
12636 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12637 (match_operand:DI 2 "register_operand" "0")
12640 (clobber (reg:CC FLAGS_REG))]
12641 "TARGET_64BIT && TARGET_GNU2_TLS"
12642 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12643 [(set_attr "type" "call")
12644 (set_attr "length" "2")
12645 (set_attr "length_address" "0")])
12647 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12648 [(set (match_operand:DI 0 "register_operand" "=&a")
12650 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12651 (match_operand:DI 3 "" "")
12654 (const:DI (unspec:DI
12655 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12657 (clobber (reg:CC FLAGS_REG))]
12658 "TARGET_64BIT && TARGET_GNU2_TLS"
12661 [(set (match_dup 0) (match_dup 4))]
12663 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12664 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12667 ;; These patterns match the binary 387 instructions for addM3, subM3,
12668 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12669 ;; SFmode. The first is the normal insn, the second the same insn but
12670 ;; with one operand a conversion, and the third the same insn but with
12671 ;; the other operand a conversion. The conversion may be SFmode or
12672 ;; SImode if the target mode DFmode, but only SImode if the target mode
12675 ;; Gcc is slightly more smart about handling normal two address instructions
12676 ;; so use special patterns for add and mull.
12678 (define_insn "*fop_<mode>_comm_mixed"
12679 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12680 (match_operator:MODEF 3 "binary_fp_operator"
12681 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12682 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12683 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12684 && COMMUTATIVE_ARITH_P (operands[3])
12685 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12686 "* return output_387_binary_op (insn, operands);"
12687 [(set (attr "type")
12688 (if_then_else (eq_attr "alternative" "1,2")
12689 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12690 (const_string "ssemul")
12691 (const_string "sseadd"))
12692 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12693 (const_string "fmul")
12694 (const_string "fop"))))
12695 (set_attr "isa" "base,noavx,avx")
12696 (set_attr "prefix" "orig,orig,vex")
12697 (set_attr "mode" "<MODE>")])
12699 (define_insn "*fop_<mode>_comm_sse"
12700 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12701 (match_operator:MODEF 3 "binary_fp_operator"
12702 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12703 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12704 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12705 && COMMUTATIVE_ARITH_P (operands[3])
12706 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12707 "* return output_387_binary_op (insn, operands);"
12708 [(set (attr "type")
12709 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12710 (const_string "ssemul")
12711 (const_string "sseadd")))
12712 (set_attr "isa" "noavx,avx")
12713 (set_attr "prefix" "orig,vex")
12714 (set_attr "mode" "<MODE>")])
12716 (define_insn "*fop_<mode>_comm_i387"
12717 [(set (match_operand:MODEF 0 "register_operand" "=f")
12718 (match_operator:MODEF 3 "binary_fp_operator"
12719 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12720 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12721 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12722 && COMMUTATIVE_ARITH_P (operands[3])
12723 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12724 "* return output_387_binary_op (insn, operands);"
12725 [(set (attr "type")
12726 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12727 (const_string "fmul")
12728 (const_string "fop")))
12729 (set_attr "mode" "<MODE>")])
12731 (define_insn "*fop_<mode>_1_mixed"
12732 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12733 (match_operator:MODEF 3 "binary_fp_operator"
12734 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12735 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12736 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12737 && !COMMUTATIVE_ARITH_P (operands[3])
12738 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12739 "* return output_387_binary_op (insn, operands);"
12740 [(set (attr "type")
12741 (cond [(and (eq_attr "alternative" "2,3")
12742 (match_operand:MODEF 3 "mult_operator" ""))
12743 (const_string "ssemul")
12744 (and (eq_attr "alternative" "2,3")
12745 (match_operand:MODEF 3 "div_operator" ""))
12746 (const_string "ssediv")
12747 (eq_attr "alternative" "2,3")
12748 (const_string "sseadd")
12749 (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 "isa" "base,base,noavx,avx")
12756 (set_attr "prefix" "orig,orig,orig,vex")
12757 (set_attr "mode" "<MODE>")])
12759 (define_insn "*rcpsf2_sse"
12760 [(set (match_operand:SF 0 "register_operand" "=x")
12761 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12764 "%vrcpss\t{%1, %d0|%d0, %1}"
12765 [(set_attr "type" "sse")
12766 (set_attr "atom_sse_attr" "rcp")
12767 (set_attr "prefix" "maybe_vex")
12768 (set_attr "mode" "SF")])
12770 (define_insn "*fop_<mode>_1_sse"
12771 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12772 (match_operator:MODEF 3 "binary_fp_operator"
12773 [(match_operand:MODEF 1 "register_operand" "0,x")
12774 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12775 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12776 && !COMMUTATIVE_ARITH_P (operands[3])"
12777 "* return output_387_binary_op (insn, operands);"
12778 [(set (attr "type")
12779 (cond [(match_operand:MODEF 3 "mult_operator" "")
12780 (const_string "ssemul")
12781 (match_operand:MODEF 3 "div_operator" "")
12782 (const_string "ssediv")
12784 (const_string "sseadd")))
12785 (set_attr "isa" "noavx,avx")
12786 (set_attr "prefix" "orig,vex")
12787 (set_attr "mode" "<MODE>")])
12789 ;; This pattern is not fully shadowed by the pattern above.
12790 (define_insn "*fop_<mode>_1_i387"
12791 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12792 (match_operator:MODEF 3 "binary_fp_operator"
12793 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12794 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12795 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12796 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12797 && !COMMUTATIVE_ARITH_P (operands[3])
12798 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12799 "* return output_387_binary_op (insn, operands);"
12800 [(set (attr "type")
12801 (cond [(match_operand:MODEF 3 "mult_operator" "")
12802 (const_string "fmul")
12803 (match_operand:MODEF 3 "div_operator" "")
12804 (const_string "fdiv")
12806 (const_string "fop")))
12807 (set_attr "mode" "<MODE>")])
12809 ;; ??? Add SSE splitters for these!
12810 (define_insn "*fop_<MODEF:mode>_2_i387"
12811 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12812 (match_operator:MODEF 3 "binary_fp_operator"
12814 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12815 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12816 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12817 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12818 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12819 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12820 [(set (attr "type")
12821 (cond [(match_operand:MODEF 3 "mult_operator" "")
12822 (const_string "fmul")
12823 (match_operand:MODEF 3 "div_operator" "")
12824 (const_string "fdiv")
12826 (const_string "fop")))
12827 (set_attr "fp_int_src" "true")
12828 (set_attr "mode" "<SWI24:MODE>")])
12830 (define_insn "*fop_<MODEF:mode>_3_i387"
12831 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12832 (match_operator:MODEF 3 "binary_fp_operator"
12833 [(match_operand:MODEF 1 "register_operand" "0,0")
12835 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12836 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12837 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12838 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12839 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12840 [(set (attr "type")
12841 (cond [(match_operand:MODEF 3 "mult_operator" "")
12842 (const_string "fmul")
12843 (match_operand:MODEF 3 "div_operator" "")
12844 (const_string "fdiv")
12846 (const_string "fop")))
12847 (set_attr "fp_int_src" "true")
12848 (set_attr "mode" "<MODE>")])
12850 (define_insn "*fop_df_4_i387"
12851 [(set (match_operand:DF 0 "register_operand" "=f,f")
12852 (match_operator:DF 3 "binary_fp_operator"
12854 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12855 (match_operand:DF 2 "register_operand" "0,f")]))]
12856 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12857 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12858 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12859 "* return output_387_binary_op (insn, operands);"
12860 [(set (attr "type")
12861 (cond [(match_operand:DF 3 "mult_operator" "")
12862 (const_string "fmul")
12863 (match_operand:DF 3 "div_operator" "")
12864 (const_string "fdiv")
12866 (const_string "fop")))
12867 (set_attr "mode" "SF")])
12869 (define_insn "*fop_df_5_i387"
12870 [(set (match_operand:DF 0 "register_operand" "=f,f")
12871 (match_operator:DF 3 "binary_fp_operator"
12872 [(match_operand:DF 1 "register_operand" "0,f")
12874 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12875 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12876 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12877 "* return output_387_binary_op (insn, operands);"
12878 [(set (attr "type")
12879 (cond [(match_operand:DF 3 "mult_operator" "")
12880 (const_string "fmul")
12881 (match_operand:DF 3 "div_operator" "")
12882 (const_string "fdiv")
12884 (const_string "fop")))
12885 (set_attr "mode" "SF")])
12887 (define_insn "*fop_df_6_i387"
12888 [(set (match_operand:DF 0 "register_operand" "=f,f")
12889 (match_operator:DF 3 "binary_fp_operator"
12891 (match_operand:SF 1 "register_operand" "0,f"))
12893 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12894 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12895 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12896 "* return output_387_binary_op (insn, operands);"
12897 [(set (attr "type")
12898 (cond [(match_operand:DF 3 "mult_operator" "")
12899 (const_string "fmul")
12900 (match_operand:DF 3 "div_operator" "")
12901 (const_string "fdiv")
12903 (const_string "fop")))
12904 (set_attr "mode" "SF")])
12906 (define_insn "*fop_xf_comm_i387"
12907 [(set (match_operand:XF 0 "register_operand" "=f")
12908 (match_operator:XF 3 "binary_fp_operator"
12909 [(match_operand:XF 1 "register_operand" "%0")
12910 (match_operand:XF 2 "register_operand" "f")]))]
12912 && COMMUTATIVE_ARITH_P (operands[3])"
12913 "* return output_387_binary_op (insn, operands);"
12914 [(set (attr "type")
12915 (if_then_else (match_operand:XF 3 "mult_operator" "")
12916 (const_string "fmul")
12917 (const_string "fop")))
12918 (set_attr "mode" "XF")])
12920 (define_insn "*fop_xf_1_i387"
12921 [(set (match_operand:XF 0 "register_operand" "=f,f")
12922 (match_operator:XF 3 "binary_fp_operator"
12923 [(match_operand:XF 1 "register_operand" "0,f")
12924 (match_operand:XF 2 "register_operand" "f,0")]))]
12926 && !COMMUTATIVE_ARITH_P (operands[3])"
12927 "* return output_387_binary_op (insn, operands);"
12928 [(set (attr "type")
12929 (cond [(match_operand:XF 3 "mult_operator" "")
12930 (const_string "fmul")
12931 (match_operand:XF 3 "div_operator" "")
12932 (const_string "fdiv")
12934 (const_string "fop")))
12935 (set_attr "mode" "XF")])
12937 (define_insn "*fop_xf_2_i387"
12938 [(set (match_operand:XF 0 "register_operand" "=f,f")
12939 (match_operator:XF 3 "binary_fp_operator"
12941 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12942 (match_operand:XF 2 "register_operand" "0,0")]))]
12943 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12944 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12945 [(set (attr "type")
12946 (cond [(match_operand:XF 3 "mult_operator" "")
12947 (const_string "fmul")
12948 (match_operand:XF 3 "div_operator" "")
12949 (const_string "fdiv")
12951 (const_string "fop")))
12952 (set_attr "fp_int_src" "true")
12953 (set_attr "mode" "<MODE>")])
12955 (define_insn "*fop_xf_3_i387"
12956 [(set (match_operand:XF 0 "register_operand" "=f,f")
12957 (match_operator:XF 3 "binary_fp_operator"
12958 [(match_operand:XF 1 "register_operand" "0,0")
12960 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12961 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12962 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12963 [(set (attr "type")
12964 (cond [(match_operand:XF 3 "mult_operator" "")
12965 (const_string "fmul")
12966 (match_operand:XF 3 "div_operator" "")
12967 (const_string "fdiv")
12969 (const_string "fop")))
12970 (set_attr "fp_int_src" "true")
12971 (set_attr "mode" "<MODE>")])
12973 (define_insn "*fop_xf_4_i387"
12974 [(set (match_operand:XF 0 "register_operand" "=f,f")
12975 (match_operator:XF 3 "binary_fp_operator"
12977 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12978 (match_operand:XF 2 "register_operand" "0,f")]))]
12980 "* return output_387_binary_op (insn, operands);"
12981 [(set (attr "type")
12982 (cond [(match_operand:XF 3 "mult_operator" "")
12983 (const_string "fmul")
12984 (match_operand:XF 3 "div_operator" "")
12985 (const_string "fdiv")
12987 (const_string "fop")))
12988 (set_attr "mode" "<MODE>")])
12990 (define_insn "*fop_xf_5_i387"
12991 [(set (match_operand:XF 0 "register_operand" "=f,f")
12992 (match_operator:XF 3 "binary_fp_operator"
12993 [(match_operand:XF 1 "register_operand" "0,f")
12995 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12997 "* return output_387_binary_op (insn, operands);"
12998 [(set (attr "type")
12999 (cond [(match_operand:XF 3 "mult_operator" "")
13000 (const_string "fmul")
13001 (match_operand:XF 3 "div_operator" "")
13002 (const_string "fdiv")
13004 (const_string "fop")))
13005 (set_attr "mode" "<MODE>")])
13007 (define_insn "*fop_xf_6_i387"
13008 [(set (match_operand:XF 0 "register_operand" "=f,f")
13009 (match_operator:XF 3 "binary_fp_operator"
13011 (match_operand:MODEF 1 "register_operand" "0,f"))
13013 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13015 "* return output_387_binary_op (insn, operands);"
13016 [(set (attr "type")
13017 (cond [(match_operand:XF 3 "mult_operator" "")
13018 (const_string "fmul")
13019 (match_operand:XF 3 "div_operator" "")
13020 (const_string "fdiv")
13022 (const_string "fop")))
13023 (set_attr "mode" "<MODE>")])
13026 [(set (match_operand 0 "register_operand" "")
13027 (match_operator 3 "binary_fp_operator"
13028 [(float (match_operand:SWI24 1 "register_operand" ""))
13029 (match_operand 2 "register_operand" "")]))]
13031 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13032 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13035 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13036 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13037 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13038 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13039 GET_MODE (operands[3]),
13042 ix86_free_from_memory (GET_MODE (operands[1]));
13047 [(set (match_operand 0 "register_operand" "")
13048 (match_operator 3 "binary_fp_operator"
13049 [(match_operand 1 "register_operand" "")
13050 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13052 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13053 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13056 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13057 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13058 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13059 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13060 GET_MODE (operands[3]),
13063 ix86_free_from_memory (GET_MODE (operands[2]));
13067 ;; FPU special functions.
13069 ;; This pattern implements a no-op XFmode truncation for
13070 ;; all fancy i386 XFmode math functions.
13072 (define_insn "truncxf<mode>2_i387_noop_unspec"
13073 [(set (match_operand:MODEF 0 "register_operand" "=f")
13074 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13075 UNSPEC_TRUNC_NOOP))]
13076 "TARGET_USE_FANCY_MATH_387"
13077 "* return output_387_reg_move (insn, operands);"
13078 [(set_attr "type" "fmov")
13079 (set_attr "mode" "<MODE>")])
13081 (define_insn "sqrtxf2"
13082 [(set (match_operand:XF 0 "register_operand" "=f")
13083 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13084 "TARGET_USE_FANCY_MATH_387"
13086 [(set_attr "type" "fpspc")
13087 (set_attr "mode" "XF")
13088 (set_attr "athlon_decode" "direct")
13089 (set_attr "amdfam10_decode" "direct")
13090 (set_attr "bdver1_decode" "direct")])
13092 (define_insn "sqrt_extend<mode>xf2_i387"
13093 [(set (match_operand:XF 0 "register_operand" "=f")
13096 (match_operand:MODEF 1 "register_operand" "0"))))]
13097 "TARGET_USE_FANCY_MATH_387"
13099 [(set_attr "type" "fpspc")
13100 (set_attr "mode" "XF")
13101 (set_attr "athlon_decode" "direct")
13102 (set_attr "amdfam10_decode" "direct")
13103 (set_attr "bdver1_decode" "direct")])
13105 (define_insn "*rsqrtsf2_sse"
13106 [(set (match_operand:SF 0 "register_operand" "=x")
13107 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13110 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13111 [(set_attr "type" "sse")
13112 (set_attr "atom_sse_attr" "rcp")
13113 (set_attr "prefix" "maybe_vex")
13114 (set_attr "mode" "SF")])
13116 (define_expand "rsqrtsf2"
13117 [(set (match_operand:SF 0 "register_operand" "")
13118 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13122 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13126 (define_insn "*sqrt<mode>2_sse"
13127 [(set (match_operand:MODEF 0 "register_operand" "=x")
13129 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13130 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13131 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13132 [(set_attr "type" "sse")
13133 (set_attr "atom_sse_attr" "sqrt")
13134 (set_attr "prefix" "maybe_vex")
13135 (set_attr "mode" "<MODE>")
13136 (set_attr "athlon_decode" "*")
13137 (set_attr "amdfam10_decode" "*")
13138 (set_attr "bdver1_decode" "*")])
13140 (define_expand "sqrt<mode>2"
13141 [(set (match_operand:MODEF 0 "register_operand" "")
13143 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13144 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13145 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13147 if (<MODE>mode == SFmode
13148 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13149 && flag_finite_math_only && !flag_trapping_math
13150 && flag_unsafe_math_optimizations)
13152 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13156 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13158 rtx op0 = gen_reg_rtx (XFmode);
13159 rtx op1 = force_reg (<MODE>mode, operands[1]);
13161 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13162 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13167 (define_insn "fpremxf4_i387"
13168 [(set (match_operand:XF 0 "register_operand" "=f")
13169 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13170 (match_operand:XF 3 "register_operand" "1")]
13172 (set (match_operand:XF 1 "register_operand" "=u")
13173 (unspec:XF [(match_dup 2) (match_dup 3)]
13175 (set (reg:CCFP FPSR_REG)
13176 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13178 "TARGET_USE_FANCY_MATH_387"
13180 [(set_attr "type" "fpspc")
13181 (set_attr "mode" "XF")])
13183 (define_expand "fmodxf3"
13184 [(use (match_operand:XF 0 "register_operand" ""))
13185 (use (match_operand:XF 1 "general_operand" ""))
13186 (use (match_operand:XF 2 "general_operand" ""))]
13187 "TARGET_USE_FANCY_MATH_387"
13189 rtx label = gen_label_rtx ();
13191 rtx op1 = gen_reg_rtx (XFmode);
13192 rtx op2 = gen_reg_rtx (XFmode);
13194 emit_move_insn (op2, operands[2]);
13195 emit_move_insn (op1, operands[1]);
13197 emit_label (label);
13198 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13199 ix86_emit_fp_unordered_jump (label);
13200 LABEL_NUSES (label) = 1;
13202 emit_move_insn (operands[0], op1);
13206 (define_expand "fmod<mode>3"
13207 [(use (match_operand:MODEF 0 "register_operand" ""))
13208 (use (match_operand:MODEF 1 "general_operand" ""))
13209 (use (match_operand:MODEF 2 "general_operand" ""))]
13210 "TARGET_USE_FANCY_MATH_387"
13212 rtx (*gen_truncxf) (rtx, rtx);
13214 rtx label = gen_label_rtx ();
13216 rtx op1 = gen_reg_rtx (XFmode);
13217 rtx op2 = gen_reg_rtx (XFmode);
13219 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13220 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13222 emit_label (label);
13223 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13224 ix86_emit_fp_unordered_jump (label);
13225 LABEL_NUSES (label) = 1;
13227 /* Truncate the result properly for strict SSE math. */
13228 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13229 && !TARGET_MIX_SSE_I387)
13230 gen_truncxf = gen_truncxf<mode>2;
13232 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13234 emit_insn (gen_truncxf (operands[0], op1));
13238 (define_insn "fprem1xf4_i387"
13239 [(set (match_operand:XF 0 "register_operand" "=f")
13240 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13241 (match_operand:XF 3 "register_operand" "1")]
13243 (set (match_operand:XF 1 "register_operand" "=u")
13244 (unspec:XF [(match_dup 2) (match_dup 3)]
13246 (set (reg:CCFP FPSR_REG)
13247 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13249 "TARGET_USE_FANCY_MATH_387"
13251 [(set_attr "type" "fpspc")
13252 (set_attr "mode" "XF")])
13254 (define_expand "remainderxf3"
13255 [(use (match_operand:XF 0 "register_operand" ""))
13256 (use (match_operand:XF 1 "general_operand" ""))
13257 (use (match_operand:XF 2 "general_operand" ""))]
13258 "TARGET_USE_FANCY_MATH_387"
13260 rtx label = gen_label_rtx ();
13262 rtx op1 = gen_reg_rtx (XFmode);
13263 rtx op2 = gen_reg_rtx (XFmode);
13265 emit_move_insn (op2, operands[2]);
13266 emit_move_insn (op1, operands[1]);
13268 emit_label (label);
13269 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13270 ix86_emit_fp_unordered_jump (label);
13271 LABEL_NUSES (label) = 1;
13273 emit_move_insn (operands[0], op1);
13277 (define_expand "remainder<mode>3"
13278 [(use (match_operand:MODEF 0 "register_operand" ""))
13279 (use (match_operand:MODEF 1 "general_operand" ""))
13280 (use (match_operand:MODEF 2 "general_operand" ""))]
13281 "TARGET_USE_FANCY_MATH_387"
13283 rtx (*gen_truncxf) (rtx, rtx);
13285 rtx label = gen_label_rtx ();
13287 rtx op1 = gen_reg_rtx (XFmode);
13288 rtx op2 = gen_reg_rtx (XFmode);
13290 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13291 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13293 emit_label (label);
13295 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13296 ix86_emit_fp_unordered_jump (label);
13297 LABEL_NUSES (label) = 1;
13299 /* Truncate the result properly for strict SSE math. */
13300 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13301 && !TARGET_MIX_SSE_I387)
13302 gen_truncxf = gen_truncxf<mode>2;
13304 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13306 emit_insn (gen_truncxf (operands[0], op1));
13310 (define_insn "*sinxf2_i387"
13311 [(set (match_operand:XF 0 "register_operand" "=f")
13312 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13313 "TARGET_USE_FANCY_MATH_387
13314 && flag_unsafe_math_optimizations"
13316 [(set_attr "type" "fpspc")
13317 (set_attr "mode" "XF")])
13319 (define_insn "*sin_extend<mode>xf2_i387"
13320 [(set (match_operand:XF 0 "register_operand" "=f")
13321 (unspec:XF [(float_extend:XF
13322 (match_operand:MODEF 1 "register_operand" "0"))]
13324 "TARGET_USE_FANCY_MATH_387
13325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13326 || TARGET_MIX_SSE_I387)
13327 && flag_unsafe_math_optimizations"
13329 [(set_attr "type" "fpspc")
13330 (set_attr "mode" "XF")])
13332 (define_insn "*cosxf2_i387"
13333 [(set (match_operand:XF 0 "register_operand" "=f")
13334 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13335 "TARGET_USE_FANCY_MATH_387
13336 && flag_unsafe_math_optimizations"
13338 [(set_attr "type" "fpspc")
13339 (set_attr "mode" "XF")])
13341 (define_insn "*cos_extend<mode>xf2_i387"
13342 [(set (match_operand:XF 0 "register_operand" "=f")
13343 (unspec:XF [(float_extend:XF
13344 (match_operand:MODEF 1 "register_operand" "0"))]
13346 "TARGET_USE_FANCY_MATH_387
13347 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13348 || TARGET_MIX_SSE_I387)
13349 && flag_unsafe_math_optimizations"
13351 [(set_attr "type" "fpspc")
13352 (set_attr "mode" "XF")])
13354 ;; When sincos pattern is defined, sin and cos builtin functions will be
13355 ;; expanded to sincos pattern with one of its outputs left unused.
13356 ;; CSE pass will figure out if two sincos patterns can be combined,
13357 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13358 ;; depending on the unused output.
13360 (define_insn "sincosxf3"
13361 [(set (match_operand:XF 0 "register_operand" "=f")
13362 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13363 UNSPEC_SINCOS_COS))
13364 (set (match_operand:XF 1 "register_operand" "=u")
13365 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13366 "TARGET_USE_FANCY_MATH_387
13367 && flag_unsafe_math_optimizations"
13369 [(set_attr "type" "fpspc")
13370 (set_attr "mode" "XF")])
13373 [(set (match_operand:XF 0 "register_operand" "")
13374 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13375 UNSPEC_SINCOS_COS))
13376 (set (match_operand:XF 1 "register_operand" "")
13377 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13378 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13379 && can_create_pseudo_p ()"
13380 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13383 [(set (match_operand:XF 0 "register_operand" "")
13384 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13385 UNSPEC_SINCOS_COS))
13386 (set (match_operand:XF 1 "register_operand" "")
13387 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13388 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13389 && can_create_pseudo_p ()"
13390 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13392 (define_insn "sincos_extend<mode>xf3_i387"
13393 [(set (match_operand:XF 0 "register_operand" "=f")
13394 (unspec:XF [(float_extend:XF
13395 (match_operand:MODEF 2 "register_operand" "0"))]
13396 UNSPEC_SINCOS_COS))
13397 (set (match_operand:XF 1 "register_operand" "=u")
13398 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13399 "TARGET_USE_FANCY_MATH_387
13400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13401 || TARGET_MIX_SSE_I387)
13402 && flag_unsafe_math_optimizations"
13404 [(set_attr "type" "fpspc")
13405 (set_attr "mode" "XF")])
13408 [(set (match_operand:XF 0 "register_operand" "")
13409 (unspec:XF [(float_extend:XF
13410 (match_operand:MODEF 2 "register_operand" ""))]
13411 UNSPEC_SINCOS_COS))
13412 (set (match_operand:XF 1 "register_operand" "")
13413 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13414 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13415 && can_create_pseudo_p ()"
13416 [(set (match_dup 1)
13417 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13420 [(set (match_operand:XF 0 "register_operand" "")
13421 (unspec:XF [(float_extend:XF
13422 (match_operand:MODEF 2 "register_operand" ""))]
13423 UNSPEC_SINCOS_COS))
13424 (set (match_operand:XF 1 "register_operand" "")
13425 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13426 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13427 && can_create_pseudo_p ()"
13428 [(set (match_dup 0)
13429 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13431 (define_expand "sincos<mode>3"
13432 [(use (match_operand:MODEF 0 "register_operand" ""))
13433 (use (match_operand:MODEF 1 "register_operand" ""))
13434 (use (match_operand:MODEF 2 "register_operand" ""))]
13435 "TARGET_USE_FANCY_MATH_387
13436 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13437 || TARGET_MIX_SSE_I387)
13438 && flag_unsafe_math_optimizations"
13440 rtx op0 = gen_reg_rtx (XFmode);
13441 rtx op1 = gen_reg_rtx (XFmode);
13443 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13444 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13445 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13449 (define_insn "fptanxf4_i387"
13450 [(set (match_operand:XF 0 "register_operand" "=f")
13451 (match_operand:XF 3 "const_double_operand" "F"))
13452 (set (match_operand:XF 1 "register_operand" "=u")
13453 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13455 "TARGET_USE_FANCY_MATH_387
13456 && flag_unsafe_math_optimizations
13457 && standard_80387_constant_p (operands[3]) == 2"
13459 [(set_attr "type" "fpspc")
13460 (set_attr "mode" "XF")])
13462 (define_insn "fptan_extend<mode>xf4_i387"
13463 [(set (match_operand:MODEF 0 "register_operand" "=f")
13464 (match_operand:MODEF 3 "const_double_operand" "F"))
13465 (set (match_operand:XF 1 "register_operand" "=u")
13466 (unspec:XF [(float_extend:XF
13467 (match_operand:MODEF 2 "register_operand" "0"))]
13469 "TARGET_USE_FANCY_MATH_387
13470 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13471 || TARGET_MIX_SSE_I387)
13472 && flag_unsafe_math_optimizations
13473 && standard_80387_constant_p (operands[3]) == 2"
13475 [(set_attr "type" "fpspc")
13476 (set_attr "mode" "XF")])
13478 (define_expand "tanxf2"
13479 [(use (match_operand:XF 0 "register_operand" ""))
13480 (use (match_operand:XF 1 "register_operand" ""))]
13481 "TARGET_USE_FANCY_MATH_387
13482 && flag_unsafe_math_optimizations"
13484 rtx one = gen_reg_rtx (XFmode);
13485 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13487 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13491 (define_expand "tan<mode>2"
13492 [(use (match_operand:MODEF 0 "register_operand" ""))
13493 (use (match_operand:MODEF 1 "register_operand" ""))]
13494 "TARGET_USE_FANCY_MATH_387
13495 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13496 || TARGET_MIX_SSE_I387)
13497 && flag_unsafe_math_optimizations"
13499 rtx op0 = gen_reg_rtx (XFmode);
13501 rtx one = gen_reg_rtx (<MODE>mode);
13502 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13504 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13505 operands[1], op2));
13506 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13510 (define_insn "*fpatanxf3_i387"
13511 [(set (match_operand:XF 0 "register_operand" "=f")
13512 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13513 (match_operand:XF 2 "register_operand" "u")]
13515 (clobber (match_scratch:XF 3 "=2"))]
13516 "TARGET_USE_FANCY_MATH_387
13517 && flag_unsafe_math_optimizations"
13519 [(set_attr "type" "fpspc")
13520 (set_attr "mode" "XF")])
13522 (define_insn "fpatan_extend<mode>xf3_i387"
13523 [(set (match_operand:XF 0 "register_operand" "=f")
13524 (unspec:XF [(float_extend:XF
13525 (match_operand:MODEF 1 "register_operand" "0"))
13527 (match_operand:MODEF 2 "register_operand" "u"))]
13529 (clobber (match_scratch:XF 3 "=2"))]
13530 "TARGET_USE_FANCY_MATH_387
13531 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13532 || TARGET_MIX_SSE_I387)
13533 && flag_unsafe_math_optimizations"
13535 [(set_attr "type" "fpspc")
13536 (set_attr "mode" "XF")])
13538 (define_expand "atan2xf3"
13539 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13540 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13541 (match_operand:XF 1 "register_operand" "")]
13543 (clobber (match_scratch:XF 3 ""))])]
13544 "TARGET_USE_FANCY_MATH_387
13545 && flag_unsafe_math_optimizations")
13547 (define_expand "atan2<mode>3"
13548 [(use (match_operand:MODEF 0 "register_operand" ""))
13549 (use (match_operand:MODEF 1 "register_operand" ""))
13550 (use (match_operand:MODEF 2 "register_operand" ""))]
13551 "TARGET_USE_FANCY_MATH_387
13552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13553 || TARGET_MIX_SSE_I387)
13554 && flag_unsafe_math_optimizations"
13556 rtx op0 = gen_reg_rtx (XFmode);
13558 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13559 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13563 (define_expand "atanxf2"
13564 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13565 (unspec:XF [(match_dup 2)
13566 (match_operand:XF 1 "register_operand" "")]
13568 (clobber (match_scratch:XF 3 ""))])]
13569 "TARGET_USE_FANCY_MATH_387
13570 && flag_unsafe_math_optimizations"
13572 operands[2] = gen_reg_rtx (XFmode);
13573 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13576 (define_expand "atan<mode>2"
13577 [(use (match_operand:MODEF 0 "register_operand" ""))
13578 (use (match_operand:MODEF 1 "register_operand" ""))]
13579 "TARGET_USE_FANCY_MATH_387
13580 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13581 || TARGET_MIX_SSE_I387)
13582 && flag_unsafe_math_optimizations"
13584 rtx op0 = gen_reg_rtx (XFmode);
13586 rtx op2 = gen_reg_rtx (<MODE>mode);
13587 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13589 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13590 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13594 (define_expand "asinxf2"
13595 [(set (match_dup 2)
13596 (mult:XF (match_operand:XF 1 "register_operand" "")
13598 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13599 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13600 (parallel [(set (match_operand:XF 0 "register_operand" "")
13601 (unspec:XF [(match_dup 5) (match_dup 1)]
13603 (clobber (match_scratch:XF 6 ""))])]
13604 "TARGET_USE_FANCY_MATH_387
13605 && flag_unsafe_math_optimizations"
13609 if (optimize_insn_for_size_p ())
13612 for (i = 2; i < 6; i++)
13613 operands[i] = gen_reg_rtx (XFmode);
13615 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13618 (define_expand "asin<mode>2"
13619 [(use (match_operand:MODEF 0 "register_operand" ""))
13620 (use (match_operand:MODEF 1 "general_operand" ""))]
13621 "TARGET_USE_FANCY_MATH_387
13622 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13623 || TARGET_MIX_SSE_I387)
13624 && flag_unsafe_math_optimizations"
13626 rtx op0 = gen_reg_rtx (XFmode);
13627 rtx op1 = gen_reg_rtx (XFmode);
13629 if (optimize_insn_for_size_p ())
13632 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13633 emit_insn (gen_asinxf2 (op0, op1));
13634 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13638 (define_expand "acosxf2"
13639 [(set (match_dup 2)
13640 (mult:XF (match_operand:XF 1 "register_operand" "")
13642 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13643 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13644 (parallel [(set (match_operand:XF 0 "register_operand" "")
13645 (unspec:XF [(match_dup 1) (match_dup 5)]
13647 (clobber (match_scratch:XF 6 ""))])]
13648 "TARGET_USE_FANCY_MATH_387
13649 && flag_unsafe_math_optimizations"
13653 if (optimize_insn_for_size_p ())
13656 for (i = 2; i < 6; i++)
13657 operands[i] = gen_reg_rtx (XFmode);
13659 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13662 (define_expand "acos<mode>2"
13663 [(use (match_operand:MODEF 0 "register_operand" ""))
13664 (use (match_operand:MODEF 1 "general_operand" ""))]
13665 "TARGET_USE_FANCY_MATH_387
13666 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13667 || TARGET_MIX_SSE_I387)
13668 && flag_unsafe_math_optimizations"
13670 rtx op0 = gen_reg_rtx (XFmode);
13671 rtx op1 = gen_reg_rtx (XFmode);
13673 if (optimize_insn_for_size_p ())
13676 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13677 emit_insn (gen_acosxf2 (op0, op1));
13678 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13682 (define_insn "fyl2xxf3_i387"
13683 [(set (match_operand:XF 0 "register_operand" "=f")
13684 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13685 (match_operand:XF 2 "register_operand" "u")]
13687 (clobber (match_scratch:XF 3 "=2"))]
13688 "TARGET_USE_FANCY_MATH_387
13689 && flag_unsafe_math_optimizations"
13691 [(set_attr "type" "fpspc")
13692 (set_attr "mode" "XF")])
13694 (define_insn "fyl2x_extend<mode>xf3_i387"
13695 [(set (match_operand:XF 0 "register_operand" "=f")
13696 (unspec:XF [(float_extend:XF
13697 (match_operand:MODEF 1 "register_operand" "0"))
13698 (match_operand:XF 2 "register_operand" "u")]
13700 (clobber (match_scratch:XF 3 "=2"))]
13701 "TARGET_USE_FANCY_MATH_387
13702 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13703 || TARGET_MIX_SSE_I387)
13704 && flag_unsafe_math_optimizations"
13706 [(set_attr "type" "fpspc")
13707 (set_attr "mode" "XF")])
13709 (define_expand "logxf2"
13710 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13711 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13712 (match_dup 2)] UNSPEC_FYL2X))
13713 (clobber (match_scratch:XF 3 ""))])]
13714 "TARGET_USE_FANCY_MATH_387
13715 && flag_unsafe_math_optimizations"
13717 operands[2] = gen_reg_rtx (XFmode);
13718 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13721 (define_expand "log<mode>2"
13722 [(use (match_operand:MODEF 0 "register_operand" ""))
13723 (use (match_operand:MODEF 1 "register_operand" ""))]
13724 "TARGET_USE_FANCY_MATH_387
13725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13726 || TARGET_MIX_SSE_I387)
13727 && flag_unsafe_math_optimizations"
13729 rtx op0 = gen_reg_rtx (XFmode);
13731 rtx op2 = gen_reg_rtx (XFmode);
13732 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13734 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13735 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13739 (define_expand "log10xf2"
13740 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13741 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13742 (match_dup 2)] UNSPEC_FYL2X))
13743 (clobber (match_scratch:XF 3 ""))])]
13744 "TARGET_USE_FANCY_MATH_387
13745 && flag_unsafe_math_optimizations"
13747 operands[2] = gen_reg_rtx (XFmode);
13748 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13751 (define_expand "log10<mode>2"
13752 [(use (match_operand:MODEF 0 "register_operand" ""))
13753 (use (match_operand:MODEF 1 "register_operand" ""))]
13754 "TARGET_USE_FANCY_MATH_387
13755 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13756 || TARGET_MIX_SSE_I387)
13757 && flag_unsafe_math_optimizations"
13759 rtx op0 = gen_reg_rtx (XFmode);
13761 rtx op2 = gen_reg_rtx (XFmode);
13762 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13764 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13765 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13769 (define_expand "log2xf2"
13770 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13771 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13772 (match_dup 2)] UNSPEC_FYL2X))
13773 (clobber (match_scratch:XF 3 ""))])]
13774 "TARGET_USE_FANCY_MATH_387
13775 && flag_unsafe_math_optimizations"
13777 operands[2] = gen_reg_rtx (XFmode);
13778 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13781 (define_expand "log2<mode>2"
13782 [(use (match_operand:MODEF 0 "register_operand" ""))
13783 (use (match_operand:MODEF 1 "register_operand" ""))]
13784 "TARGET_USE_FANCY_MATH_387
13785 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13786 || TARGET_MIX_SSE_I387)
13787 && flag_unsafe_math_optimizations"
13789 rtx op0 = gen_reg_rtx (XFmode);
13791 rtx op2 = gen_reg_rtx (XFmode);
13792 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13794 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13795 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13799 (define_insn "fyl2xp1xf3_i387"
13800 [(set (match_operand:XF 0 "register_operand" "=f")
13801 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13802 (match_operand:XF 2 "register_operand" "u")]
13804 (clobber (match_scratch:XF 3 "=2"))]
13805 "TARGET_USE_FANCY_MATH_387
13806 && flag_unsafe_math_optimizations"
13808 [(set_attr "type" "fpspc")
13809 (set_attr "mode" "XF")])
13811 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13812 [(set (match_operand:XF 0 "register_operand" "=f")
13813 (unspec:XF [(float_extend:XF
13814 (match_operand:MODEF 1 "register_operand" "0"))
13815 (match_operand:XF 2 "register_operand" "u")]
13817 (clobber (match_scratch:XF 3 "=2"))]
13818 "TARGET_USE_FANCY_MATH_387
13819 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13820 || TARGET_MIX_SSE_I387)
13821 && flag_unsafe_math_optimizations"
13823 [(set_attr "type" "fpspc")
13824 (set_attr "mode" "XF")])
13826 (define_expand "log1pxf2"
13827 [(use (match_operand:XF 0 "register_operand" ""))
13828 (use (match_operand:XF 1 "register_operand" ""))]
13829 "TARGET_USE_FANCY_MATH_387
13830 && flag_unsafe_math_optimizations"
13832 if (optimize_insn_for_size_p ())
13835 ix86_emit_i387_log1p (operands[0], operands[1]);
13839 (define_expand "log1p<mode>2"
13840 [(use (match_operand:MODEF 0 "register_operand" ""))
13841 (use (match_operand:MODEF 1 "register_operand" ""))]
13842 "TARGET_USE_FANCY_MATH_387
13843 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13844 || TARGET_MIX_SSE_I387)
13845 && flag_unsafe_math_optimizations"
13849 if (optimize_insn_for_size_p ())
13852 op0 = gen_reg_rtx (XFmode);
13854 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13856 ix86_emit_i387_log1p (op0, operands[1]);
13857 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13861 (define_insn "fxtractxf3_i387"
13862 [(set (match_operand:XF 0 "register_operand" "=f")
13863 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13864 UNSPEC_XTRACT_FRACT))
13865 (set (match_operand:XF 1 "register_operand" "=u")
13866 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13867 "TARGET_USE_FANCY_MATH_387
13868 && flag_unsafe_math_optimizations"
13870 [(set_attr "type" "fpspc")
13871 (set_attr "mode" "XF")])
13873 (define_insn "fxtract_extend<mode>xf3_i387"
13874 [(set (match_operand:XF 0 "register_operand" "=f")
13875 (unspec:XF [(float_extend:XF
13876 (match_operand:MODEF 2 "register_operand" "0"))]
13877 UNSPEC_XTRACT_FRACT))
13878 (set (match_operand:XF 1 "register_operand" "=u")
13879 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13880 "TARGET_USE_FANCY_MATH_387
13881 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13882 || TARGET_MIX_SSE_I387)
13883 && flag_unsafe_math_optimizations"
13885 [(set_attr "type" "fpspc")
13886 (set_attr "mode" "XF")])
13888 (define_expand "logbxf2"
13889 [(parallel [(set (match_dup 2)
13890 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13891 UNSPEC_XTRACT_FRACT))
13892 (set (match_operand:XF 0 "register_operand" "")
13893 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13894 "TARGET_USE_FANCY_MATH_387
13895 && flag_unsafe_math_optimizations"
13896 "operands[2] = gen_reg_rtx (XFmode);")
13898 (define_expand "logb<mode>2"
13899 [(use (match_operand:MODEF 0 "register_operand" ""))
13900 (use (match_operand:MODEF 1 "register_operand" ""))]
13901 "TARGET_USE_FANCY_MATH_387
13902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13903 || TARGET_MIX_SSE_I387)
13904 && flag_unsafe_math_optimizations"
13906 rtx op0 = gen_reg_rtx (XFmode);
13907 rtx op1 = gen_reg_rtx (XFmode);
13909 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13910 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13914 (define_expand "ilogbxf2"
13915 [(use (match_operand:SI 0 "register_operand" ""))
13916 (use (match_operand:XF 1 "register_operand" ""))]
13917 "TARGET_USE_FANCY_MATH_387
13918 && flag_unsafe_math_optimizations"
13922 if (optimize_insn_for_size_p ())
13925 op0 = gen_reg_rtx (XFmode);
13926 op1 = gen_reg_rtx (XFmode);
13928 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13929 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13933 (define_expand "ilogb<mode>2"
13934 [(use (match_operand:SI 0 "register_operand" ""))
13935 (use (match_operand:MODEF 1 "register_operand" ""))]
13936 "TARGET_USE_FANCY_MATH_387
13937 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13938 || TARGET_MIX_SSE_I387)
13939 && flag_unsafe_math_optimizations"
13943 if (optimize_insn_for_size_p ())
13946 op0 = gen_reg_rtx (XFmode);
13947 op1 = gen_reg_rtx (XFmode);
13949 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13950 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13954 (define_insn "*f2xm1xf2_i387"
13955 [(set (match_operand:XF 0 "register_operand" "=f")
13956 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13958 "TARGET_USE_FANCY_MATH_387
13959 && flag_unsafe_math_optimizations"
13961 [(set_attr "type" "fpspc")
13962 (set_attr "mode" "XF")])
13964 (define_insn "*fscalexf4_i387"
13965 [(set (match_operand:XF 0 "register_operand" "=f")
13966 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13967 (match_operand:XF 3 "register_operand" "1")]
13968 UNSPEC_FSCALE_FRACT))
13969 (set (match_operand:XF 1 "register_operand" "=u")
13970 (unspec:XF [(match_dup 2) (match_dup 3)]
13971 UNSPEC_FSCALE_EXP))]
13972 "TARGET_USE_FANCY_MATH_387
13973 && flag_unsafe_math_optimizations"
13975 [(set_attr "type" "fpspc")
13976 (set_attr "mode" "XF")])
13978 (define_expand "expNcorexf3"
13979 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13980 (match_operand:XF 2 "register_operand" "")))
13981 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13982 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13983 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13984 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13985 (parallel [(set (match_operand:XF 0 "register_operand" "")
13986 (unspec:XF [(match_dup 8) (match_dup 4)]
13987 UNSPEC_FSCALE_FRACT))
13989 (unspec:XF [(match_dup 8) (match_dup 4)]
13990 UNSPEC_FSCALE_EXP))])]
13991 "TARGET_USE_FANCY_MATH_387
13992 && flag_unsafe_math_optimizations"
13996 if (optimize_insn_for_size_p ())
13999 for (i = 3; i < 10; i++)
14000 operands[i] = gen_reg_rtx (XFmode);
14002 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14005 (define_expand "expxf2"
14006 [(use (match_operand:XF 0 "register_operand" ""))
14007 (use (match_operand:XF 1 "register_operand" ""))]
14008 "TARGET_USE_FANCY_MATH_387
14009 && flag_unsafe_math_optimizations"
14013 if (optimize_insn_for_size_p ())
14016 op2 = gen_reg_rtx (XFmode);
14017 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14019 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14023 (define_expand "exp<mode>2"
14024 [(use (match_operand:MODEF 0 "register_operand" ""))
14025 (use (match_operand:MODEF 1 "general_operand" ""))]
14026 "TARGET_USE_FANCY_MATH_387
14027 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14028 || TARGET_MIX_SSE_I387)
14029 && flag_unsafe_math_optimizations"
14033 if (optimize_insn_for_size_p ())
14036 op0 = gen_reg_rtx (XFmode);
14037 op1 = gen_reg_rtx (XFmode);
14039 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14040 emit_insn (gen_expxf2 (op0, op1));
14041 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14045 (define_expand "exp10xf2"
14046 [(use (match_operand:XF 0 "register_operand" ""))
14047 (use (match_operand:XF 1 "register_operand" ""))]
14048 "TARGET_USE_FANCY_MATH_387
14049 && flag_unsafe_math_optimizations"
14053 if (optimize_insn_for_size_p ())
14056 op2 = gen_reg_rtx (XFmode);
14057 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14059 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14063 (define_expand "exp10<mode>2"
14064 [(use (match_operand:MODEF 0 "register_operand" ""))
14065 (use (match_operand:MODEF 1 "general_operand" ""))]
14066 "TARGET_USE_FANCY_MATH_387
14067 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14068 || TARGET_MIX_SSE_I387)
14069 && flag_unsafe_math_optimizations"
14073 if (optimize_insn_for_size_p ())
14076 op0 = gen_reg_rtx (XFmode);
14077 op1 = gen_reg_rtx (XFmode);
14079 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14080 emit_insn (gen_exp10xf2 (op0, op1));
14081 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14085 (define_expand "exp2xf2"
14086 [(use (match_operand:XF 0 "register_operand" ""))
14087 (use (match_operand:XF 1 "register_operand" ""))]
14088 "TARGET_USE_FANCY_MATH_387
14089 && flag_unsafe_math_optimizations"
14093 if (optimize_insn_for_size_p ())
14096 op2 = gen_reg_rtx (XFmode);
14097 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14099 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14103 (define_expand "exp2<mode>2"
14104 [(use (match_operand:MODEF 0 "register_operand" ""))
14105 (use (match_operand:MODEF 1 "general_operand" ""))]
14106 "TARGET_USE_FANCY_MATH_387
14107 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14108 || TARGET_MIX_SSE_I387)
14109 && flag_unsafe_math_optimizations"
14113 if (optimize_insn_for_size_p ())
14116 op0 = gen_reg_rtx (XFmode);
14117 op1 = gen_reg_rtx (XFmode);
14119 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14120 emit_insn (gen_exp2xf2 (op0, op1));
14121 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14125 (define_expand "expm1xf2"
14126 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14128 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14129 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14130 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14131 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14132 (parallel [(set (match_dup 7)
14133 (unspec:XF [(match_dup 6) (match_dup 4)]
14134 UNSPEC_FSCALE_FRACT))
14136 (unspec:XF [(match_dup 6) (match_dup 4)]
14137 UNSPEC_FSCALE_EXP))])
14138 (parallel [(set (match_dup 10)
14139 (unspec:XF [(match_dup 9) (match_dup 8)]
14140 UNSPEC_FSCALE_FRACT))
14141 (set (match_dup 11)
14142 (unspec:XF [(match_dup 9) (match_dup 8)]
14143 UNSPEC_FSCALE_EXP))])
14144 (set (match_dup 12) (minus:XF (match_dup 10)
14145 (float_extend:XF (match_dup 13))))
14146 (set (match_operand:XF 0 "register_operand" "")
14147 (plus:XF (match_dup 12) (match_dup 7)))]
14148 "TARGET_USE_FANCY_MATH_387
14149 && flag_unsafe_math_optimizations"
14153 if (optimize_insn_for_size_p ())
14156 for (i = 2; i < 13; i++)
14157 operands[i] = gen_reg_rtx (XFmode);
14160 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14162 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14165 (define_expand "expm1<mode>2"
14166 [(use (match_operand:MODEF 0 "register_operand" ""))
14167 (use (match_operand:MODEF 1 "general_operand" ""))]
14168 "TARGET_USE_FANCY_MATH_387
14169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14170 || TARGET_MIX_SSE_I387)
14171 && flag_unsafe_math_optimizations"
14175 if (optimize_insn_for_size_p ())
14178 op0 = gen_reg_rtx (XFmode);
14179 op1 = gen_reg_rtx (XFmode);
14181 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14182 emit_insn (gen_expm1xf2 (op0, op1));
14183 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14187 (define_expand "ldexpxf3"
14188 [(set (match_dup 3)
14189 (float:XF (match_operand:SI 2 "register_operand" "")))
14190 (parallel [(set (match_operand:XF 0 " register_operand" "")
14191 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14193 UNSPEC_FSCALE_FRACT))
14195 (unspec:XF [(match_dup 1) (match_dup 3)]
14196 UNSPEC_FSCALE_EXP))])]
14197 "TARGET_USE_FANCY_MATH_387
14198 && flag_unsafe_math_optimizations"
14200 if (optimize_insn_for_size_p ())
14203 operands[3] = gen_reg_rtx (XFmode);
14204 operands[4] = gen_reg_rtx (XFmode);
14207 (define_expand "ldexp<mode>3"
14208 [(use (match_operand:MODEF 0 "register_operand" ""))
14209 (use (match_operand:MODEF 1 "general_operand" ""))
14210 (use (match_operand:SI 2 "register_operand" ""))]
14211 "TARGET_USE_FANCY_MATH_387
14212 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14213 || TARGET_MIX_SSE_I387)
14214 && flag_unsafe_math_optimizations"
14218 if (optimize_insn_for_size_p ())
14221 op0 = gen_reg_rtx (XFmode);
14222 op1 = gen_reg_rtx (XFmode);
14224 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14225 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14226 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14230 (define_expand "scalbxf3"
14231 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14232 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14233 (match_operand:XF 2 "register_operand" "")]
14234 UNSPEC_FSCALE_FRACT))
14236 (unspec:XF [(match_dup 1) (match_dup 2)]
14237 UNSPEC_FSCALE_EXP))])]
14238 "TARGET_USE_FANCY_MATH_387
14239 && flag_unsafe_math_optimizations"
14241 if (optimize_insn_for_size_p ())
14244 operands[3] = gen_reg_rtx (XFmode);
14247 (define_expand "scalb<mode>3"
14248 [(use (match_operand:MODEF 0 "register_operand" ""))
14249 (use (match_operand:MODEF 1 "general_operand" ""))
14250 (use (match_operand:MODEF 2 "general_operand" ""))]
14251 "TARGET_USE_FANCY_MATH_387
14252 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14253 || TARGET_MIX_SSE_I387)
14254 && flag_unsafe_math_optimizations"
14258 if (optimize_insn_for_size_p ())
14261 op0 = gen_reg_rtx (XFmode);
14262 op1 = gen_reg_rtx (XFmode);
14263 op2 = gen_reg_rtx (XFmode);
14265 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14266 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14267 emit_insn (gen_scalbxf3 (op0, op1, op2));
14268 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14272 (define_expand "significandxf2"
14273 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14274 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14275 UNSPEC_XTRACT_FRACT))
14277 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14278 "TARGET_USE_FANCY_MATH_387
14279 && flag_unsafe_math_optimizations"
14280 "operands[2] = gen_reg_rtx (XFmode);")
14282 (define_expand "significand<mode>2"
14283 [(use (match_operand:MODEF 0 "register_operand" ""))
14284 (use (match_operand:MODEF 1 "register_operand" ""))]
14285 "TARGET_USE_FANCY_MATH_387
14286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14287 || TARGET_MIX_SSE_I387)
14288 && flag_unsafe_math_optimizations"
14290 rtx op0 = gen_reg_rtx (XFmode);
14291 rtx op1 = gen_reg_rtx (XFmode);
14293 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14294 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14299 (define_insn "sse4_1_round<mode>2"
14300 [(set (match_operand:MODEF 0 "register_operand" "=x")
14301 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14302 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14305 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14306 [(set_attr "type" "ssecvt")
14307 (set_attr "prefix_extra" "1")
14308 (set_attr "prefix" "maybe_vex")
14309 (set_attr "mode" "<MODE>")])
14311 (define_insn "rintxf2"
14312 [(set (match_operand:XF 0 "register_operand" "=f")
14313 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14315 "TARGET_USE_FANCY_MATH_387
14316 && flag_unsafe_math_optimizations"
14318 [(set_attr "type" "fpspc")
14319 (set_attr "mode" "XF")])
14321 (define_expand "rint<mode>2"
14322 [(use (match_operand:MODEF 0 "register_operand" ""))
14323 (use (match_operand:MODEF 1 "register_operand" ""))]
14324 "(TARGET_USE_FANCY_MATH_387
14325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14326 || TARGET_MIX_SSE_I387)
14327 && flag_unsafe_math_optimizations)
14328 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14329 && !flag_trapping_math)"
14331 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14332 && !flag_trapping_math)
14334 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14337 emit_insn (gen_sse4_1_round<mode>2
14338 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14340 ix86_expand_rint (operand0, operand1);
14344 rtx op0 = gen_reg_rtx (XFmode);
14345 rtx op1 = gen_reg_rtx (XFmode);
14347 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14348 emit_insn (gen_rintxf2 (op0, op1));
14350 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14355 (define_expand "round<mode>2"
14356 [(match_operand:MODEF 0 "register_operand" "")
14357 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14358 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14359 && !flag_trapping_math && !flag_rounding_math"
14361 if (optimize_insn_for_size_p ())
14363 if (TARGET_64BIT || (<MODE>mode != DFmode))
14364 ix86_expand_round (operand0, operand1);
14366 ix86_expand_rounddf_32 (operand0, operand1);
14370 (define_insn_and_split "*fistdi2_1"
14371 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14372 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14374 "TARGET_USE_FANCY_MATH_387
14375 && can_create_pseudo_p ()"
14380 if (memory_operand (operands[0], VOIDmode))
14381 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14384 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14385 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14390 [(set_attr "type" "fpspc")
14391 (set_attr "mode" "DI")])
14393 (define_insn "fistdi2"
14394 [(set (match_operand:DI 0 "memory_operand" "=m")
14395 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14397 (clobber (match_scratch:XF 2 "=&1f"))]
14398 "TARGET_USE_FANCY_MATH_387"
14399 "* return output_fix_trunc (insn, operands, false);"
14400 [(set_attr "type" "fpspc")
14401 (set_attr "mode" "DI")])
14403 (define_insn "fistdi2_with_temp"
14404 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14405 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14407 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14408 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14409 "TARGET_USE_FANCY_MATH_387"
14411 [(set_attr "type" "fpspc")
14412 (set_attr "mode" "DI")])
14415 [(set (match_operand:DI 0 "register_operand" "")
14416 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14418 (clobber (match_operand:DI 2 "memory_operand" ""))
14419 (clobber (match_scratch 3 ""))]
14421 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14422 (clobber (match_dup 3))])
14423 (set (match_dup 0) (match_dup 2))])
14426 [(set (match_operand:DI 0 "memory_operand" "")
14427 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14429 (clobber (match_operand:DI 2 "memory_operand" ""))
14430 (clobber (match_scratch 3 ""))]
14432 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14433 (clobber (match_dup 3))])])
14435 (define_insn_and_split "*fist<mode>2_1"
14436 [(set (match_operand:SWI24 0 "register_operand" "")
14437 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14439 "TARGET_USE_FANCY_MATH_387
14440 && can_create_pseudo_p ()"
14445 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14446 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14450 [(set_attr "type" "fpspc")
14451 (set_attr "mode" "<MODE>")])
14453 (define_insn "fist<mode>2"
14454 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14455 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14457 "TARGET_USE_FANCY_MATH_387"
14458 "* return output_fix_trunc (insn, operands, false);"
14459 [(set_attr "type" "fpspc")
14460 (set_attr "mode" "<MODE>")])
14462 (define_insn "fist<mode>2_with_temp"
14463 [(set (match_operand:SWI24 0 "register_operand" "=r")
14464 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14466 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14467 "TARGET_USE_FANCY_MATH_387"
14469 [(set_attr "type" "fpspc")
14470 (set_attr "mode" "<MODE>")])
14473 [(set (match_operand:SWI24 0 "register_operand" "")
14474 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14476 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14478 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14479 (set (match_dup 0) (match_dup 2))])
14482 [(set (match_operand:SWI24 0 "memory_operand" "")
14483 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14485 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14487 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14489 (define_expand "lrintxf<mode>2"
14490 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14491 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14493 "TARGET_USE_FANCY_MATH_387")
14495 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14496 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14497 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14498 UNSPEC_FIX_NOTRUNC))]
14499 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14500 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14502 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14503 [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14504 (match_operand:MODEF 1 "register_operand" "")]
14505 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14506 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14507 && !flag_trapping_math && !flag_rounding_math"
14509 if (optimize_insn_for_size_p ())
14511 ix86_expand_lround (operand0, operand1);
14515 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14516 (define_insn_and_split "frndintxf2_floor"
14517 [(set (match_operand:XF 0 "register_operand" "")
14518 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14519 UNSPEC_FRNDINT_FLOOR))
14520 (clobber (reg:CC FLAGS_REG))]
14521 "TARGET_USE_FANCY_MATH_387
14522 && flag_unsafe_math_optimizations
14523 && can_create_pseudo_p ()"
14528 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14530 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14531 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14533 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14534 operands[2], operands[3]));
14537 [(set_attr "type" "frndint")
14538 (set_attr "i387_cw" "floor")
14539 (set_attr "mode" "XF")])
14541 (define_insn "frndintxf2_floor_i387"
14542 [(set (match_operand:XF 0 "register_operand" "=f")
14543 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14544 UNSPEC_FRNDINT_FLOOR))
14545 (use (match_operand:HI 2 "memory_operand" "m"))
14546 (use (match_operand:HI 3 "memory_operand" "m"))]
14547 "TARGET_USE_FANCY_MATH_387
14548 && flag_unsafe_math_optimizations"
14549 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14550 [(set_attr "type" "frndint")
14551 (set_attr "i387_cw" "floor")
14552 (set_attr "mode" "XF")])
14554 (define_expand "floorxf2"
14555 [(use (match_operand:XF 0 "register_operand" ""))
14556 (use (match_operand:XF 1 "register_operand" ""))]
14557 "TARGET_USE_FANCY_MATH_387
14558 && flag_unsafe_math_optimizations"
14560 if (optimize_insn_for_size_p ())
14562 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14566 (define_expand "floor<mode>2"
14567 [(use (match_operand:MODEF 0 "register_operand" ""))
14568 (use (match_operand:MODEF 1 "register_operand" ""))]
14569 "(TARGET_USE_FANCY_MATH_387
14570 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14571 || TARGET_MIX_SSE_I387)
14572 && flag_unsafe_math_optimizations)
14573 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14574 && !flag_trapping_math)"
14576 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14577 && !flag_trapping_math
14578 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14580 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14583 emit_insn (gen_sse4_1_round<mode>2
14584 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14585 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14586 ix86_expand_floorceil (operand0, operand1, true);
14588 ix86_expand_floorceildf_32 (operand0, operand1, true);
14594 if (optimize_insn_for_size_p ())
14597 op0 = gen_reg_rtx (XFmode);
14598 op1 = gen_reg_rtx (XFmode);
14599 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14600 emit_insn (gen_frndintxf2_floor (op0, op1));
14602 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14607 (define_insn_and_split "*fist<mode>2_floor_1"
14608 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14609 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14610 UNSPEC_FIST_FLOOR))
14611 (clobber (reg:CC FLAGS_REG))]
14612 "TARGET_USE_FANCY_MATH_387
14613 && flag_unsafe_math_optimizations
14614 && can_create_pseudo_p ()"
14619 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14621 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14622 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14623 if (memory_operand (operands[0], VOIDmode))
14624 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14625 operands[2], operands[3]));
14628 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14629 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14630 operands[2], operands[3],
14635 [(set_attr "type" "fistp")
14636 (set_attr "i387_cw" "floor")
14637 (set_attr "mode" "<MODE>")])
14639 (define_insn "fistdi2_floor"
14640 [(set (match_operand:DI 0 "memory_operand" "=m")
14641 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14642 UNSPEC_FIST_FLOOR))
14643 (use (match_operand:HI 2 "memory_operand" "m"))
14644 (use (match_operand:HI 3 "memory_operand" "m"))
14645 (clobber (match_scratch:XF 4 "=&1f"))]
14646 "TARGET_USE_FANCY_MATH_387
14647 && flag_unsafe_math_optimizations"
14648 "* return output_fix_trunc (insn, operands, false);"
14649 [(set_attr "type" "fistp")
14650 (set_attr "i387_cw" "floor")
14651 (set_attr "mode" "DI")])
14653 (define_insn "fistdi2_floor_with_temp"
14654 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14655 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14656 UNSPEC_FIST_FLOOR))
14657 (use (match_operand:HI 2 "memory_operand" "m,m"))
14658 (use (match_operand:HI 3 "memory_operand" "m,m"))
14659 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14660 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14661 "TARGET_USE_FANCY_MATH_387
14662 && flag_unsafe_math_optimizations"
14664 [(set_attr "type" "fistp")
14665 (set_attr "i387_cw" "floor")
14666 (set_attr "mode" "DI")])
14669 [(set (match_operand:DI 0 "register_operand" "")
14670 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14671 UNSPEC_FIST_FLOOR))
14672 (use (match_operand:HI 2 "memory_operand" ""))
14673 (use (match_operand:HI 3 "memory_operand" ""))
14674 (clobber (match_operand:DI 4 "memory_operand" ""))
14675 (clobber (match_scratch 5 ""))]
14677 [(parallel [(set (match_dup 4)
14678 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14679 (use (match_dup 2))
14680 (use (match_dup 3))
14681 (clobber (match_dup 5))])
14682 (set (match_dup 0) (match_dup 4))])
14685 [(set (match_operand:DI 0 "memory_operand" "")
14686 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14687 UNSPEC_FIST_FLOOR))
14688 (use (match_operand:HI 2 "memory_operand" ""))
14689 (use (match_operand:HI 3 "memory_operand" ""))
14690 (clobber (match_operand:DI 4 "memory_operand" ""))
14691 (clobber (match_scratch 5 ""))]
14693 [(parallel [(set (match_dup 0)
14694 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14695 (use (match_dup 2))
14696 (use (match_dup 3))
14697 (clobber (match_dup 5))])])
14699 (define_insn "fist<mode>2_floor"
14700 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14701 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14702 UNSPEC_FIST_FLOOR))
14703 (use (match_operand:HI 2 "memory_operand" "m"))
14704 (use (match_operand:HI 3 "memory_operand" "m"))]
14705 "TARGET_USE_FANCY_MATH_387
14706 && flag_unsafe_math_optimizations"
14707 "* return output_fix_trunc (insn, operands, false);"
14708 [(set_attr "type" "fistp")
14709 (set_attr "i387_cw" "floor")
14710 (set_attr "mode" "<MODE>")])
14712 (define_insn "fist<mode>2_floor_with_temp"
14713 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14714 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14715 UNSPEC_FIST_FLOOR))
14716 (use (match_operand:HI 2 "memory_operand" "m,m"))
14717 (use (match_operand:HI 3 "memory_operand" "m,m"))
14718 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14719 "TARGET_USE_FANCY_MATH_387
14720 && flag_unsafe_math_optimizations"
14722 [(set_attr "type" "fistp")
14723 (set_attr "i387_cw" "floor")
14724 (set_attr "mode" "<MODE>")])
14727 [(set (match_operand:SWI24 0 "register_operand" "")
14728 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14729 UNSPEC_FIST_FLOOR))
14730 (use (match_operand:HI 2 "memory_operand" ""))
14731 (use (match_operand:HI 3 "memory_operand" ""))
14732 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14734 [(parallel [(set (match_dup 4)
14735 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14736 (use (match_dup 2))
14737 (use (match_dup 3))])
14738 (set (match_dup 0) (match_dup 4))])
14741 [(set (match_operand:SWI24 0 "memory_operand" "")
14742 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14743 UNSPEC_FIST_FLOOR))
14744 (use (match_operand:HI 2 "memory_operand" ""))
14745 (use (match_operand:HI 3 "memory_operand" ""))
14746 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14748 [(parallel [(set (match_dup 0)
14749 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14750 (use (match_dup 2))
14751 (use (match_dup 3))])])
14753 (define_expand "lfloorxf<mode>2"
14754 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14755 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14756 UNSPEC_FIST_FLOOR))
14757 (clobber (reg:CC FLAGS_REG))])]
14758 "TARGET_USE_FANCY_MATH_387
14759 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14760 && flag_unsafe_math_optimizations")
14762 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14763 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14764 (match_operand:MODEF 1 "register_operand" "")]
14765 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14766 && !flag_trapping_math"
14768 if (TARGET_64BIT && optimize_insn_for_size_p ())
14770 ix86_expand_lfloorceil (operand0, operand1, true);
14774 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14775 (define_insn_and_split "frndintxf2_ceil"
14776 [(set (match_operand:XF 0 "register_operand" "")
14777 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14778 UNSPEC_FRNDINT_CEIL))
14779 (clobber (reg:CC FLAGS_REG))]
14780 "TARGET_USE_FANCY_MATH_387
14781 && flag_unsafe_math_optimizations
14782 && can_create_pseudo_p ()"
14787 ix86_optimize_mode_switching[I387_CEIL] = 1;
14789 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14790 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14792 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14793 operands[2], operands[3]));
14796 [(set_attr "type" "frndint")
14797 (set_attr "i387_cw" "ceil")
14798 (set_attr "mode" "XF")])
14800 (define_insn "frndintxf2_ceil_i387"
14801 [(set (match_operand:XF 0 "register_operand" "=f")
14802 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14803 UNSPEC_FRNDINT_CEIL))
14804 (use (match_operand:HI 2 "memory_operand" "m"))
14805 (use (match_operand:HI 3 "memory_operand" "m"))]
14806 "TARGET_USE_FANCY_MATH_387
14807 && flag_unsafe_math_optimizations"
14808 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14809 [(set_attr "type" "frndint")
14810 (set_attr "i387_cw" "ceil")
14811 (set_attr "mode" "XF")])
14813 (define_expand "ceilxf2"
14814 [(use (match_operand:XF 0 "register_operand" ""))
14815 (use (match_operand:XF 1 "register_operand" ""))]
14816 "TARGET_USE_FANCY_MATH_387
14817 && flag_unsafe_math_optimizations"
14819 if (optimize_insn_for_size_p ())
14821 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14825 (define_expand "ceil<mode>2"
14826 [(use (match_operand:MODEF 0 "register_operand" ""))
14827 (use (match_operand:MODEF 1 "register_operand" ""))]
14828 "(TARGET_USE_FANCY_MATH_387
14829 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14830 || TARGET_MIX_SSE_I387)
14831 && flag_unsafe_math_optimizations)
14832 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14833 && !flag_trapping_math)"
14835 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14836 && !flag_trapping_math
14837 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14840 emit_insn (gen_sse4_1_round<mode>2
14841 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14842 else if (optimize_insn_for_size_p ())
14844 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14845 ix86_expand_floorceil (operand0, operand1, false);
14847 ix86_expand_floorceildf_32 (operand0, operand1, false);
14853 if (optimize_insn_for_size_p ())
14856 op0 = gen_reg_rtx (XFmode);
14857 op1 = gen_reg_rtx (XFmode);
14858 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14859 emit_insn (gen_frndintxf2_ceil (op0, op1));
14861 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14866 (define_insn_and_split "*fist<mode>2_ceil_1"
14867 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14868 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14870 (clobber (reg:CC FLAGS_REG))]
14871 "TARGET_USE_FANCY_MATH_387
14872 && flag_unsafe_math_optimizations
14873 && can_create_pseudo_p ()"
14878 ix86_optimize_mode_switching[I387_CEIL] = 1;
14880 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14881 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14882 if (memory_operand (operands[0], VOIDmode))
14883 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14884 operands[2], operands[3]));
14887 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14888 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14889 operands[2], operands[3],
14894 [(set_attr "type" "fistp")
14895 (set_attr "i387_cw" "ceil")
14896 (set_attr "mode" "<MODE>")])
14898 (define_insn "fistdi2_ceil"
14899 [(set (match_operand:DI 0 "memory_operand" "=m")
14900 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14902 (use (match_operand:HI 2 "memory_operand" "m"))
14903 (use (match_operand:HI 3 "memory_operand" "m"))
14904 (clobber (match_scratch:XF 4 "=&1f"))]
14905 "TARGET_USE_FANCY_MATH_387
14906 && flag_unsafe_math_optimizations"
14907 "* return output_fix_trunc (insn, operands, false);"
14908 [(set_attr "type" "fistp")
14909 (set_attr "i387_cw" "ceil")
14910 (set_attr "mode" "DI")])
14912 (define_insn "fistdi2_ceil_with_temp"
14913 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14914 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14916 (use (match_operand:HI 2 "memory_operand" "m,m"))
14917 (use (match_operand:HI 3 "memory_operand" "m,m"))
14918 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14919 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14920 "TARGET_USE_FANCY_MATH_387
14921 && flag_unsafe_math_optimizations"
14923 [(set_attr "type" "fistp")
14924 (set_attr "i387_cw" "ceil")
14925 (set_attr "mode" "DI")])
14928 [(set (match_operand:DI 0 "register_operand" "")
14929 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14931 (use (match_operand:HI 2 "memory_operand" ""))
14932 (use (match_operand:HI 3 "memory_operand" ""))
14933 (clobber (match_operand:DI 4 "memory_operand" ""))
14934 (clobber (match_scratch 5 ""))]
14936 [(parallel [(set (match_dup 4)
14937 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14938 (use (match_dup 2))
14939 (use (match_dup 3))
14940 (clobber (match_dup 5))])
14941 (set (match_dup 0) (match_dup 4))])
14944 [(set (match_operand:DI 0 "memory_operand" "")
14945 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14947 (use (match_operand:HI 2 "memory_operand" ""))
14948 (use (match_operand:HI 3 "memory_operand" ""))
14949 (clobber (match_operand:DI 4 "memory_operand" ""))
14950 (clobber (match_scratch 5 ""))]
14952 [(parallel [(set (match_dup 0)
14953 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14954 (use (match_dup 2))
14955 (use (match_dup 3))
14956 (clobber (match_dup 5))])])
14958 (define_insn "fist<mode>2_ceil"
14959 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14960 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14962 (use (match_operand:HI 2 "memory_operand" "m"))
14963 (use (match_operand:HI 3 "memory_operand" "m"))]
14964 "TARGET_USE_FANCY_MATH_387
14965 && flag_unsafe_math_optimizations"
14966 "* return output_fix_trunc (insn, operands, false);"
14967 [(set_attr "type" "fistp")
14968 (set_attr "i387_cw" "ceil")
14969 (set_attr "mode" "<MODE>")])
14971 (define_insn "fist<mode>2_ceil_with_temp"
14972 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14973 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14975 (use (match_operand:HI 2 "memory_operand" "m,m"))
14976 (use (match_operand:HI 3 "memory_operand" "m,m"))
14977 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14978 "TARGET_USE_FANCY_MATH_387
14979 && flag_unsafe_math_optimizations"
14981 [(set_attr "type" "fistp")
14982 (set_attr "i387_cw" "ceil")
14983 (set_attr "mode" "<MODE>")])
14986 [(set (match_operand:SWI24 0 "register_operand" "")
14987 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14989 (use (match_operand:HI 2 "memory_operand" ""))
14990 (use (match_operand:HI 3 "memory_operand" ""))
14991 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14993 [(parallel [(set (match_dup 4)
14994 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
14995 (use (match_dup 2))
14996 (use (match_dup 3))])
14997 (set (match_dup 0) (match_dup 4))])
15000 [(set (match_operand:SWI24 0 "memory_operand" "")
15001 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15003 (use (match_operand:HI 2 "memory_operand" ""))
15004 (use (match_operand:HI 3 "memory_operand" ""))
15005 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15007 [(parallel [(set (match_dup 0)
15008 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15009 (use (match_dup 2))
15010 (use (match_dup 3))])])
15012 (define_expand "lceilxf<mode>2"
15013 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15014 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15016 (clobber (reg:CC FLAGS_REG))])]
15017 "TARGET_USE_FANCY_MATH_387
15018 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15019 && flag_unsafe_math_optimizations")
15021 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15022 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15023 (match_operand:MODEF 1 "register_operand" "")]
15024 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15025 && !flag_trapping_math"
15027 ix86_expand_lfloorceil (operand0, operand1, false);
15031 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15032 (define_insn_and_split "frndintxf2_trunc"
15033 [(set (match_operand:XF 0 "register_operand" "")
15034 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15035 UNSPEC_FRNDINT_TRUNC))
15036 (clobber (reg:CC FLAGS_REG))]
15037 "TARGET_USE_FANCY_MATH_387
15038 && flag_unsafe_math_optimizations
15039 && can_create_pseudo_p ()"
15044 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15046 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15047 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15049 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15050 operands[2], operands[3]));
15053 [(set_attr "type" "frndint")
15054 (set_attr "i387_cw" "trunc")
15055 (set_attr "mode" "XF")])
15057 (define_insn "frndintxf2_trunc_i387"
15058 [(set (match_operand:XF 0 "register_operand" "=f")
15059 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15060 UNSPEC_FRNDINT_TRUNC))
15061 (use (match_operand:HI 2 "memory_operand" "m"))
15062 (use (match_operand:HI 3 "memory_operand" "m"))]
15063 "TARGET_USE_FANCY_MATH_387
15064 && flag_unsafe_math_optimizations"
15065 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15066 [(set_attr "type" "frndint")
15067 (set_attr "i387_cw" "trunc")
15068 (set_attr "mode" "XF")])
15070 (define_expand "btruncxf2"
15071 [(use (match_operand:XF 0 "register_operand" ""))
15072 (use (match_operand:XF 1 "register_operand" ""))]
15073 "TARGET_USE_FANCY_MATH_387
15074 && flag_unsafe_math_optimizations"
15076 if (optimize_insn_for_size_p ())
15078 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15082 (define_expand "btrunc<mode>2"
15083 [(use (match_operand:MODEF 0 "register_operand" ""))
15084 (use (match_operand:MODEF 1 "register_operand" ""))]
15085 "(TARGET_USE_FANCY_MATH_387
15086 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15087 || TARGET_MIX_SSE_I387)
15088 && flag_unsafe_math_optimizations)
15089 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15090 && !flag_trapping_math)"
15092 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15093 && !flag_trapping_math
15094 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15097 emit_insn (gen_sse4_1_round<mode>2
15098 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15099 else if (optimize_insn_for_size_p ())
15101 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15102 ix86_expand_trunc (operand0, operand1);
15104 ix86_expand_truncdf_32 (operand0, operand1);
15110 if (optimize_insn_for_size_p ())
15113 op0 = gen_reg_rtx (XFmode);
15114 op1 = gen_reg_rtx (XFmode);
15115 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15116 emit_insn (gen_frndintxf2_trunc (op0, op1));
15118 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15123 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15124 (define_insn_and_split "frndintxf2_mask_pm"
15125 [(set (match_operand:XF 0 "register_operand" "")
15126 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15127 UNSPEC_FRNDINT_MASK_PM))
15128 (clobber (reg:CC FLAGS_REG))]
15129 "TARGET_USE_FANCY_MATH_387
15130 && flag_unsafe_math_optimizations
15131 && can_create_pseudo_p ()"
15136 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15138 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15139 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15141 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15142 operands[2], operands[3]));
15145 [(set_attr "type" "frndint")
15146 (set_attr "i387_cw" "mask_pm")
15147 (set_attr "mode" "XF")])
15149 (define_insn "frndintxf2_mask_pm_i387"
15150 [(set (match_operand:XF 0 "register_operand" "=f")
15151 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15152 UNSPEC_FRNDINT_MASK_PM))
15153 (use (match_operand:HI 2 "memory_operand" "m"))
15154 (use (match_operand:HI 3 "memory_operand" "m"))]
15155 "TARGET_USE_FANCY_MATH_387
15156 && flag_unsafe_math_optimizations"
15157 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15158 [(set_attr "type" "frndint")
15159 (set_attr "i387_cw" "mask_pm")
15160 (set_attr "mode" "XF")])
15162 (define_expand "nearbyintxf2"
15163 [(use (match_operand:XF 0 "register_operand" ""))
15164 (use (match_operand:XF 1 "register_operand" ""))]
15165 "TARGET_USE_FANCY_MATH_387
15166 && flag_unsafe_math_optimizations"
15168 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15172 (define_expand "nearbyint<mode>2"
15173 [(use (match_operand:MODEF 0 "register_operand" ""))
15174 (use (match_operand:MODEF 1 "register_operand" ""))]
15175 "TARGET_USE_FANCY_MATH_387
15176 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15177 || TARGET_MIX_SSE_I387)
15178 && flag_unsafe_math_optimizations"
15180 rtx op0 = gen_reg_rtx (XFmode);
15181 rtx op1 = gen_reg_rtx (XFmode);
15183 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15184 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15186 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15190 (define_insn "fxam<mode>2_i387"
15191 [(set (match_operand:HI 0 "register_operand" "=a")
15193 [(match_operand:X87MODEF 1 "register_operand" "f")]
15195 "TARGET_USE_FANCY_MATH_387"
15196 "fxam\n\tfnstsw\t%0"
15197 [(set_attr "type" "multi")
15198 (set_attr "length" "4")
15199 (set_attr "unit" "i387")
15200 (set_attr "mode" "<MODE>")])
15202 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15203 [(set (match_operand:HI 0 "register_operand" "")
15205 [(match_operand:MODEF 1 "memory_operand" "")]
15207 "TARGET_USE_FANCY_MATH_387
15208 && can_create_pseudo_p ()"
15211 [(set (match_dup 2)(match_dup 1))
15213 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15215 operands[2] = gen_reg_rtx (<MODE>mode);
15217 MEM_VOLATILE_P (operands[1]) = 1;
15219 [(set_attr "type" "multi")
15220 (set_attr "unit" "i387")
15221 (set_attr "mode" "<MODE>")])
15223 (define_expand "isinfxf2"
15224 [(use (match_operand:SI 0 "register_operand" ""))
15225 (use (match_operand:XF 1 "register_operand" ""))]
15226 "TARGET_USE_FANCY_MATH_387
15227 && TARGET_C99_FUNCTIONS"
15229 rtx mask = GEN_INT (0x45);
15230 rtx val = GEN_INT (0x05);
15234 rtx scratch = gen_reg_rtx (HImode);
15235 rtx res = gen_reg_rtx (QImode);
15237 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15239 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15240 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15241 cond = gen_rtx_fmt_ee (EQ, QImode,
15242 gen_rtx_REG (CCmode, FLAGS_REG),
15244 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15245 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15249 (define_expand "isinf<mode>2"
15250 [(use (match_operand:SI 0 "register_operand" ""))
15251 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15252 "TARGET_USE_FANCY_MATH_387
15253 && TARGET_C99_FUNCTIONS
15254 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15256 rtx mask = GEN_INT (0x45);
15257 rtx val = GEN_INT (0x05);
15261 rtx scratch = gen_reg_rtx (HImode);
15262 rtx res = gen_reg_rtx (QImode);
15264 /* Remove excess precision by forcing value through memory. */
15265 if (memory_operand (operands[1], VOIDmode))
15266 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15269 enum ix86_stack_slot slot = (virtuals_instantiated
15272 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15274 emit_move_insn (temp, operands[1]);
15275 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15278 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15279 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15280 cond = gen_rtx_fmt_ee (EQ, QImode,
15281 gen_rtx_REG (CCmode, FLAGS_REG),
15283 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15284 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15288 (define_expand "signbitxf2"
15289 [(use (match_operand:SI 0 "register_operand" ""))
15290 (use (match_operand:XF 1 "register_operand" ""))]
15291 "TARGET_USE_FANCY_MATH_387"
15293 rtx scratch = gen_reg_rtx (HImode);
15295 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15296 emit_insn (gen_andsi3 (operands[0],
15297 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15301 (define_insn "movmsk_df"
15302 [(set (match_operand:SI 0 "register_operand" "=r")
15304 [(match_operand:DF 1 "register_operand" "x")]
15306 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15307 "%vmovmskpd\t{%1, %0|%0, %1}"
15308 [(set_attr "type" "ssemov")
15309 (set_attr "prefix" "maybe_vex")
15310 (set_attr "mode" "DF")])
15312 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15313 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15314 (define_expand "signbitdf2"
15315 [(use (match_operand:SI 0 "register_operand" ""))
15316 (use (match_operand:DF 1 "register_operand" ""))]
15317 "TARGET_USE_FANCY_MATH_387
15318 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15320 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15322 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15323 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15327 rtx scratch = gen_reg_rtx (HImode);
15329 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15330 emit_insn (gen_andsi3 (operands[0],
15331 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15336 (define_expand "signbitsf2"
15337 [(use (match_operand:SI 0 "register_operand" ""))
15338 (use (match_operand:SF 1 "register_operand" ""))]
15339 "TARGET_USE_FANCY_MATH_387
15340 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15342 rtx scratch = gen_reg_rtx (HImode);
15344 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15345 emit_insn (gen_andsi3 (operands[0],
15346 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15350 ;; Block operation instructions
15353 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15356 [(set_attr "length" "1")
15357 (set_attr "length_immediate" "0")
15358 (set_attr "modrm" "0")])
15360 (define_expand "movmem<mode>"
15361 [(use (match_operand:BLK 0 "memory_operand" ""))
15362 (use (match_operand:BLK 1 "memory_operand" ""))
15363 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15364 (use (match_operand:SWI48 3 "const_int_operand" ""))
15365 (use (match_operand:SI 4 "const_int_operand" ""))
15366 (use (match_operand:SI 5 "const_int_operand" ""))]
15369 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15370 operands[4], operands[5]))
15376 ;; Most CPUs don't like single string operations
15377 ;; Handle this case here to simplify previous expander.
15379 (define_expand "strmov"
15380 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15381 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15382 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15383 (clobber (reg:CC FLAGS_REG))])
15384 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15385 (clobber (reg:CC FLAGS_REG))])]
15388 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15390 /* If .md ever supports :P for Pmode, these can be directly
15391 in the pattern above. */
15392 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15393 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15395 /* Can't use this if the user has appropriated esi or edi. */
15396 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15397 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15399 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15400 operands[2], operands[3],
15401 operands[5], operands[6]));
15405 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15408 (define_expand "strmov_singleop"
15409 [(parallel [(set (match_operand 1 "memory_operand" "")
15410 (match_operand 3 "memory_operand" ""))
15411 (set (match_operand 0 "register_operand" "")
15412 (match_operand 4 "" ""))
15413 (set (match_operand 2 "register_operand" "")
15414 (match_operand 5 "" ""))])]
15416 "ix86_current_function_needs_cld = 1;")
15418 (define_insn "*strmovdi_rex_1"
15419 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15420 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15421 (set (match_operand:DI 0 "register_operand" "=D")
15422 (plus:DI (match_dup 2)
15424 (set (match_operand:DI 1 "register_operand" "=S")
15425 (plus:DI (match_dup 3)
15429 [(set_attr "type" "str")
15430 (set_attr "memory" "both")
15431 (set_attr "mode" "DI")])
15433 (define_insn "*strmovsi_1"
15434 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15435 (mem:SI (match_operand:P 3 "register_operand" "1")))
15436 (set (match_operand:P 0 "register_operand" "=D")
15437 (plus:P (match_dup 2)
15439 (set (match_operand:P 1 "register_operand" "=S")
15440 (plus:P (match_dup 3)
15444 [(set_attr "type" "str")
15445 (set_attr "memory" "both")
15446 (set_attr "mode" "SI")])
15448 (define_insn "*strmovhi_1"
15449 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15450 (mem:HI (match_operand:P 3 "register_operand" "1")))
15451 (set (match_operand:P 0 "register_operand" "=D")
15452 (plus:P (match_dup 2)
15454 (set (match_operand:P 1 "register_operand" "=S")
15455 (plus:P (match_dup 3)
15459 [(set_attr "type" "str")
15460 (set_attr "memory" "both")
15461 (set_attr "mode" "HI")])
15463 (define_insn "*strmovqi_1"
15464 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15465 (mem:QI (match_operand:P 3 "register_operand" "1")))
15466 (set (match_operand:P 0 "register_operand" "=D")
15467 (plus:P (match_dup 2)
15469 (set (match_operand:P 1 "register_operand" "=S")
15470 (plus:P (match_dup 3)
15474 [(set_attr "type" "str")
15475 (set_attr "memory" "both")
15476 (set (attr "prefix_rex")
15478 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15480 (const_string "*")))
15481 (set_attr "mode" "QI")])
15483 (define_expand "rep_mov"
15484 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15485 (set (match_operand 0 "register_operand" "")
15486 (match_operand 5 "" ""))
15487 (set (match_operand 2 "register_operand" "")
15488 (match_operand 6 "" ""))
15489 (set (match_operand 1 "memory_operand" "")
15490 (match_operand 3 "memory_operand" ""))
15491 (use (match_dup 4))])]
15493 "ix86_current_function_needs_cld = 1;")
15495 (define_insn "*rep_movdi_rex64"
15496 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15497 (set (match_operand:DI 0 "register_operand" "=D")
15498 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15500 (match_operand:DI 3 "register_operand" "0")))
15501 (set (match_operand:DI 1 "register_operand" "=S")
15502 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15503 (match_operand:DI 4 "register_operand" "1")))
15504 (set (mem:BLK (match_dup 3))
15505 (mem:BLK (match_dup 4)))
15506 (use (match_dup 5))]
15509 [(set_attr "type" "str")
15510 (set_attr "prefix_rep" "1")
15511 (set_attr "memory" "both")
15512 (set_attr "mode" "DI")])
15514 (define_insn "*rep_movsi"
15515 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15516 (set (match_operand:P 0 "register_operand" "=D")
15517 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15519 (match_operand:P 3 "register_operand" "0")))
15520 (set (match_operand:P 1 "register_operand" "=S")
15521 (plus:P (ashift:P (match_dup 5) (const_int 2))
15522 (match_operand:P 4 "register_operand" "1")))
15523 (set (mem:BLK (match_dup 3))
15524 (mem:BLK (match_dup 4)))
15525 (use (match_dup 5))]
15527 "rep{%;} movs{l|d}"
15528 [(set_attr "type" "str")
15529 (set_attr "prefix_rep" "1")
15530 (set_attr "memory" "both")
15531 (set_attr "mode" "SI")])
15533 (define_insn "*rep_movqi"
15534 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15535 (set (match_operand:P 0 "register_operand" "=D")
15536 (plus:P (match_operand:P 3 "register_operand" "0")
15537 (match_operand:P 5 "register_operand" "2")))
15538 (set (match_operand:P 1 "register_operand" "=S")
15539 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15540 (set (mem:BLK (match_dup 3))
15541 (mem:BLK (match_dup 4)))
15542 (use (match_dup 5))]
15545 [(set_attr "type" "str")
15546 (set_attr "prefix_rep" "1")
15547 (set_attr "memory" "both")
15548 (set_attr "mode" "QI")])
15550 (define_expand "setmem<mode>"
15551 [(use (match_operand:BLK 0 "memory_operand" ""))
15552 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15553 (use (match_operand:QI 2 "nonmemory_operand" ""))
15554 (use (match_operand 3 "const_int_operand" ""))
15555 (use (match_operand:SI 4 "const_int_operand" ""))
15556 (use (match_operand:SI 5 "const_int_operand" ""))]
15559 if (ix86_expand_setmem (operands[0], operands[1],
15560 operands[2], operands[3],
15561 operands[4], operands[5]))
15567 ;; Most CPUs don't like single string operations
15568 ;; Handle this case here to simplify previous expander.
15570 (define_expand "strset"
15571 [(set (match_operand 1 "memory_operand" "")
15572 (match_operand 2 "register_operand" ""))
15573 (parallel [(set (match_operand 0 "register_operand" "")
15575 (clobber (reg:CC FLAGS_REG))])]
15578 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15579 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15581 /* If .md ever supports :P for Pmode, this can be directly
15582 in the pattern above. */
15583 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15584 GEN_INT (GET_MODE_SIZE (GET_MODE
15586 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15588 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15594 (define_expand "strset_singleop"
15595 [(parallel [(set (match_operand 1 "memory_operand" "")
15596 (match_operand 2 "register_operand" ""))
15597 (set (match_operand 0 "register_operand" "")
15598 (match_operand 3 "" ""))])]
15600 "ix86_current_function_needs_cld = 1;")
15602 (define_insn "*strsetdi_rex_1"
15603 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15604 (match_operand:DI 2 "register_operand" "a"))
15605 (set (match_operand:DI 0 "register_operand" "=D")
15606 (plus:DI (match_dup 1)
15610 [(set_attr "type" "str")
15611 (set_attr "memory" "store")
15612 (set_attr "mode" "DI")])
15614 (define_insn "*strsetsi_1"
15615 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15616 (match_operand:SI 2 "register_operand" "a"))
15617 (set (match_operand:P 0 "register_operand" "=D")
15618 (plus:P (match_dup 1)
15622 [(set_attr "type" "str")
15623 (set_attr "memory" "store")
15624 (set_attr "mode" "SI")])
15626 (define_insn "*strsethi_1"
15627 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15628 (match_operand:HI 2 "register_operand" "a"))
15629 (set (match_operand:P 0 "register_operand" "=D")
15630 (plus:P (match_dup 1)
15634 [(set_attr "type" "str")
15635 (set_attr "memory" "store")
15636 (set_attr "mode" "HI")])
15638 (define_insn "*strsetqi_1"
15639 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15640 (match_operand:QI 2 "register_operand" "a"))
15641 (set (match_operand:P 0 "register_operand" "=D")
15642 (plus:P (match_dup 1)
15646 [(set_attr "type" "str")
15647 (set_attr "memory" "store")
15648 (set (attr "prefix_rex")
15650 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15652 (const_string "*")))
15653 (set_attr "mode" "QI")])
15655 (define_expand "rep_stos"
15656 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15657 (set (match_operand 0 "register_operand" "")
15658 (match_operand 4 "" ""))
15659 (set (match_operand 2 "memory_operand" "") (const_int 0))
15660 (use (match_operand 3 "register_operand" ""))
15661 (use (match_dup 1))])]
15663 "ix86_current_function_needs_cld = 1;")
15665 (define_insn "*rep_stosdi_rex64"
15666 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15667 (set (match_operand:DI 0 "register_operand" "=D")
15668 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15670 (match_operand:DI 3 "register_operand" "0")))
15671 (set (mem:BLK (match_dup 3))
15673 (use (match_operand:DI 2 "register_operand" "a"))
15674 (use (match_dup 4))]
15677 [(set_attr "type" "str")
15678 (set_attr "prefix_rep" "1")
15679 (set_attr "memory" "store")
15680 (set_attr "mode" "DI")])
15682 (define_insn "*rep_stossi"
15683 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15684 (set (match_operand:P 0 "register_operand" "=D")
15685 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15687 (match_operand:P 3 "register_operand" "0")))
15688 (set (mem:BLK (match_dup 3))
15690 (use (match_operand:SI 2 "register_operand" "a"))
15691 (use (match_dup 4))]
15693 "rep{%;} stos{l|d}"
15694 [(set_attr "type" "str")
15695 (set_attr "prefix_rep" "1")
15696 (set_attr "memory" "store")
15697 (set_attr "mode" "SI")])
15699 (define_insn "*rep_stosqi"
15700 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15701 (set (match_operand:P 0 "register_operand" "=D")
15702 (plus:P (match_operand:P 3 "register_operand" "0")
15703 (match_operand:P 4 "register_operand" "1")))
15704 (set (mem:BLK (match_dup 3))
15706 (use (match_operand:QI 2 "register_operand" "a"))
15707 (use (match_dup 4))]
15710 [(set_attr "type" "str")
15711 (set_attr "prefix_rep" "1")
15712 (set_attr "memory" "store")
15713 (set (attr "prefix_rex")
15715 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15717 (const_string "*")))
15718 (set_attr "mode" "QI")])
15720 (define_expand "cmpstrnsi"
15721 [(set (match_operand:SI 0 "register_operand" "")
15722 (compare:SI (match_operand:BLK 1 "general_operand" "")
15723 (match_operand:BLK 2 "general_operand" "")))
15724 (use (match_operand 3 "general_operand" ""))
15725 (use (match_operand 4 "immediate_operand" ""))]
15728 rtx addr1, addr2, out, outlow, count, countreg, align;
15730 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15733 /* Can't use this if the user has appropriated esi or edi. */
15734 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15739 out = gen_reg_rtx (SImode);
15741 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15742 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15743 if (addr1 != XEXP (operands[1], 0))
15744 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15745 if (addr2 != XEXP (operands[2], 0))
15746 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15748 count = operands[3];
15749 countreg = ix86_zero_extend_to_Pmode (count);
15751 /* %%% Iff we are testing strict equality, we can use known alignment
15752 to good advantage. This may be possible with combine, particularly
15753 once cc0 is dead. */
15754 align = operands[4];
15756 if (CONST_INT_P (count))
15758 if (INTVAL (count) == 0)
15760 emit_move_insn (operands[0], const0_rtx);
15763 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15764 operands[1], operands[2]));
15768 rtx (*gen_cmp) (rtx, rtx);
15770 gen_cmp = (TARGET_64BIT
15771 ? gen_cmpdi_1 : gen_cmpsi_1);
15773 emit_insn (gen_cmp (countreg, countreg));
15774 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15775 operands[1], operands[2]));
15778 outlow = gen_lowpart (QImode, out);
15779 emit_insn (gen_cmpintqi (outlow));
15780 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15782 if (operands[0] != out)
15783 emit_move_insn (operands[0], out);
15788 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15790 (define_expand "cmpintqi"
15791 [(set (match_dup 1)
15792 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15794 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15795 (parallel [(set (match_operand:QI 0 "register_operand" "")
15796 (minus:QI (match_dup 1)
15798 (clobber (reg:CC FLAGS_REG))])]
15801 operands[1] = gen_reg_rtx (QImode);
15802 operands[2] = gen_reg_rtx (QImode);
15805 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15806 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15808 (define_expand "cmpstrnqi_nz_1"
15809 [(parallel [(set (reg:CC FLAGS_REG)
15810 (compare:CC (match_operand 4 "memory_operand" "")
15811 (match_operand 5 "memory_operand" "")))
15812 (use (match_operand 2 "register_operand" ""))
15813 (use (match_operand:SI 3 "immediate_operand" ""))
15814 (clobber (match_operand 0 "register_operand" ""))
15815 (clobber (match_operand 1 "register_operand" ""))
15816 (clobber (match_dup 2))])]
15818 "ix86_current_function_needs_cld = 1;")
15820 (define_insn "*cmpstrnqi_nz_1"
15821 [(set (reg:CC FLAGS_REG)
15822 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15823 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15824 (use (match_operand:P 6 "register_operand" "2"))
15825 (use (match_operand:SI 3 "immediate_operand" "i"))
15826 (clobber (match_operand:P 0 "register_operand" "=S"))
15827 (clobber (match_operand:P 1 "register_operand" "=D"))
15828 (clobber (match_operand:P 2 "register_operand" "=c"))]
15831 [(set_attr "type" "str")
15832 (set_attr "mode" "QI")
15833 (set (attr "prefix_rex")
15835 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15837 (const_string "*")))
15838 (set_attr "prefix_rep" "1")])
15840 ;; The same, but the count is not known to not be zero.
15842 (define_expand "cmpstrnqi_1"
15843 [(parallel [(set (reg:CC FLAGS_REG)
15844 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15846 (compare:CC (match_operand 4 "memory_operand" "")
15847 (match_operand 5 "memory_operand" ""))
15849 (use (match_operand:SI 3 "immediate_operand" ""))
15850 (use (reg:CC FLAGS_REG))
15851 (clobber (match_operand 0 "register_operand" ""))
15852 (clobber (match_operand 1 "register_operand" ""))
15853 (clobber (match_dup 2))])]
15855 "ix86_current_function_needs_cld = 1;")
15857 (define_insn "*cmpstrnqi_1"
15858 [(set (reg:CC FLAGS_REG)
15859 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15861 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15862 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15864 (use (match_operand:SI 3 "immediate_operand" "i"))
15865 (use (reg:CC FLAGS_REG))
15866 (clobber (match_operand:P 0 "register_operand" "=S"))
15867 (clobber (match_operand:P 1 "register_operand" "=D"))
15868 (clobber (match_operand:P 2 "register_operand" "=c"))]
15871 [(set_attr "type" "str")
15872 (set_attr "mode" "QI")
15873 (set (attr "prefix_rex")
15875 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15877 (const_string "*")))
15878 (set_attr "prefix_rep" "1")])
15880 (define_expand "strlen<mode>"
15881 [(set (match_operand:SWI48x 0 "register_operand" "")
15882 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15883 (match_operand:QI 2 "immediate_operand" "")
15884 (match_operand 3 "immediate_operand" "")]
15888 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15894 (define_expand "strlenqi_1"
15895 [(parallel [(set (match_operand 0 "register_operand" "")
15896 (match_operand 2 "" ""))
15897 (clobber (match_operand 1 "register_operand" ""))
15898 (clobber (reg:CC FLAGS_REG))])]
15900 "ix86_current_function_needs_cld = 1;")
15902 (define_insn "*strlenqi_1"
15903 [(set (match_operand:P 0 "register_operand" "=&c")
15904 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15905 (match_operand:QI 2 "register_operand" "a")
15906 (match_operand:P 3 "immediate_operand" "i")
15907 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15908 (clobber (match_operand:P 1 "register_operand" "=D"))
15909 (clobber (reg:CC FLAGS_REG))]
15912 [(set_attr "type" "str")
15913 (set_attr "mode" "QI")
15914 (set (attr "prefix_rex")
15916 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15918 (const_string "*")))
15919 (set_attr "prefix_rep" "1")])
15921 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15922 ;; handled in combine, but it is not currently up to the task.
15923 ;; When used for their truth value, the cmpstrn* expanders generate
15932 ;; The intermediate three instructions are unnecessary.
15934 ;; This one handles cmpstrn*_nz_1...
15937 (set (reg:CC FLAGS_REG)
15938 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15939 (mem:BLK (match_operand 5 "register_operand" ""))))
15940 (use (match_operand 6 "register_operand" ""))
15941 (use (match_operand:SI 3 "immediate_operand" ""))
15942 (clobber (match_operand 0 "register_operand" ""))
15943 (clobber (match_operand 1 "register_operand" ""))
15944 (clobber (match_operand 2 "register_operand" ""))])
15945 (set (match_operand:QI 7 "register_operand" "")
15946 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15947 (set (match_operand:QI 8 "register_operand" "")
15948 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15949 (set (reg FLAGS_REG)
15950 (compare (match_dup 7) (match_dup 8)))
15952 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15954 (set (reg:CC FLAGS_REG)
15955 (compare:CC (mem:BLK (match_dup 4))
15956 (mem:BLK (match_dup 5))))
15957 (use (match_dup 6))
15958 (use (match_dup 3))
15959 (clobber (match_dup 0))
15960 (clobber (match_dup 1))
15961 (clobber (match_dup 2))])])
15963 ;; ...and this one handles cmpstrn*_1.
15966 (set (reg:CC FLAGS_REG)
15967 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15969 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15970 (mem:BLK (match_operand 5 "register_operand" "")))
15972 (use (match_operand:SI 3 "immediate_operand" ""))
15973 (use (reg:CC FLAGS_REG))
15974 (clobber (match_operand 0 "register_operand" ""))
15975 (clobber (match_operand 1 "register_operand" ""))
15976 (clobber (match_operand 2 "register_operand" ""))])
15977 (set (match_operand:QI 7 "register_operand" "")
15978 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15979 (set (match_operand:QI 8 "register_operand" "")
15980 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15981 (set (reg FLAGS_REG)
15982 (compare (match_dup 7) (match_dup 8)))
15984 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15986 (set (reg:CC FLAGS_REG)
15987 (if_then_else:CC (ne (match_dup 6)
15989 (compare:CC (mem:BLK (match_dup 4))
15990 (mem:BLK (match_dup 5)))
15992 (use (match_dup 3))
15993 (use (reg:CC FLAGS_REG))
15994 (clobber (match_dup 0))
15995 (clobber (match_dup 1))
15996 (clobber (match_dup 2))])])
15998 ;; Conditional move instructions.
16000 (define_expand "mov<mode>cc"
16001 [(set (match_operand:SWIM 0 "register_operand" "")
16002 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16003 (match_operand:SWIM 2 "general_operand" "")
16004 (match_operand:SWIM 3 "general_operand" "")))]
16006 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16008 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16009 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16010 ;; So just document what we're doing explicitly.
16012 (define_expand "x86_mov<mode>cc_0_m1"
16014 [(set (match_operand:SWI48 0 "register_operand" "")
16015 (if_then_else:SWI48
16016 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16017 [(match_operand 1 "flags_reg_operand" "")
16021 (clobber (reg:CC FLAGS_REG))])])
16023 (define_insn "*x86_mov<mode>cc_0_m1"
16024 [(set (match_operand:SWI48 0 "register_operand" "=r")
16025 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16026 [(reg FLAGS_REG) (const_int 0)])
16029 (clobber (reg:CC FLAGS_REG))]
16031 "sbb{<imodesuffix>}\t%0, %0"
16032 ; Since we don't have the proper number of operands for an alu insn,
16033 ; fill in all the blanks.
16034 [(set_attr "type" "alu")
16035 (set_attr "use_carry" "1")
16036 (set_attr "pent_pair" "pu")
16037 (set_attr "memory" "none")
16038 (set_attr "imm_disp" "false")
16039 (set_attr "mode" "<MODE>")
16040 (set_attr "length_immediate" "0")])
16042 (define_insn "*x86_mov<mode>cc_0_m1_se"
16043 [(set (match_operand:SWI48 0 "register_operand" "=r")
16044 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16045 [(reg FLAGS_REG) (const_int 0)])
16048 (clobber (reg:CC FLAGS_REG))]
16050 "sbb{<imodesuffix>}\t%0, %0"
16051 [(set_attr "type" "alu")
16052 (set_attr "use_carry" "1")
16053 (set_attr "pent_pair" "pu")
16054 (set_attr "memory" "none")
16055 (set_attr "imm_disp" "false")
16056 (set_attr "mode" "<MODE>")
16057 (set_attr "length_immediate" "0")])
16059 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16060 [(set (match_operand:SWI48 0 "register_operand" "=r")
16061 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16062 [(reg FLAGS_REG) (const_int 0)])))]
16064 "sbb{<imodesuffix>}\t%0, %0"
16065 [(set_attr "type" "alu")
16066 (set_attr "use_carry" "1")
16067 (set_attr "pent_pair" "pu")
16068 (set_attr "memory" "none")
16069 (set_attr "imm_disp" "false")
16070 (set_attr "mode" "<MODE>")
16071 (set_attr "length_immediate" "0")])
16073 (define_insn "*mov<mode>cc_noc"
16074 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16075 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16076 [(reg FLAGS_REG) (const_int 0)])
16077 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16078 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16079 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16081 cmov%O2%C1\t{%2, %0|%0, %2}
16082 cmov%O2%c1\t{%3, %0|%0, %3}"
16083 [(set_attr "type" "icmov")
16084 (set_attr "mode" "<MODE>")])
16086 (define_insn_and_split "*movqicc_noc"
16087 [(set (match_operand:QI 0 "register_operand" "=r,r")
16088 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16089 [(match_operand 4 "flags_reg_operand" "")
16091 (match_operand:QI 2 "register_operand" "r,0")
16092 (match_operand:QI 3 "register_operand" "0,r")))]
16093 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16095 "&& reload_completed"
16096 [(set (match_dup 0)
16097 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16100 "operands[0] = gen_lowpart (SImode, operands[0]);
16101 operands[2] = gen_lowpart (SImode, operands[2]);
16102 operands[3] = gen_lowpart (SImode, operands[3]);"
16103 [(set_attr "type" "icmov")
16104 (set_attr "mode" "SI")])
16106 (define_expand "mov<mode>cc"
16107 [(set (match_operand:X87MODEF 0 "register_operand" "")
16108 (if_then_else:X87MODEF
16109 (match_operand 1 "ix86_fp_comparison_operator" "")
16110 (match_operand:X87MODEF 2 "register_operand" "")
16111 (match_operand:X87MODEF 3 "register_operand" "")))]
16112 "(TARGET_80387 && TARGET_CMOVE)
16113 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16114 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16116 (define_insn "*movxfcc_1"
16117 [(set (match_operand:XF 0 "register_operand" "=f,f")
16118 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16119 [(reg FLAGS_REG) (const_int 0)])
16120 (match_operand:XF 2 "register_operand" "f,0")
16121 (match_operand:XF 3 "register_operand" "0,f")))]
16122 "TARGET_80387 && TARGET_CMOVE"
16124 fcmov%F1\t{%2, %0|%0, %2}
16125 fcmov%f1\t{%3, %0|%0, %3}"
16126 [(set_attr "type" "fcmov")
16127 (set_attr "mode" "XF")])
16129 (define_insn "*movdfcc_1_rex64"
16130 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16131 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16132 [(reg FLAGS_REG) (const_int 0)])
16133 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16134 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16135 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16136 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16138 fcmov%F1\t{%2, %0|%0, %2}
16139 fcmov%f1\t{%3, %0|%0, %3}
16140 cmov%O2%C1\t{%2, %0|%0, %2}
16141 cmov%O2%c1\t{%3, %0|%0, %3}"
16142 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16143 (set_attr "mode" "DF,DF,DI,DI")])
16145 (define_insn "*movdfcc_1"
16146 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16147 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16148 [(reg FLAGS_REG) (const_int 0)])
16149 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16150 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16151 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16152 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16154 fcmov%F1\t{%2, %0|%0, %2}
16155 fcmov%f1\t{%3, %0|%0, %3}
16158 [(set_attr "type" "fcmov,fcmov,multi,multi")
16159 (set_attr "mode" "DF,DF,DI,DI")])
16162 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16163 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16164 [(match_operand 4 "flags_reg_operand" "")
16166 (match_operand:DF 2 "nonimmediate_operand" "")
16167 (match_operand:DF 3 "nonimmediate_operand" "")))]
16168 "!TARGET_64BIT && reload_completed"
16169 [(set (match_dup 2)
16170 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16174 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16178 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16179 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16182 (define_insn "*movsfcc_1_387"
16183 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16184 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16185 [(reg FLAGS_REG) (const_int 0)])
16186 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16187 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16188 "TARGET_80387 && TARGET_CMOVE
16189 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16191 fcmov%F1\t{%2, %0|%0, %2}
16192 fcmov%f1\t{%3, %0|%0, %3}
16193 cmov%O2%C1\t{%2, %0|%0, %2}
16194 cmov%O2%c1\t{%3, %0|%0, %3}"
16195 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16196 (set_attr "mode" "SF,SF,SI,SI")])
16198 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16199 ;; the scalar versions to have only XMM registers as operands.
16201 ;; XOP conditional move
16202 (define_insn "*xop_pcmov_<mode>"
16203 [(set (match_operand:MODEF 0 "register_operand" "=x")
16204 (if_then_else:MODEF
16205 (match_operand:MODEF 1 "register_operand" "x")
16206 (match_operand:MODEF 2 "register_operand" "x")
16207 (match_operand:MODEF 3 "register_operand" "x")))]
16209 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16210 [(set_attr "type" "sse4arg")])
16212 ;; These versions of the min/max patterns are intentionally ignorant of
16213 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16214 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16215 ;; are undefined in this condition, we're certain this is correct.
16217 (define_insn "<code><mode>3"
16218 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16220 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16221 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16222 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16224 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16225 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16226 [(set_attr "isa" "noavx,avx")
16227 (set_attr "prefix" "orig,vex")
16228 (set_attr "type" "sseadd")
16229 (set_attr "mode" "<MODE>")])
16231 ;; These versions of the min/max patterns implement exactly the operations
16232 ;; min = (op1 < op2 ? op1 : op2)
16233 ;; max = (!(op1 < op2) ? op1 : op2)
16234 ;; Their operands are not commutative, and thus they may be used in the
16235 ;; presence of -0.0 and NaN.
16237 (define_insn "*ieee_smin<mode>3"
16238 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16240 [(match_operand:MODEF 1 "register_operand" "0,x")
16241 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16243 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16245 min<ssemodesuffix>\t{%2, %0|%0, %2}
16246 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16247 [(set_attr "isa" "noavx,avx")
16248 (set_attr "prefix" "orig,vex")
16249 (set_attr "type" "sseadd")
16250 (set_attr "mode" "<MODE>")])
16252 (define_insn "*ieee_smax<mode>3"
16253 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16255 [(match_operand:MODEF 1 "register_operand" "0,x")
16256 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16258 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16260 max<ssemodesuffix>\t{%2, %0|%0, %2}
16261 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16262 [(set_attr "isa" "noavx,avx")
16263 (set_attr "prefix" "orig,vex")
16264 (set_attr "type" "sseadd")
16265 (set_attr "mode" "<MODE>")])
16267 ;; Make two stack loads independent:
16269 ;; fld %st(0) -> fld bb
16270 ;; fmul bb fmul %st(1), %st
16272 ;; Actually we only match the last two instructions for simplicity.
16274 [(set (match_operand 0 "fp_register_operand" "")
16275 (match_operand 1 "fp_register_operand" ""))
16277 (match_operator 2 "binary_fp_operator"
16279 (match_operand 3 "memory_operand" "")]))]
16280 "REGNO (operands[0]) != REGNO (operands[1])"
16281 [(set (match_dup 0) (match_dup 3))
16282 (set (match_dup 0) (match_dup 4))]
16284 ;; The % modifier is not operational anymore in peephole2's, so we have to
16285 ;; swap the operands manually in the case of addition and multiplication.
16286 "if (COMMUTATIVE_ARITH_P (operands[2]))
16287 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16288 GET_MODE (operands[2]),
16289 operands[0], operands[1]);
16291 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16292 GET_MODE (operands[2]),
16293 operands[1], operands[0]);")
16295 ;; Conditional addition patterns
16296 (define_expand "add<mode>cc"
16297 [(match_operand:SWI 0 "register_operand" "")
16298 (match_operand 1 "ordered_comparison_operator" "")
16299 (match_operand:SWI 2 "register_operand" "")
16300 (match_operand:SWI 3 "const_int_operand" "")]
16302 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16304 ;; Misc patterns (?)
16306 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16307 ;; Otherwise there will be nothing to keep
16309 ;; [(set (reg ebp) (reg esp))]
16310 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16311 ;; (clobber (eflags)]
16312 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16314 ;; in proper program order.
16316 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16317 [(set (match_operand:P 0 "register_operand" "=r,r")
16318 (plus:P (match_operand:P 1 "register_operand" "0,r")
16319 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16320 (clobber (reg:CC FLAGS_REG))
16321 (clobber (mem:BLK (scratch)))]
16324 switch (get_attr_type (insn))
16327 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16330 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16331 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16332 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16334 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16337 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16338 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16341 [(set (attr "type")
16342 (cond [(and (eq_attr "alternative" "0")
16343 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16344 (const_string "alu")
16345 (match_operand:<MODE> 2 "const0_operand" "")
16346 (const_string "imov")
16348 (const_string "lea")))
16349 (set (attr "length_immediate")
16350 (cond [(eq_attr "type" "imov")
16352 (and (eq_attr "type" "alu")
16353 (match_operand 2 "const128_operand" ""))
16356 (const_string "*")))
16357 (set_attr "mode" "<MODE>")])
16359 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16360 [(set (match_operand:P 0 "register_operand" "=r")
16361 (minus:P (match_operand:P 1 "register_operand" "0")
16362 (match_operand:P 2 "register_operand" "r")))
16363 (clobber (reg:CC FLAGS_REG))
16364 (clobber (mem:BLK (scratch)))]
16366 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16367 [(set_attr "type" "alu")
16368 (set_attr "mode" "<MODE>")])
16370 (define_insn "allocate_stack_worker_probe_<mode>"
16371 [(set (match_operand:P 0 "register_operand" "=a")
16372 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16373 UNSPECV_STACK_PROBE))
16374 (clobber (reg:CC FLAGS_REG))]
16375 "ix86_target_stack_probe ()"
16376 "call\t___chkstk_ms"
16377 [(set_attr "type" "multi")
16378 (set_attr "length" "5")])
16380 (define_expand "allocate_stack"
16381 [(match_operand 0 "register_operand" "")
16382 (match_operand 1 "general_operand" "")]
16383 "ix86_target_stack_probe ()"
16387 #ifndef CHECK_STACK_LIMIT
16388 #define CHECK_STACK_LIMIT 0
16391 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16392 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16394 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16395 stack_pointer_rtx, 0, OPTAB_DIRECT);
16396 if (x != stack_pointer_rtx)
16397 emit_move_insn (stack_pointer_rtx, x);
16401 x = copy_to_mode_reg (Pmode, operands[1]);
16403 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16405 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16406 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16407 stack_pointer_rtx, 0, OPTAB_DIRECT);
16408 if (x != stack_pointer_rtx)
16409 emit_move_insn (stack_pointer_rtx, x);
16412 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16416 ;; Use IOR for stack probes, this is shorter.
16417 (define_expand "probe_stack"
16418 [(match_operand 0 "memory_operand" "")]
16421 rtx (*gen_ior3) (rtx, rtx, rtx);
16423 gen_ior3 = (GET_MODE (operands[0]) == DImode
16424 ? gen_iordi3 : gen_iorsi3);
16426 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16430 (define_insn "adjust_stack_and_probe<mode>"
16431 [(set (match_operand:P 0 "register_operand" "=r")
16432 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16433 UNSPECV_PROBE_STACK_RANGE))
16434 (set (reg:P SP_REG)
16435 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16436 (clobber (reg:CC FLAGS_REG))
16437 (clobber (mem:BLK (scratch)))]
16439 "* return output_adjust_stack_and_probe (operands[0]);"
16440 [(set_attr "type" "multi")])
16442 (define_insn "probe_stack_range<mode>"
16443 [(set (match_operand:P 0 "register_operand" "=r")
16444 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16445 (match_operand:P 2 "const_int_operand" "n")]
16446 UNSPECV_PROBE_STACK_RANGE))
16447 (clobber (reg:CC FLAGS_REG))]
16449 "* return output_probe_stack_range (operands[0], operands[2]);"
16450 [(set_attr "type" "multi")])
16452 (define_expand "builtin_setjmp_receiver"
16453 [(label_ref (match_operand 0 "" ""))]
16454 "!TARGET_64BIT && flag_pic"
16460 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16461 rtx label_rtx = gen_label_rtx ();
16462 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16463 xops[0] = xops[1] = picreg;
16464 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16465 ix86_expand_binary_operator (MINUS, SImode, xops);
16469 emit_insn (gen_set_got (pic_offset_table_rtx));
16473 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16476 [(set (match_operand 0 "register_operand" "")
16477 (match_operator 3 "promotable_binary_operator"
16478 [(match_operand 1 "register_operand" "")
16479 (match_operand 2 "aligned_operand" "")]))
16480 (clobber (reg:CC FLAGS_REG))]
16481 "! TARGET_PARTIAL_REG_STALL && reload_completed
16482 && ((GET_MODE (operands[0]) == HImode
16483 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16484 /* ??? next two lines just !satisfies_constraint_K (...) */
16485 || !CONST_INT_P (operands[2])
16486 || satisfies_constraint_K (operands[2])))
16487 || (GET_MODE (operands[0]) == QImode
16488 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16489 [(parallel [(set (match_dup 0)
16490 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16491 (clobber (reg:CC FLAGS_REG))])]
16492 "operands[0] = gen_lowpart (SImode, operands[0]);
16493 operands[1] = gen_lowpart (SImode, operands[1]);
16494 if (GET_CODE (operands[3]) != ASHIFT)
16495 operands[2] = gen_lowpart (SImode, operands[2]);
16496 PUT_MODE (operands[3], SImode);")
16498 ; Promote the QImode tests, as i386 has encoding of the AND
16499 ; instruction with 32-bit sign-extended immediate and thus the
16500 ; instruction size is unchanged, except in the %eax case for
16501 ; which it is increased by one byte, hence the ! optimize_size.
16503 [(set (match_operand 0 "flags_reg_operand" "")
16504 (match_operator 2 "compare_operator"
16505 [(and (match_operand 3 "aligned_operand" "")
16506 (match_operand 4 "const_int_operand" ""))
16508 (set (match_operand 1 "register_operand" "")
16509 (and (match_dup 3) (match_dup 4)))]
16510 "! TARGET_PARTIAL_REG_STALL && reload_completed
16511 && optimize_insn_for_speed_p ()
16512 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16513 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16514 /* Ensure that the operand will remain sign-extended immediate. */
16515 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16516 [(parallel [(set (match_dup 0)
16517 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16520 (and:SI (match_dup 3) (match_dup 4)))])]
16523 = gen_int_mode (INTVAL (operands[4])
16524 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16525 operands[1] = gen_lowpart (SImode, operands[1]);
16526 operands[3] = gen_lowpart (SImode, operands[3]);
16529 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16530 ; the TEST instruction with 32-bit sign-extended immediate and thus
16531 ; the instruction size would at least double, which is not what we
16532 ; want even with ! optimize_size.
16534 [(set (match_operand 0 "flags_reg_operand" "")
16535 (match_operator 1 "compare_operator"
16536 [(and (match_operand:HI 2 "aligned_operand" "")
16537 (match_operand:HI 3 "const_int_operand" ""))
16539 "! TARGET_PARTIAL_REG_STALL && reload_completed
16540 && ! TARGET_FAST_PREFIX
16541 && optimize_insn_for_speed_p ()
16542 /* Ensure that the operand will remain sign-extended immediate. */
16543 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16544 [(set (match_dup 0)
16545 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16549 = gen_int_mode (INTVAL (operands[3])
16550 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16551 operands[2] = gen_lowpart (SImode, operands[2]);
16555 [(set (match_operand 0 "register_operand" "")
16556 (neg (match_operand 1 "register_operand" "")))
16557 (clobber (reg:CC FLAGS_REG))]
16558 "! TARGET_PARTIAL_REG_STALL && reload_completed
16559 && (GET_MODE (operands[0]) == HImode
16560 || (GET_MODE (operands[0]) == QImode
16561 && (TARGET_PROMOTE_QImode
16562 || optimize_insn_for_size_p ())))"
16563 [(parallel [(set (match_dup 0)
16564 (neg:SI (match_dup 1)))
16565 (clobber (reg:CC FLAGS_REG))])]
16566 "operands[0] = gen_lowpart (SImode, operands[0]);
16567 operands[1] = gen_lowpart (SImode, operands[1]);")
16570 [(set (match_operand 0 "register_operand" "")
16571 (not (match_operand 1 "register_operand" "")))]
16572 "! TARGET_PARTIAL_REG_STALL && reload_completed
16573 && (GET_MODE (operands[0]) == HImode
16574 || (GET_MODE (operands[0]) == QImode
16575 && (TARGET_PROMOTE_QImode
16576 || optimize_insn_for_size_p ())))"
16577 [(set (match_dup 0)
16578 (not:SI (match_dup 1)))]
16579 "operands[0] = gen_lowpart (SImode, operands[0]);
16580 operands[1] = gen_lowpart (SImode, operands[1]);")
16583 [(set (match_operand 0 "register_operand" "")
16584 (if_then_else (match_operator 1 "ordered_comparison_operator"
16585 [(reg FLAGS_REG) (const_int 0)])
16586 (match_operand 2 "register_operand" "")
16587 (match_operand 3 "register_operand" "")))]
16588 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16589 && (GET_MODE (operands[0]) == HImode
16590 || (GET_MODE (operands[0]) == QImode
16591 && (TARGET_PROMOTE_QImode
16592 || optimize_insn_for_size_p ())))"
16593 [(set (match_dup 0)
16594 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16595 "operands[0] = gen_lowpart (SImode, operands[0]);
16596 operands[2] = gen_lowpart (SImode, operands[2]);
16597 operands[3] = gen_lowpart (SImode, operands[3]);")
16599 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16600 ;; transform a complex memory operation into two memory to register operations.
16602 ;; Don't push memory operands
16604 [(set (match_operand:SWI 0 "push_operand" "")
16605 (match_operand:SWI 1 "memory_operand" ""))
16606 (match_scratch:SWI 2 "<r>")]
16607 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16608 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16609 [(set (match_dup 2) (match_dup 1))
16610 (set (match_dup 0) (match_dup 2))])
16612 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16615 [(set (match_operand:SF 0 "push_operand" "")
16616 (match_operand:SF 1 "memory_operand" ""))
16617 (match_scratch:SF 2 "r")]
16618 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16619 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16620 [(set (match_dup 2) (match_dup 1))
16621 (set (match_dup 0) (match_dup 2))])
16623 ;; Don't move an immediate directly to memory when the instruction
16626 [(match_scratch:SWI124 1 "<r>")
16627 (set (match_operand:SWI124 0 "memory_operand" "")
16629 "optimize_insn_for_speed_p ()
16630 && !TARGET_USE_MOV0
16631 && TARGET_SPLIT_LONG_MOVES
16632 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16633 && peep2_regno_dead_p (0, FLAGS_REG)"
16634 [(parallel [(set (match_dup 2) (const_int 0))
16635 (clobber (reg:CC FLAGS_REG))])
16636 (set (match_dup 0) (match_dup 1))]
16637 "operands[2] = gen_lowpart (SImode, operands[1]);")
16640 [(match_scratch:SWI124 2 "<r>")
16641 (set (match_operand:SWI124 0 "memory_operand" "")
16642 (match_operand:SWI124 1 "immediate_operand" ""))]
16643 "optimize_insn_for_speed_p ()
16644 && TARGET_SPLIT_LONG_MOVES
16645 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16646 [(set (match_dup 2) (match_dup 1))
16647 (set (match_dup 0) (match_dup 2))])
16649 ;; Don't compare memory with zero, load and use a test instead.
16651 [(set (match_operand 0 "flags_reg_operand" "")
16652 (match_operator 1 "compare_operator"
16653 [(match_operand:SI 2 "memory_operand" "")
16655 (match_scratch:SI 3 "r")]
16656 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16657 [(set (match_dup 3) (match_dup 2))
16658 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16660 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16661 ;; Don't split NOTs with a displacement operand, because resulting XOR
16662 ;; will not be pairable anyway.
16664 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16665 ;; represented using a modRM byte. The XOR replacement is long decoded,
16666 ;; so this split helps here as well.
16668 ;; Note: Can't do this as a regular split because we can't get proper
16669 ;; lifetime information then.
16672 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16673 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16674 "optimize_insn_for_speed_p ()
16675 && ((TARGET_NOT_UNPAIRABLE
16676 && (!MEM_P (operands[0])
16677 || !memory_displacement_operand (operands[0], <MODE>mode)))
16678 || (TARGET_NOT_VECTORMODE
16679 && long_memory_operand (operands[0], <MODE>mode)))
16680 && peep2_regno_dead_p (0, FLAGS_REG)"
16681 [(parallel [(set (match_dup 0)
16682 (xor:SWI124 (match_dup 1) (const_int -1)))
16683 (clobber (reg:CC FLAGS_REG))])])
16685 ;; Non pairable "test imm, reg" instructions can be translated to
16686 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16687 ;; byte opcode instead of two, have a short form for byte operands),
16688 ;; so do it for other CPUs as well. Given that the value was dead,
16689 ;; this should not create any new dependencies. Pass on the sub-word
16690 ;; versions if we're concerned about partial register stalls.
16693 [(set (match_operand 0 "flags_reg_operand" "")
16694 (match_operator 1 "compare_operator"
16695 [(and:SI (match_operand:SI 2 "register_operand" "")
16696 (match_operand:SI 3 "immediate_operand" ""))
16698 "ix86_match_ccmode (insn, CCNOmode)
16699 && (true_regnum (operands[2]) != AX_REG
16700 || satisfies_constraint_K (operands[3]))
16701 && peep2_reg_dead_p (1, operands[2])"
16703 [(set (match_dup 0)
16704 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16707 (and:SI (match_dup 2) (match_dup 3)))])])
16709 ;; We don't need to handle HImode case, because it will be promoted to SImode
16710 ;; on ! TARGET_PARTIAL_REG_STALL
16713 [(set (match_operand 0 "flags_reg_operand" "")
16714 (match_operator 1 "compare_operator"
16715 [(and:QI (match_operand:QI 2 "register_operand" "")
16716 (match_operand:QI 3 "immediate_operand" ""))
16718 "! TARGET_PARTIAL_REG_STALL
16719 && ix86_match_ccmode (insn, CCNOmode)
16720 && true_regnum (operands[2]) != AX_REG
16721 && peep2_reg_dead_p (1, operands[2])"
16723 [(set (match_dup 0)
16724 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16727 (and:QI (match_dup 2) (match_dup 3)))])])
16730 [(set (match_operand 0 "flags_reg_operand" "")
16731 (match_operator 1 "compare_operator"
16734 (match_operand 2 "ext_register_operand" "")
16737 (match_operand 3 "const_int_operand" ""))
16739 "! TARGET_PARTIAL_REG_STALL
16740 && ix86_match_ccmode (insn, CCNOmode)
16741 && true_regnum (operands[2]) != AX_REG
16742 && peep2_reg_dead_p (1, operands[2])"
16743 [(parallel [(set (match_dup 0)
16752 (set (zero_extract:SI (match_dup 2)
16760 (match_dup 3)))])])
16762 ;; Don't do logical operations with memory inputs.
16764 [(match_scratch:SI 2 "r")
16765 (parallel [(set (match_operand:SI 0 "register_operand" "")
16766 (match_operator:SI 3 "arith_or_logical_operator"
16768 (match_operand:SI 1 "memory_operand" "")]))
16769 (clobber (reg:CC FLAGS_REG))])]
16770 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16771 [(set (match_dup 2) (match_dup 1))
16772 (parallel [(set (match_dup 0)
16773 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16774 (clobber (reg:CC FLAGS_REG))])])
16777 [(match_scratch:SI 2 "r")
16778 (parallel [(set (match_operand:SI 0 "register_operand" "")
16779 (match_operator:SI 3 "arith_or_logical_operator"
16780 [(match_operand:SI 1 "memory_operand" "")
16782 (clobber (reg:CC FLAGS_REG))])]
16783 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16784 [(set (match_dup 2) (match_dup 1))
16785 (parallel [(set (match_dup 0)
16786 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16787 (clobber (reg:CC FLAGS_REG))])])
16789 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16790 ;; refers to the destination of the load!
16793 [(set (match_operand:SI 0 "register_operand" "")
16794 (match_operand:SI 1 "register_operand" ""))
16795 (parallel [(set (match_dup 0)
16796 (match_operator:SI 3 "commutative_operator"
16798 (match_operand:SI 2 "memory_operand" "")]))
16799 (clobber (reg:CC FLAGS_REG))])]
16800 "REGNO (operands[0]) != REGNO (operands[1])
16801 && GENERAL_REGNO_P (REGNO (operands[0]))
16802 && GENERAL_REGNO_P (REGNO (operands[1]))"
16803 [(set (match_dup 0) (match_dup 4))
16804 (parallel [(set (match_dup 0)
16805 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16806 (clobber (reg:CC FLAGS_REG))])]
16807 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16810 [(set (match_operand 0 "register_operand" "")
16811 (match_operand 1 "register_operand" ""))
16813 (match_operator 3 "commutative_operator"
16815 (match_operand 2 "memory_operand" "")]))]
16816 "REGNO (operands[0]) != REGNO (operands[1])
16817 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16818 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16819 [(set (match_dup 0) (match_dup 2))
16821 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16823 ; Don't do logical operations with memory outputs
16825 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16826 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16827 ; the same decoder scheduling characteristics as the original.
16830 [(match_scratch:SI 2 "r")
16831 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16832 (match_operator:SI 3 "arith_or_logical_operator"
16834 (match_operand:SI 1 "nonmemory_operand" "")]))
16835 (clobber (reg:CC FLAGS_REG))])]
16836 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16837 /* Do not split stack checking probes. */
16838 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16839 [(set (match_dup 2) (match_dup 0))
16840 (parallel [(set (match_dup 2)
16841 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16842 (clobber (reg:CC FLAGS_REG))])
16843 (set (match_dup 0) (match_dup 2))])
16846 [(match_scratch:SI 2 "r")
16847 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16848 (match_operator:SI 3 "arith_or_logical_operator"
16849 [(match_operand:SI 1 "nonmemory_operand" "")
16851 (clobber (reg:CC FLAGS_REG))])]
16852 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16853 /* Do not split stack checking probes. */
16854 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16855 [(set (match_dup 2) (match_dup 0))
16856 (parallel [(set (match_dup 2)
16857 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16858 (clobber (reg:CC FLAGS_REG))])
16859 (set (match_dup 0) (match_dup 2))])
16861 ;; Attempt to use arith or logical operations with memory outputs with
16862 ;; setting of flags.
16864 [(set (match_operand:SWI 0 "register_operand" "")
16865 (match_operand:SWI 1 "memory_operand" ""))
16866 (parallel [(set (match_dup 0)
16867 (match_operator:SWI 3 "plusminuslogic_operator"
16869 (match_operand:SWI 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 && peep2_reg_dead_p (4, operands[0])
16875 && !reg_overlap_mentioned_p (operands[0], operands[1])
16876 && ix86_match_ccmode (peep2_next_insn (3),
16877 (GET_CODE (operands[3]) == PLUS
16878 || GET_CODE (operands[3]) == MINUS)
16879 ? CCGOCmode : CCNOmode)"
16880 [(parallel [(set (match_dup 4) (match_dup 5))
16881 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16882 (match_dup 2)]))])]
16883 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16884 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16885 copy_rtx (operands[1]),
16886 copy_rtx (operands[2]));
16887 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16888 operands[5], const0_rtx);")
16891 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16892 (match_operator:SWI 2 "plusminuslogic_operator"
16894 (match_operand:SWI 1 "memory_operand" "")]))
16895 (clobber (reg:CC FLAGS_REG))])
16896 (set (match_dup 1) (match_dup 0))
16897 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16898 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16899 && GET_CODE (operands[2]) != MINUS
16900 && peep2_reg_dead_p (3, operands[0])
16901 && !reg_overlap_mentioned_p (operands[0], operands[1])
16902 && ix86_match_ccmode (peep2_next_insn (2),
16903 GET_CODE (operands[2]) == PLUS
16904 ? CCGOCmode : CCNOmode)"
16905 [(parallel [(set (match_dup 3) (match_dup 4))
16906 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16907 (match_dup 0)]))])]
16908 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16909 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16910 copy_rtx (operands[1]),
16911 copy_rtx (operands[0]));
16912 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16913 operands[4], const0_rtx);")
16916 [(set (match_operand:SWI12 0 "register_operand" "")
16917 (match_operand:SWI12 1 "memory_operand" ""))
16918 (parallel [(set (match_operand:SI 4 "register_operand" "")
16919 (match_operator:SI 3 "plusminuslogic_operator"
16921 (match_operand:SI 2 "nonmemory_operand" "")]))
16922 (clobber (reg:CC FLAGS_REG))])
16923 (set (match_dup 1) (match_dup 0))
16924 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16925 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16926 && REG_P (operands[0]) && REG_P (operands[4])
16927 && REGNO (operands[0]) == REGNO (operands[4])
16928 && peep2_reg_dead_p (4, operands[0])
16929 && !reg_overlap_mentioned_p (operands[0], operands[1])
16930 && ix86_match_ccmode (peep2_next_insn (3),
16931 (GET_CODE (operands[3]) == PLUS
16932 || GET_CODE (operands[3]) == MINUS)
16933 ? CCGOCmode : CCNOmode)"
16934 [(parallel [(set (match_dup 4) (match_dup 5))
16935 (set (match_dup 1) (match_dup 6))])]
16936 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16937 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16938 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16939 copy_rtx (operands[1]), operands[2]);
16940 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16941 operands[5], const0_rtx);
16942 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16943 copy_rtx (operands[1]),
16944 copy_rtx (operands[2]));")
16946 ;; Attempt to always use XOR for zeroing registers.
16948 [(set (match_operand 0 "register_operand" "")
16949 (match_operand 1 "const0_operand" ""))]
16950 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16951 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16952 && GENERAL_REG_P (operands[0])
16953 && peep2_regno_dead_p (0, FLAGS_REG)"
16954 [(parallel [(set (match_dup 0) (const_int 0))
16955 (clobber (reg:CC FLAGS_REG))])]
16956 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16959 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16961 "(GET_MODE (operands[0]) == QImode
16962 || GET_MODE (operands[0]) == HImode)
16963 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16964 && peep2_regno_dead_p (0, FLAGS_REG)"
16965 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16966 (clobber (reg:CC FLAGS_REG))])])
16968 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16970 [(set (match_operand:SWI248 0 "register_operand" "")
16972 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16973 && peep2_regno_dead_p (0, FLAGS_REG)"
16974 [(parallel [(set (match_dup 0) (const_int -1))
16975 (clobber (reg:CC FLAGS_REG))])]
16977 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16978 operands[0] = gen_lowpart (SImode, operands[0]);
16981 ;; Attempt to convert simple lea to add/shift.
16982 ;; These can be created by move expanders.
16985 [(set (match_operand:SWI48 0 "register_operand" "")
16986 (plus:SWI48 (match_dup 0)
16987 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16988 "peep2_regno_dead_p (0, FLAGS_REG)"
16989 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16990 (clobber (reg:CC FLAGS_REG))])])
16993 [(set (match_operand:SI 0 "register_operand" "")
16994 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16995 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16997 && peep2_regno_dead_p (0, FLAGS_REG)
16998 && REGNO (operands[0]) == REGNO (operands[1])"
16999 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17000 (clobber (reg:CC FLAGS_REG))])]
17001 "operands[2] = gen_lowpart (SImode, operands[2]);")
17004 [(set (match_operand:SWI48 0 "register_operand" "")
17005 (mult:SWI48 (match_dup 0)
17006 (match_operand:SWI48 1 "const_int_operand" "")))]
17007 "exact_log2 (INTVAL (operands[1])) >= 0
17008 && peep2_regno_dead_p (0, FLAGS_REG)"
17009 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17010 (clobber (reg:CC FLAGS_REG))])]
17011 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17014 [(set (match_operand:SI 0 "register_operand" "")
17015 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17016 (match_operand:DI 2 "const_int_operand" "")) 0))]
17018 && exact_log2 (INTVAL (operands[2])) >= 0
17019 && REGNO (operands[0]) == REGNO (operands[1])
17020 && peep2_regno_dead_p (0, FLAGS_REG)"
17021 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17022 (clobber (reg:CC FLAGS_REG))])]
17023 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17025 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17026 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17027 ;; On many CPUs it is also faster, since special hardware to avoid esp
17028 ;; dependencies is present.
17030 ;; While some of these conversions may be done using splitters, we use
17031 ;; peepholes in order to allow combine_stack_adjustments pass to see
17032 ;; nonobfuscated RTL.
17034 ;; Convert prologue esp subtractions to push.
17035 ;; We need register to push. In order to keep verify_flow_info happy we have
17037 ;; - use scratch and clobber it in order to avoid dependencies
17038 ;; - use already live register
17039 ;; We can't use the second way right now, since there is no reliable way how to
17040 ;; verify that given register is live. First choice will also most likely in
17041 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17042 ;; call clobbered registers are dead. We may want to use base pointer as an
17043 ;; alternative when no register is available later.
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_PUSH || optimize_insn_for_size_p ())
17053 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17054 [(clobber (match_dup 1))
17055 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17056 (clobber (mem:BLK (scratch)))])])
17059 [(match_scratch:P 1 "r")
17060 (parallel [(set (reg:P SP_REG)
17061 (plus:P (reg:P SP_REG)
17062 (match_operand:P 0 "const_int_operand" "")))
17063 (clobber (reg:CC FLAGS_REG))
17064 (clobber (mem:BLK (scratch)))])]
17065 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17066 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17067 [(clobber (match_dup 1))
17068 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17069 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17070 (clobber (mem:BLK (scratch)))])])
17072 ;; Convert esp subtractions to push.
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 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17080 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17081 [(clobber (match_dup 1))
17082 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17085 [(match_scratch:P 1 "r")
17086 (parallel [(set (reg:P SP_REG)
17087 (plus:P (reg:P SP_REG)
17088 (match_operand:P 0 "const_int_operand" "")))
17089 (clobber (reg:CC FLAGS_REG))])]
17090 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17091 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17092 [(clobber (match_dup 1))
17093 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17094 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17096 ;; Convert epilogue deallocator to pop.
17098 [(match_scratch:P 1 "r")
17099 (parallel [(set (reg:P SP_REG)
17100 (plus:P (reg:P SP_REG)
17101 (match_operand:P 0 "const_int_operand" "")))
17102 (clobber (reg:CC FLAGS_REG))
17103 (clobber (mem:BLK (scratch)))])]
17104 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17105 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17106 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17107 (clobber (mem:BLK (scratch)))])])
17109 ;; Two pops case is tricky, since pop causes dependency
17110 ;; on destination register. We use two registers if available.
17112 [(match_scratch:P 1 "r")
17113 (match_scratch:P 2 "r")
17114 (parallel [(set (reg:P SP_REG)
17115 (plus:P (reg:P SP_REG)
17116 (match_operand:P 0 "const_int_operand" "")))
17117 (clobber (reg:CC FLAGS_REG))
17118 (clobber (mem:BLK (scratch)))])]
17119 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17120 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17121 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17122 (clobber (mem:BLK (scratch)))])
17123 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17126 [(match_scratch:P 1 "r")
17127 (parallel [(set (reg:P SP_REG)
17128 (plus:P (reg:P SP_REG)
17129 (match_operand:P 0 "const_int_operand" "")))
17130 (clobber (reg:CC FLAGS_REG))
17131 (clobber (mem:BLK (scratch)))])]
17132 "optimize_insn_for_size_p ()
17133 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17134 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17135 (clobber (mem:BLK (scratch)))])
17136 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17138 ;; Convert esp additions to pop.
17140 [(match_scratch:P 1 "r")
17141 (parallel [(set (reg:P SP_REG)
17142 (plus:P (reg:P SP_REG)
17143 (match_operand:P 0 "const_int_operand" "")))
17144 (clobber (reg:CC FLAGS_REG))])]
17145 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17146 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17148 ;; Two pops case is tricky, since pop causes dependency
17149 ;; on destination register. We use two registers if available.
17151 [(match_scratch:P 1 "r")
17152 (match_scratch:P 2 "r")
17153 (parallel [(set (reg:P SP_REG)
17154 (plus:P (reg:P SP_REG)
17155 (match_operand:P 0 "const_int_operand" "")))
17156 (clobber (reg:CC FLAGS_REG))])]
17157 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17158 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17159 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17162 [(match_scratch:P 1 "r")
17163 (parallel [(set (reg:P SP_REG)
17164 (plus:P (reg:P SP_REG)
17165 (match_operand:P 0 "const_int_operand" "")))
17166 (clobber (reg:CC FLAGS_REG))])]
17167 "optimize_insn_for_size_p ()
17168 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17169 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17170 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17172 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17173 ;; required and register dies. Similarly for 128 to -128.
17175 [(set (match_operand 0 "flags_reg_operand" "")
17176 (match_operator 1 "compare_operator"
17177 [(match_operand 2 "register_operand" "")
17178 (match_operand 3 "const_int_operand" "")]))]
17179 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17180 && incdec_operand (operands[3], GET_MODE (operands[3])))
17181 || (!TARGET_FUSE_CMP_AND_BRANCH
17182 && INTVAL (operands[3]) == 128))
17183 && ix86_match_ccmode (insn, CCGCmode)
17184 && peep2_reg_dead_p (1, operands[2])"
17185 [(parallel [(set (match_dup 0)
17186 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17187 (clobber (match_dup 2))])])
17189 ;; Convert imul by three, five and nine into lea
17192 [(set (match_operand:SWI48 0 "register_operand" "")
17193 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17194 (match_operand:SWI48 2 "const_int_operand" "")))
17195 (clobber (reg:CC FLAGS_REG))])]
17196 "INTVAL (operands[2]) == 3
17197 || INTVAL (operands[2]) == 5
17198 || INTVAL (operands[2]) == 9"
17199 [(set (match_dup 0)
17200 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17202 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17206 [(set (match_operand:SWI48 0 "register_operand" "")
17207 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17208 (match_operand:SWI48 2 "const_int_operand" "")))
17209 (clobber (reg:CC FLAGS_REG))])]
17210 "optimize_insn_for_speed_p ()
17211 && (INTVAL (operands[2]) == 3
17212 || INTVAL (operands[2]) == 5
17213 || INTVAL (operands[2]) == 9)"
17214 [(set (match_dup 0) (match_dup 1))
17216 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17218 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17220 ;; imul $32bit_imm, mem, reg is vector decoded, while
17221 ;; imul $32bit_imm, reg, reg is direct decoded.
17223 [(match_scratch:SWI48 3 "r")
17224 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17225 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17226 (match_operand:SWI48 2 "immediate_operand" "")))
17227 (clobber (reg:CC FLAGS_REG))])]
17228 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17229 && !satisfies_constraint_K (operands[2])"
17230 [(set (match_dup 3) (match_dup 1))
17231 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17232 (clobber (reg:CC FLAGS_REG))])])
17235 [(match_scratch:SI 3 "r")
17236 (parallel [(set (match_operand:DI 0 "register_operand" "")
17238 (mult:SI (match_operand:SI 1 "memory_operand" "")
17239 (match_operand:SI 2 "immediate_operand" ""))))
17240 (clobber (reg:CC FLAGS_REG))])]
17242 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17243 && !satisfies_constraint_K (operands[2])"
17244 [(set (match_dup 3) (match_dup 1))
17245 (parallel [(set (match_dup 0)
17246 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17247 (clobber (reg:CC FLAGS_REG))])])
17249 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17250 ;; Convert it into imul reg, reg
17251 ;; It would be better to force assembler to encode instruction using long
17252 ;; immediate, but there is apparently no way to do so.
17254 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17256 (match_operand:SWI248 1 "nonimmediate_operand" "")
17257 (match_operand:SWI248 2 "const_int_operand" "")))
17258 (clobber (reg:CC FLAGS_REG))])
17259 (match_scratch:SWI248 3 "r")]
17260 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17261 && satisfies_constraint_K (operands[2])"
17262 [(set (match_dup 3) (match_dup 2))
17263 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17264 (clobber (reg:CC FLAGS_REG))])]
17266 if (!rtx_equal_p (operands[0], operands[1]))
17267 emit_move_insn (operands[0], operands[1]);
17270 ;; After splitting up read-modify operations, array accesses with memory
17271 ;; operands might end up in form:
17273 ;; movl 4(%esp), %edx
17275 ;; instead of pre-splitting:
17277 ;; addl 4(%esp), %eax
17279 ;; movl 4(%esp), %edx
17280 ;; leal (%edx,%eax,4), %eax
17283 [(match_scratch:P 5 "r")
17284 (parallel [(set (match_operand 0 "register_operand" "")
17285 (ashift (match_operand 1 "register_operand" "")
17286 (match_operand 2 "const_int_operand" "")))
17287 (clobber (reg:CC FLAGS_REG))])
17288 (parallel [(set (match_operand 3 "register_operand" "")
17289 (plus (match_dup 0)
17290 (match_operand 4 "x86_64_general_operand" "")))
17291 (clobber (reg:CC FLAGS_REG))])]
17292 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17293 /* Validate MODE for lea. */
17294 && ((!TARGET_PARTIAL_REG_STALL
17295 && (GET_MODE (operands[0]) == QImode
17296 || GET_MODE (operands[0]) == HImode))
17297 || GET_MODE (operands[0]) == SImode
17298 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17299 && (rtx_equal_p (operands[0], operands[3])
17300 || peep2_reg_dead_p (2, operands[0]))
17301 /* We reorder load and the shift. */
17302 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17303 [(set (match_dup 5) (match_dup 4))
17304 (set (match_dup 0) (match_dup 1))]
17306 enum machine_mode op1mode = GET_MODE (operands[1]);
17307 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17308 int scale = 1 << INTVAL (operands[2]);
17309 rtx index = gen_lowpart (Pmode, operands[1]);
17310 rtx base = gen_lowpart (Pmode, operands[5]);
17311 rtx dest = gen_lowpart (mode, operands[3]);
17313 operands[1] = gen_rtx_PLUS (Pmode, base,
17314 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17315 operands[5] = base;
17317 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17318 if (op1mode != Pmode)
17319 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17320 operands[0] = dest;
17323 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17324 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17325 ;; caught for use by garbage collectors and the like. Using an insn that
17326 ;; maps to SIGILL makes it more likely the program will rightfully die.
17327 ;; Keeping with tradition, "6" is in honor of #UD.
17328 (define_insn "trap"
17329 [(trap_if (const_int 1) (const_int 6))]
17331 { return ASM_SHORT "0x0b0f"; }
17332 [(set_attr "length" "2")])
17334 (define_expand "prefetch"
17335 [(prefetch (match_operand 0 "address_operand" "")
17336 (match_operand:SI 1 "const_int_operand" "")
17337 (match_operand:SI 2 "const_int_operand" ""))]
17338 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17340 int rw = INTVAL (operands[1]);
17341 int locality = INTVAL (operands[2]);
17343 gcc_assert (rw == 0 || rw == 1);
17344 gcc_assert (locality >= 0 && locality <= 3);
17345 gcc_assert (GET_MODE (operands[0]) == Pmode
17346 || GET_MODE (operands[0]) == VOIDmode);
17348 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17349 supported by SSE counterpart or the SSE prefetch is not available
17350 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17352 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17353 operands[2] = GEN_INT (3);
17355 operands[1] = const0_rtx;
17358 (define_insn "*prefetch_sse_<mode>"
17359 [(prefetch (match_operand:P 0 "address_operand" "p")
17361 (match_operand:SI 1 "const_int_operand" ""))]
17362 "TARGET_PREFETCH_SSE"
17364 static const char * const patterns[4] = {
17365 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17368 int locality = INTVAL (operands[1]);
17369 gcc_assert (locality >= 0 && locality <= 3);
17371 return patterns[locality];
17373 [(set_attr "type" "sse")
17374 (set_attr "atom_sse_attr" "prefetch")
17375 (set (attr "length_address")
17376 (symbol_ref "memory_address_length (operands[0])"))
17377 (set_attr "memory" "none")])
17379 (define_insn "*prefetch_3dnow_<mode>"
17380 [(prefetch (match_operand:P 0 "address_operand" "p")
17381 (match_operand:SI 1 "const_int_operand" "n")
17385 if (INTVAL (operands[1]) == 0)
17386 return "prefetch\t%a0";
17388 return "prefetchw\t%a0";
17390 [(set_attr "type" "mmx")
17391 (set (attr "length_address")
17392 (symbol_ref "memory_address_length (operands[0])"))
17393 (set_attr "memory" "none")])
17395 (define_expand "stack_protect_set"
17396 [(match_operand 0 "memory_operand" "")
17397 (match_operand 1 "memory_operand" "")]
17400 rtx (*insn)(rtx, rtx);
17402 #ifdef TARGET_THREAD_SSP_OFFSET
17403 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17404 insn = (TARGET_64BIT
17405 ? gen_stack_tls_protect_set_di
17406 : gen_stack_tls_protect_set_si);
17408 insn = (TARGET_64BIT
17409 ? gen_stack_protect_set_di
17410 : gen_stack_protect_set_si);
17413 emit_insn (insn (operands[0], operands[1]));
17417 (define_insn "stack_protect_set_<mode>"
17418 [(set (match_operand:P 0 "memory_operand" "=m")
17419 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17420 (set (match_scratch:P 2 "=&r") (const_int 0))
17421 (clobber (reg:CC FLAGS_REG))]
17423 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17424 [(set_attr "type" "multi")])
17426 (define_insn "stack_tls_protect_set_<mode>"
17427 [(set (match_operand:P 0 "memory_operand" "=m")
17428 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17429 UNSPEC_SP_TLS_SET))
17430 (set (match_scratch:P 2 "=&r") (const_int 0))
17431 (clobber (reg:CC FLAGS_REG))]
17433 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17434 [(set_attr "type" "multi")])
17436 (define_expand "stack_protect_test"
17437 [(match_operand 0 "memory_operand" "")
17438 (match_operand 1 "memory_operand" "")
17439 (match_operand 2 "" "")]
17442 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17444 rtx (*insn)(rtx, rtx, rtx);
17446 #ifdef TARGET_THREAD_SSP_OFFSET
17447 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17448 insn = (TARGET_64BIT
17449 ? gen_stack_tls_protect_test_di
17450 : gen_stack_tls_protect_test_si);
17452 insn = (TARGET_64BIT
17453 ? gen_stack_protect_test_di
17454 : gen_stack_protect_test_si);
17457 emit_insn (insn (flags, operands[0], operands[1]));
17459 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17460 flags, const0_rtx, operands[2]));
17464 (define_insn "stack_protect_test_<mode>"
17465 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17466 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17467 (match_operand:P 2 "memory_operand" "m")]
17469 (clobber (match_scratch:P 3 "=&r"))]
17471 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17472 [(set_attr "type" "multi")])
17474 (define_insn "stack_tls_protect_test_<mode>"
17475 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17476 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17477 (match_operand:P 2 "const_int_operand" "i")]
17478 UNSPEC_SP_TLS_TEST))
17479 (clobber (match_scratch:P 3 "=r"))]
17481 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17482 [(set_attr "type" "multi")])
17484 (define_insn "sse4_2_crc32<mode>"
17485 [(set (match_operand:SI 0 "register_operand" "=r")
17487 [(match_operand:SI 1 "register_operand" "0")
17488 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17490 "TARGET_SSE4_2 || TARGET_CRC32"
17491 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17492 [(set_attr "type" "sselog1")
17493 (set_attr "prefix_rep" "1")
17494 (set_attr "prefix_extra" "1")
17495 (set (attr "prefix_data16")
17496 (if_then_else (match_operand:HI 2 "" "")
17498 (const_string "*")))
17499 (set (attr "prefix_rex")
17500 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17502 (const_string "*")))
17503 (set_attr "mode" "SI")])
17505 (define_insn "sse4_2_crc32di"
17506 [(set (match_operand:DI 0 "register_operand" "=r")
17508 [(match_operand:DI 1 "register_operand" "0")
17509 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17511 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17512 "crc32{q}\t{%2, %0|%0, %2}"
17513 [(set_attr "type" "sselog1")
17514 (set_attr "prefix_rep" "1")
17515 (set_attr "prefix_extra" "1")
17516 (set_attr "mode" "DI")])
17518 (define_expand "rdpmc"
17519 [(match_operand:DI 0 "register_operand" "")
17520 (match_operand:SI 1 "register_operand" "")]
17523 rtx reg = gen_reg_rtx (DImode);
17526 /* Force operand 1 into ECX. */
17527 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17528 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17529 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17534 rtvec vec = rtvec_alloc (2);
17535 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17536 rtx upper = gen_reg_rtx (DImode);
17537 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17538 gen_rtvec (1, const0_rtx),
17540 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17541 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17543 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17544 NULL, 1, OPTAB_DIRECT);
17545 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17549 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17550 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17554 (define_insn "*rdpmc"
17555 [(set (match_operand:DI 0 "register_operand" "=A")
17556 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17560 [(set_attr "type" "other")
17561 (set_attr "length" "2")])
17563 (define_insn "*rdpmc_rex64"
17564 [(set (match_operand:DI 0 "register_operand" "=a")
17565 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17567 (set (match_operand:DI 1 "register_operand" "=d")
17568 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17571 [(set_attr "type" "other")
17572 (set_attr "length" "2")])
17574 (define_expand "rdtsc"
17575 [(set (match_operand:DI 0 "register_operand" "")
17576 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17581 rtvec vec = rtvec_alloc (2);
17582 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17583 rtx upper = gen_reg_rtx (DImode);
17584 rtx lower = gen_reg_rtx (DImode);
17585 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17586 gen_rtvec (1, const0_rtx),
17588 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17589 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17591 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17592 NULL, 1, OPTAB_DIRECT);
17593 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17595 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17600 (define_insn "*rdtsc"
17601 [(set (match_operand:DI 0 "register_operand" "=A")
17602 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17605 [(set_attr "type" "other")
17606 (set_attr "length" "2")])
17608 (define_insn "*rdtsc_rex64"
17609 [(set (match_operand:DI 0 "register_operand" "=a")
17610 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17611 (set (match_operand:DI 1 "register_operand" "=d")
17612 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17615 [(set_attr "type" "other")
17616 (set_attr "length" "2")])
17618 (define_expand "rdtscp"
17619 [(match_operand:DI 0 "register_operand" "")
17620 (match_operand:SI 1 "memory_operand" "")]
17623 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17624 gen_rtvec (1, const0_rtx),
17626 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17627 gen_rtvec (1, const0_rtx),
17629 rtx reg = gen_reg_rtx (DImode);
17630 rtx tmp = gen_reg_rtx (SImode);
17634 rtvec vec = rtvec_alloc (3);
17635 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17636 rtx upper = gen_reg_rtx (DImode);
17637 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17638 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17639 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17641 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17642 NULL, 1, OPTAB_DIRECT);
17643 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17648 rtvec vec = rtvec_alloc (2);
17649 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17650 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17651 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17654 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17655 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17659 (define_insn "*rdtscp"
17660 [(set (match_operand:DI 0 "register_operand" "=A")
17661 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17662 (set (match_operand:SI 1 "register_operand" "=c")
17663 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17666 [(set_attr "type" "other")
17667 (set_attr "length" "3")])
17669 (define_insn "*rdtscp_rex64"
17670 [(set (match_operand:DI 0 "register_operand" "=a")
17671 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17672 (set (match_operand:DI 1 "register_operand" "=d")
17673 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17674 (set (match_operand:SI 2 "register_operand" "=c")
17675 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17678 [(set_attr "type" "other")
17679 (set_attr "length" "3")])
17681 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17683 ;; LWP instructions
17685 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17687 (define_expand "lwp_llwpcb"
17688 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17689 UNSPECV_LLWP_INTRINSIC)]
17692 (define_insn "*lwp_llwpcb<mode>1"
17693 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17694 UNSPECV_LLWP_INTRINSIC)]
17697 [(set_attr "type" "lwp")
17698 (set_attr "mode" "<MODE>")
17699 (set_attr "length" "5")])
17701 (define_expand "lwp_slwpcb"
17702 [(set (match_operand 0 "register_operand" "=r")
17703 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17708 insn = (TARGET_64BIT
17710 : gen_lwp_slwpcbsi);
17712 emit_insn (insn (operands[0]));
17716 (define_insn "lwp_slwpcb<mode>"
17717 [(set (match_operand:P 0 "register_operand" "=r")
17718 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17721 [(set_attr "type" "lwp")
17722 (set_attr "mode" "<MODE>")
17723 (set_attr "length" "5")])
17725 (define_expand "lwp_lwpval<mode>3"
17726 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17727 (match_operand:SI 2 "nonimmediate_operand" "rm")
17728 (match_operand:SI 3 "const_int_operand" "i")]
17729 UNSPECV_LWPVAL_INTRINSIC)]
17731 "/* Avoid unused variable warning. */
17734 (define_insn "*lwp_lwpval<mode>3_1"
17735 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17736 (match_operand:SI 1 "nonimmediate_operand" "rm")
17737 (match_operand:SI 2 "const_int_operand" "i")]
17738 UNSPECV_LWPVAL_INTRINSIC)]
17740 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17741 [(set_attr "type" "lwp")
17742 (set_attr "mode" "<MODE>")
17743 (set (attr "length")
17744 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17746 (define_expand "lwp_lwpins<mode>3"
17747 [(set (reg:CCC FLAGS_REG)
17748 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17749 (match_operand:SI 2 "nonimmediate_operand" "rm")
17750 (match_operand:SI 3 "const_int_operand" "i")]
17751 UNSPECV_LWPINS_INTRINSIC))
17752 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17753 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17756 (define_insn "*lwp_lwpins<mode>3_1"
17757 [(set (reg:CCC FLAGS_REG)
17758 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17759 (match_operand:SI 1 "nonimmediate_operand" "rm")
17760 (match_operand:SI 2 "const_int_operand" "i")]
17761 UNSPECV_LWPINS_INTRINSIC))]
17763 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17764 [(set_attr "type" "lwp")
17765 (set_attr "mode" "<MODE>")
17766 (set (attr "length")
17767 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17769 (define_insn "rdfsbase<mode>"
17770 [(set (match_operand:SWI48 0 "register_operand" "=r")
17771 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17772 "TARGET_64BIT && TARGET_FSGSBASE"
17774 [(set_attr "type" "other")
17775 (set_attr "prefix_extra" "2")])
17777 (define_insn "rdgsbase<mode>"
17778 [(set (match_operand:SWI48 0 "register_operand" "=r")
17779 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17780 "TARGET_64BIT && TARGET_FSGSBASE"
17782 [(set_attr "type" "other")
17783 (set_attr "prefix_extra" "2")])
17785 (define_insn "wrfsbase<mode>"
17786 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17788 "TARGET_64BIT && TARGET_FSGSBASE"
17790 [(set_attr "type" "other")
17791 (set_attr "prefix_extra" "2")])
17793 (define_insn "wrgsbase<mode>"
17794 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17796 "TARGET_64BIT && TARGET_FSGSBASE"
17798 [(set_attr "type" "other")
17799 (set_attr "prefix_extra" "2")])
17801 (define_insn "rdrand<mode>_1"
17802 [(set (match_operand:SWI248 0 "register_operand" "=r")
17803 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17804 (set (reg:CCC FLAGS_REG)
17805 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17808 [(set_attr "type" "other")
17809 (set_attr "prefix_extra" "1")])
17811 (define_expand "pause"
17812 [(set (match_dup 0)
17813 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17816 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17817 MEM_VOLATILE_P (operands[0]) = 1;
17820 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17821 ;; They have the same encoding.
17822 (define_insn "*pause"
17823 [(set (match_operand:BLK 0 "" "")
17824 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17827 [(set_attr "length" "2")
17828 (set_attr "memory" "unknown")])
17832 (include "sync.md")