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 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
110 UNSPEC_CALL_NEEDS_VZEROUPPER
112 ;; For SSE/MMX support:
130 UNSPEC_MS_TO_SYSV_CALL
132 ;; Generic math support
134 UNSPEC_IEEE_MIN ; not commutative
135 UNSPEC_IEEE_MAX ; not commutative
137 ;; x87 Floating point
153 UNSPEC_FRNDINT_MASK_PM
157 ;; x87 Double output FP
189 ;; For SSE4.1 support
199 ;; For SSE4.2 support
206 UNSPEC_XOP_UNSIGNED_CMP
217 UNSPEC_AESKEYGENASSIST
219 ;; For PCLMUL support
235 ;; For RDRAND support
239 (define_c_enum "unspecv" [
242 UNSPECV_PROBE_STACK_RANGE
262 UNSPECV_LLWP_INTRINSIC
263 UNSPECV_SLWP_INTRINSIC
264 UNSPECV_LWPVAL_INTRINSIC
265 UNSPECV_LWPINS_INTRINSIC
270 UNSPECV_SPLIT_STACK_RETURN
273 ;; Constants to represent rounding modes in the ROUND instruction
282 ;; Constants to represent pcomtrue/pcomfalse variants
292 ;; Constants used in the XOP pperm instruction
294 [(PPERM_SRC 0x00) /* copy source */
295 (PPERM_INVERT 0x20) /* invert source */
296 (PPERM_REVERSE 0x40) /* bit reverse source */
297 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
298 (PPERM_ZERO 0x80) /* all 0's */
299 (PPERM_ONES 0xa0) /* all 1's */
300 (PPERM_SIGN 0xc0) /* propagate sign bit */
301 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
302 (PPERM_SRC1 0x00) /* use first source byte */
303 (PPERM_SRC2 0x10) /* use second source byte */
306 ;; Registers by name.
359 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
362 ;; In C guard expressions, put expressions which may be compile-time
363 ;; constants first. This allows for better optimization. For
364 ;; example, write "TARGET_64BIT && reload_completed", not
365 ;; "reload_completed && TARGET_64BIT".
369 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
370 atom,generic64,amdfam10,bdver1,btver1"
371 (const (symbol_ref "ix86_schedule")))
373 ;; A basic instruction type. Refinements due to arguments to be
374 ;; provided in other attributes.
377 alu,alu1,negnot,imov,imovx,lea,
378 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
379 icmp,test,ibr,setcc,icmov,
380 push,pop,call,callv,leave,
382 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
383 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
384 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
385 ssemuladd,sse4arg,lwp,
386 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
387 (const_string "other"))
389 ;; Main data type used by the insn
391 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
392 (const_string "unknown"))
394 ;; The CPU unit operations uses.
395 (define_attr "unit" "integer,i387,sse,mmx,unknown"
396 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
397 (const_string "i387")
398 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
399 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
400 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
402 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
404 (eq_attr "type" "other")
405 (const_string "unknown")]
406 (const_string "integer")))
408 ;; The (bounding maximum) length of an instruction immediate.
409 (define_attr "length_immediate" ""
410 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
413 (eq_attr "unit" "i387,sse,mmx")
415 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
417 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
418 (eq_attr "type" "imov,test")
419 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
420 (eq_attr "type" "call")
421 (if_then_else (match_operand 0 "constant_call_address_operand" "")
424 (eq_attr "type" "callv")
425 (if_then_else (match_operand 1 "constant_call_address_operand" "")
428 ;; We don't know the size before shorten_branches. Expect
429 ;; the instruction to fit for better scheduling.
430 (eq_attr "type" "ibr")
433 (symbol_ref "/* Update immediate_length and other attributes! */
434 gcc_unreachable (),1")))
436 ;; The (bounding maximum) length of an instruction address.
437 (define_attr "length_address" ""
438 (cond [(eq_attr "type" "str,other,multi,fxch")
440 (and (eq_attr "type" "call")
441 (match_operand 0 "constant_call_address_operand" ""))
443 (and (eq_attr "type" "callv")
444 (match_operand 1 "constant_call_address_operand" ""))
447 (symbol_ref "ix86_attr_length_address_default (insn)")))
449 ;; Set when length prefix is used.
450 (define_attr "prefix_data16" ""
451 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
453 (eq_attr "mode" "HI")
455 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
460 ;; Set when string REP prefix is used.
461 (define_attr "prefix_rep" ""
462 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
464 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
469 ;; Set when 0f opcode prefix is used.
470 (define_attr "prefix_0f" ""
472 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
473 (eq_attr "unit" "sse,mmx"))
477 ;; Set when REX opcode prefix is used.
478 (define_attr "prefix_rex" ""
479 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
481 (and (eq_attr "mode" "DI")
482 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
483 (eq_attr "unit" "!mmx")))
485 (and (eq_attr "mode" "QI")
486 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
489 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
492 (and (eq_attr "type" "imovx")
493 (match_operand:QI 1 "ext_QIreg_operand" ""))
498 ;; There are also additional prefixes in 3DNOW, SSSE3.
499 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
500 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
501 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
502 (define_attr "prefix_extra" ""
503 (cond [(eq_attr "type" "ssemuladd,sse4arg")
505 (eq_attr "type" "sseiadd1,ssecvt1")
510 ;; Prefix used: original, VEX or maybe VEX.
511 (define_attr "prefix" "orig,vex,maybe_vex"
512 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
514 (const_string "orig")))
516 ;; VEX W bit is used.
517 (define_attr "prefix_vex_w" "" (const_int 0))
519 ;; The length of VEX prefix
520 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
521 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
522 ;; still prefix_0f 1, with prefix_extra 1.
523 (define_attr "length_vex" ""
524 (if_then_else (and (eq_attr "prefix_0f" "1")
525 (eq_attr "prefix_extra" "0"))
526 (if_then_else (eq_attr "prefix_vex_w" "1")
527 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
528 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
529 (if_then_else (eq_attr "prefix_vex_w" "1")
530 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
531 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
533 ;; Set when modrm byte is used.
534 (define_attr "modrm" ""
535 (cond [(eq_attr "type" "str,leave")
537 (eq_attr "unit" "i387")
539 (and (eq_attr "type" "incdec")
540 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
541 (ior (match_operand:SI 1 "register_operand" "")
542 (match_operand:HI 1 "register_operand" ""))))
544 (and (eq_attr "type" "push")
545 (not (match_operand 1 "memory_operand" "")))
547 (and (eq_attr "type" "pop")
548 (not (match_operand 0 "memory_operand" "")))
550 (and (eq_attr "type" "imov")
551 (and (not (eq_attr "mode" "DI"))
552 (ior (and (match_operand 0 "register_operand" "")
553 (match_operand 1 "immediate_operand" ""))
554 (ior (and (match_operand 0 "ax_reg_operand" "")
555 (match_operand 1 "memory_displacement_only_operand" ""))
556 (and (match_operand 0 "memory_displacement_only_operand" "")
557 (match_operand 1 "ax_reg_operand" ""))))))
559 (and (eq_attr "type" "call")
560 (match_operand 0 "constant_call_address_operand" ""))
562 (and (eq_attr "type" "callv")
563 (match_operand 1 "constant_call_address_operand" ""))
565 (and (eq_attr "type" "alu,alu1,icmp,test")
566 (match_operand 0 "ax_reg_operand" ""))
567 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
571 ;; The (bounding maximum) length of an instruction in bytes.
572 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
573 ;; Later we may want to split them and compute proper length as for
575 (define_attr "length" ""
576 (cond [(eq_attr "type" "other,multi,fistp,frndint")
578 (eq_attr "type" "fcmp")
580 (eq_attr "unit" "i387")
582 (plus (attr "prefix_data16")
583 (attr "length_address")))
584 (ior (eq_attr "prefix" "vex")
585 (and (eq_attr "prefix" "maybe_vex")
586 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
587 (plus (attr "length_vex")
588 (plus (attr "length_immediate")
590 (attr "length_address"))))]
591 (plus (plus (attr "modrm")
592 (plus (attr "prefix_0f")
593 (plus (attr "prefix_rex")
594 (plus (attr "prefix_extra")
596 (plus (attr "prefix_rep")
597 (plus (attr "prefix_data16")
598 (plus (attr "length_immediate")
599 (attr "length_address")))))))
601 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
602 ;; `store' if there is a simple memory reference therein, or `unknown'
603 ;; if the instruction is complex.
605 (define_attr "memory" "none,load,store,both,unknown"
606 (cond [(eq_attr "type" "other,multi,str,lwp")
607 (const_string "unknown")
608 (eq_attr "type" "lea,fcmov,fpspc")
609 (const_string "none")
610 (eq_attr "type" "fistp,leave")
611 (const_string "both")
612 (eq_attr "type" "frndint")
613 (const_string "load")
614 (eq_attr "type" "push")
615 (if_then_else (match_operand 1 "memory_operand" "")
616 (const_string "both")
617 (const_string "store"))
618 (eq_attr "type" "pop")
619 (if_then_else (match_operand 0 "memory_operand" "")
620 (const_string "both")
621 (const_string "load"))
622 (eq_attr "type" "setcc")
623 (if_then_else (match_operand 0 "memory_operand" "")
624 (const_string "store")
625 (const_string "none"))
626 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
627 (if_then_else (ior (match_operand 0 "memory_operand" "")
628 (match_operand 1 "memory_operand" ""))
629 (const_string "load")
630 (const_string "none"))
631 (eq_attr "type" "ibr")
632 (if_then_else (match_operand 0 "memory_operand" "")
633 (const_string "load")
634 (const_string "none"))
635 (eq_attr "type" "call")
636 (if_then_else (match_operand 0 "constant_call_address_operand" "")
637 (const_string "none")
638 (const_string "load"))
639 (eq_attr "type" "callv")
640 (if_then_else (match_operand 1 "constant_call_address_operand" "")
641 (const_string "none")
642 (const_string "load"))
643 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
644 (match_operand 1 "memory_operand" ""))
645 (const_string "both")
646 (and (match_operand 0 "memory_operand" "")
647 (match_operand 1 "memory_operand" ""))
648 (const_string "both")
649 (match_operand 0 "memory_operand" "")
650 (const_string "store")
651 (match_operand 1 "memory_operand" "")
652 (const_string "load")
654 "!alu1,negnot,ishift1,
655 imov,imovx,icmp,test,bitmanip,
657 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
658 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
659 (match_operand 2 "memory_operand" ""))
660 (const_string "load")
661 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
662 (match_operand 3 "memory_operand" ""))
663 (const_string "load")
665 (const_string "none")))
667 ;; Indicates if an instruction has both an immediate and a displacement.
669 (define_attr "imm_disp" "false,true,unknown"
670 (cond [(eq_attr "type" "other,multi")
671 (const_string "unknown")
672 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
673 (and (match_operand 0 "memory_displacement_operand" "")
674 (match_operand 1 "immediate_operand" "")))
675 (const_string "true")
676 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
677 (and (match_operand 0 "memory_displacement_operand" "")
678 (match_operand 2 "immediate_operand" "")))
679 (const_string "true")
681 (const_string "false")))
683 ;; Indicates if an FP operation has an integer source.
685 (define_attr "fp_int_src" "false,true"
686 (const_string "false"))
688 ;; Defines rounding mode of an FP operation.
690 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
691 (const_string "any"))
693 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
694 (define_attr "use_carry" "0,1" (const_string "0"))
696 ;; Define attribute to indicate unaligned ssemov insns
697 (define_attr "movu" "0,1" (const_string "0"))
699 ;; Used to control the "enabled" attribute on a per-instruction basis.
700 (define_attr "isa" "base,noavx,avx"
701 (const_string "base"))
703 (define_attr "enabled" ""
704 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
705 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
709 ;; Describe a user's asm statement.
710 (define_asm_attributes
711 [(set_attr "length" "128")
712 (set_attr "type" "multi")])
714 (define_code_iterator plusminus [plus minus])
716 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
718 ;; Base name for define_insn
719 (define_code_attr plusminus_insn
720 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
721 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
723 ;; Base name for insn mnemonic.
724 (define_code_attr plusminus_mnemonic
725 [(plus "add") (ss_plus "adds") (us_plus "addus")
726 (minus "sub") (ss_minus "subs") (us_minus "subus")])
727 (define_code_attr plusminus_carry_mnemonic
728 [(plus "adc") (minus "sbb")])
730 ;; Mark commutative operators as such in constraints.
731 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
732 (minus "") (ss_minus "") (us_minus "")])
734 ;; Mapping of signed max and min
735 (define_code_iterator smaxmin [smax smin])
737 ;; Mapping of unsigned max and min
738 (define_code_iterator umaxmin [umax umin])
740 ;; Base name for integer and FP insn mnemonic
741 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
742 (umax "maxu") (umin "minu")])
743 (define_code_attr maxmin_float [(smax "max") (smin "min")])
745 ;; Mapping of logic operators
746 (define_code_iterator any_logic [and ior xor])
747 (define_code_iterator any_or [ior xor])
749 ;; Base name for insn mnemonic.
750 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
752 ;; Mapping of shift-right operators
753 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
755 ;; Base name for define_insn
756 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
758 ;; Base name for insn mnemonic.
759 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
761 ;; Mapping of rotate operators
762 (define_code_iterator any_rotate [rotate rotatert])
764 ;; Base name for define_insn
765 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
767 ;; Base name for insn mnemonic.
768 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
770 ;; Mapping of abs neg operators
771 (define_code_iterator absneg [abs neg])
773 ;; Base name for x87 insn mnemonic.
774 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
776 ;; Used in signed and unsigned widening multiplications.
777 (define_code_iterator any_extend [sign_extend zero_extend])
779 ;; Various insn prefixes for signed and unsigned operations.
780 (define_code_attr u [(sign_extend "") (zero_extend "u")
781 (div "") (udiv "u")])
782 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
784 ;; Used in signed and unsigned divisions.
785 (define_code_iterator any_div [div udiv])
787 ;; Instruction prefix for signed and unsigned operations.
788 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
789 (div "i") (udiv "")])
791 ;; 64bit single word integer modes.
792 (define_mode_iterator SWI1248x [QI HI SI DI])
794 ;; 64bit single word integer modes without QImode and HImode.
795 (define_mode_iterator SWI48x [SI DI])
797 ;; Single word integer modes.
798 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
800 ;; Single word integer modes without SImode and DImode.
801 (define_mode_iterator SWI12 [QI HI])
803 ;; Single word integer modes without DImode.
804 (define_mode_iterator SWI124 [QI HI SI])
806 ;; Single word integer modes without QImode and DImode.
807 (define_mode_iterator SWI24 [HI SI])
809 ;; Single word integer modes without QImode.
810 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
812 ;; Single word integer modes without QImode and HImode.
813 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
815 ;; All math-dependant single and double word integer modes.
816 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
817 (HI "TARGET_HIMODE_MATH")
818 SI DI (TI "TARGET_64BIT")])
820 ;; Math-dependant single word integer modes.
821 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
822 (HI "TARGET_HIMODE_MATH")
823 SI (DI "TARGET_64BIT")])
825 ;; Math-dependant single word integer modes without DImode.
826 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
827 (HI "TARGET_HIMODE_MATH")
830 ;; Math-dependant single word integer modes without QImode.
831 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
832 SI (DI "TARGET_64BIT")])
834 ;; Double word integer modes.
835 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
836 (TI "TARGET_64BIT")])
838 ;; Double word integer modes as mode attribute.
839 (define_mode_attr DWI [(SI "DI") (DI "TI")])
840 (define_mode_attr dwi [(SI "di") (DI "ti")])
842 ;; Half mode for double word integer modes.
843 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
844 (DI "TARGET_64BIT")])
846 ;; Instruction suffix for integer modes.
847 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
849 ;; Pointer size prefix for integer modes (Intel asm dialect)
850 (define_mode_attr iptrsize [(QI "BYTE")
855 ;; Register class for integer modes.
856 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
858 ;; Immediate operand constraint for integer modes.
859 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
861 ;; General operand constraint for word modes.
862 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
864 ;; Immediate operand constraint for double integer modes.
865 (define_mode_attr di [(SI "iF") (DI "e")])
867 ;; Immediate operand constraint for shifts.
868 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
870 ;; General operand predicate for integer modes.
871 (define_mode_attr general_operand
872 [(QI "general_operand")
873 (HI "general_operand")
874 (SI "general_operand")
875 (DI "x86_64_general_operand")
876 (TI "x86_64_general_operand")])
878 ;; General sign/zero extend operand predicate for integer modes.
879 (define_mode_attr general_szext_operand
880 [(QI "general_operand")
881 (HI "general_operand")
882 (SI "general_operand")
883 (DI "x86_64_szext_general_operand")])
885 ;; Immediate operand predicate for integer modes.
886 (define_mode_attr immediate_operand
887 [(QI "immediate_operand")
888 (HI "immediate_operand")
889 (SI "immediate_operand")
890 (DI "x86_64_immediate_operand")])
892 ;; Nonmemory operand predicate for integer modes.
893 (define_mode_attr nonmemory_operand
894 [(QI "nonmemory_operand")
895 (HI "nonmemory_operand")
896 (SI "nonmemory_operand")
897 (DI "x86_64_nonmemory_operand")])
899 ;; Operand predicate for shifts.
900 (define_mode_attr shift_operand
901 [(QI "nonimmediate_operand")
902 (HI "nonimmediate_operand")
903 (SI "nonimmediate_operand")
904 (DI "shiftdi_operand")
905 (TI "register_operand")])
907 ;; Operand predicate for shift argument.
908 (define_mode_attr shift_immediate_operand
909 [(QI "const_1_to_31_operand")
910 (HI "const_1_to_31_operand")
911 (SI "const_1_to_31_operand")
912 (DI "const_1_to_63_operand")])
914 ;; Input operand predicate for arithmetic left shifts.
915 (define_mode_attr ashl_input_operand
916 [(QI "nonimmediate_operand")
917 (HI "nonimmediate_operand")
918 (SI "nonimmediate_operand")
919 (DI "ashldi_input_operand")
920 (TI "reg_or_pm1_operand")])
922 ;; SSE and x87 SFmode and DFmode floating point modes
923 (define_mode_iterator MODEF [SF DF])
925 ;; All x87 floating point modes
926 (define_mode_iterator X87MODEF [SF DF XF])
928 ;; All integer modes handled by x87 fisttp operator.
929 (define_mode_iterator X87MODEI [HI SI DI])
931 ;; All integer modes handled by integer x87 operators.
932 (define_mode_iterator X87MODEI12 [HI SI])
934 ;; All integer modes handled by SSE cvtts?2si* operators.
935 (define_mode_iterator SSEMODEI24 [SI DI])
937 ;; SSE instruction suffix for various modes
938 (define_mode_attr ssemodesuffix
940 (V8SF "ps") (V4DF "pd")
941 (V4SF "ps") (V2DF "pd")
942 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
945 ;; SSE vector suffix for floating point modes
946 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
948 ;; SSE vector mode corresponding to a scalar mode
949 (define_mode_attr ssevecmode
950 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
952 ;; Instruction suffix for REX 64bit operators.
953 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
955 ;; This mode iterator allows :P to be used for patterns that operate on
956 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
957 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
959 ;; Scheduling descriptions
961 (include "pentium.md")
964 (include "athlon.md")
965 (include "bdver1.md")
971 ;; Operand and operator predicates and constraints
973 (include "predicates.md")
974 (include "constraints.md")
977 ;; Compare and branch/compare and store instructions.
979 (define_expand "cbranch<mode>4"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
982 (match_operand:SDWIM 2 "<general_operand>" "")))
983 (set (pc) (if_then_else
984 (match_operator 0 "ordered_comparison_operator"
985 [(reg:CC FLAGS_REG) (const_int 0)])
986 (label_ref (match_operand 3 "" ""))
990 if (MEM_P (operands[1]) && MEM_P (operands[2]))
991 operands[1] = force_reg (<MODE>mode, operands[1]);
992 ix86_expand_branch (GET_CODE (operands[0]),
993 operands[1], operands[2], operands[3]);
997 (define_expand "cstore<mode>4"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1000 (match_operand:SWIM 3 "<general_operand>" "")))
1001 (set (match_operand:QI 0 "register_operand" "")
1002 (match_operator 1 "ordered_comparison_operator"
1003 [(reg:CC FLAGS_REG) (const_int 0)]))]
1006 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1007 operands[2] = force_reg (<MODE>mode, operands[2]);
1008 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1009 operands[2], operands[3]);
1013 (define_expand "cmp<mode>_1"
1014 [(set (reg:CC FLAGS_REG)
1015 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1016 (match_operand:SWI48 1 "<general_operand>" "")))])
1018 (define_insn "*cmp<mode>_ccno_1"
1019 [(set (reg FLAGS_REG)
1020 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1021 (match_operand:SWI 1 "const0_operand" "")))]
1022 "ix86_match_ccmode (insn, CCNOmode)"
1024 test{<imodesuffix>}\t%0, %0
1025 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1026 [(set_attr "type" "test,icmp")
1027 (set_attr "length_immediate" "0,1")
1028 (set_attr "mode" "<MODE>")])
1030 (define_insn "*cmp<mode>_1"
1031 [(set (reg FLAGS_REG)
1032 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1033 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1034 "ix86_match_ccmode (insn, CCmode)"
1035 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "<MODE>")])
1039 (define_insn "*cmp<mode>_minus_1"
1040 [(set (reg FLAGS_REG)
1042 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1043 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1045 "ix86_match_ccmode (insn, CCGOCmode)"
1046 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1047 [(set_attr "type" "icmp")
1048 (set_attr "mode" "<MODE>")])
1050 (define_insn "*cmpqi_ext_1"
1051 [(set (reg FLAGS_REG)
1053 (match_operand:QI 0 "general_operand" "Qm")
1056 (match_operand 1 "ext_register_operand" "Q")
1058 (const_int 8)) 0)))]
1059 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1060 "cmp{b}\t{%h1, %0|%0, %h1}"
1061 [(set_attr "type" "icmp")
1062 (set_attr "mode" "QI")])
1064 (define_insn "*cmpqi_ext_1_rex64"
1065 [(set (reg FLAGS_REG)
1067 (match_operand:QI 0 "register_operand" "Q")
1070 (match_operand 1 "ext_register_operand" "Q")
1072 (const_int 8)) 0)))]
1073 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1074 "cmp{b}\t{%h1, %0|%0, %h1}"
1075 [(set_attr "type" "icmp")
1076 (set_attr "mode" "QI")])
1078 (define_insn "*cmpqi_ext_2"
1079 [(set (reg FLAGS_REG)
1083 (match_operand 0 "ext_register_operand" "Q")
1086 (match_operand:QI 1 "const0_operand" "")))]
1087 "ix86_match_ccmode (insn, CCNOmode)"
1089 [(set_attr "type" "test")
1090 (set_attr "length_immediate" "0")
1091 (set_attr "mode" "QI")])
1093 (define_expand "cmpqi_ext_3"
1094 [(set (reg:CC FLAGS_REG)
1098 (match_operand 0 "ext_register_operand" "")
1101 (match_operand:QI 1 "immediate_operand" "")))])
1103 (define_insn "*cmpqi_ext_3_insn"
1104 [(set (reg FLAGS_REG)
1108 (match_operand 0 "ext_register_operand" "Q")
1111 (match_operand:QI 1 "general_operand" "Qmn")))]
1112 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1113 "cmp{b}\t{%1, %h0|%h0, %1}"
1114 [(set_attr "type" "icmp")
1115 (set_attr "modrm" "1")
1116 (set_attr "mode" "QI")])
1118 (define_insn "*cmpqi_ext_3_insn_rex64"
1119 [(set (reg FLAGS_REG)
1123 (match_operand 0 "ext_register_operand" "Q")
1126 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1127 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1128 "cmp{b}\t{%1, %h0|%h0, %1}"
1129 [(set_attr "type" "icmp")
1130 (set_attr "modrm" "1")
1131 (set_attr "mode" "QI")])
1133 (define_insn "*cmpqi_ext_4"
1134 [(set (reg FLAGS_REG)
1138 (match_operand 0 "ext_register_operand" "Q")
1143 (match_operand 1 "ext_register_operand" "Q")
1145 (const_int 8)) 0)))]
1146 "ix86_match_ccmode (insn, CCmode)"
1147 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1148 [(set_attr "type" "icmp")
1149 (set_attr "mode" "QI")])
1151 ;; These implement float point compares.
1152 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1153 ;; which would allow mix and match FP modes on the compares. Which is what
1154 ;; the old patterns did, but with many more of them.
1156 (define_expand "cbranchxf4"
1157 [(set (reg:CC FLAGS_REG)
1158 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1159 (match_operand:XF 2 "nonmemory_operand" "")))
1160 (set (pc) (if_then_else
1161 (match_operator 0 "ix86_fp_comparison_operator"
1164 (label_ref (match_operand 3 "" ""))
1168 ix86_expand_branch (GET_CODE (operands[0]),
1169 operands[1], operands[2], operands[3]);
1173 (define_expand "cstorexf4"
1174 [(set (reg:CC FLAGS_REG)
1175 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1176 (match_operand:XF 3 "nonmemory_operand" "")))
1177 (set (match_operand:QI 0 "register_operand" "")
1178 (match_operator 1 "ix86_fp_comparison_operator"
1183 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1184 operands[2], operands[3]);
1188 (define_expand "cbranch<mode>4"
1189 [(set (reg:CC FLAGS_REG)
1190 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1191 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1192 (set (pc) (if_then_else
1193 (match_operator 0 "ix86_fp_comparison_operator"
1196 (label_ref (match_operand 3 "" ""))
1198 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1200 ix86_expand_branch (GET_CODE (operands[0]),
1201 operands[1], operands[2], operands[3]);
1205 (define_expand "cstore<mode>4"
1206 [(set (reg:CC FLAGS_REG)
1207 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1208 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1209 (set (match_operand:QI 0 "register_operand" "")
1210 (match_operator 1 "ix86_fp_comparison_operator"
1213 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1215 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1216 operands[2], operands[3]);
1220 (define_expand "cbranchcc4"
1221 [(set (pc) (if_then_else
1222 (match_operator 0 "comparison_operator"
1223 [(match_operand 1 "flags_reg_operand" "")
1224 (match_operand 2 "const0_operand" "")])
1225 (label_ref (match_operand 3 "" ""))
1229 ix86_expand_branch (GET_CODE (operands[0]),
1230 operands[1], operands[2], operands[3]);
1234 (define_expand "cstorecc4"
1235 [(set (match_operand:QI 0 "register_operand" "")
1236 (match_operator 1 "comparison_operator"
1237 [(match_operand 2 "flags_reg_operand" "")
1238 (match_operand 3 "const0_operand" "")]))]
1241 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1242 operands[2], operands[3]);
1247 ;; FP compares, step 1:
1248 ;; Set the FP condition codes.
1250 ;; CCFPmode compare with exceptions
1251 ;; CCFPUmode compare with no exceptions
1253 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1254 ;; used to manage the reg stack popping would not be preserved.
1256 (define_insn "*cmpfp_0"
1257 [(set (match_operand:HI 0 "register_operand" "=a")
1260 (match_operand 1 "register_operand" "f")
1261 (match_operand 2 "const0_operand" ""))]
1263 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1264 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1265 "* return output_fp_compare (insn, operands, 0, 0);"
1266 [(set_attr "type" "multi")
1267 (set_attr "unit" "i387")
1269 (cond [(match_operand:SF 1 "" "")
1271 (match_operand:DF 1 "" "")
1274 (const_string "XF")))])
1276 (define_insn_and_split "*cmpfp_0_cc"
1277 [(set (reg:CCFP FLAGS_REG)
1279 (match_operand 1 "register_operand" "f")
1280 (match_operand 2 "const0_operand" "")))
1281 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1282 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1283 && TARGET_SAHF && !TARGET_CMOVE
1284 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1286 "&& reload_completed"
1289 [(compare:CCFP (match_dup 1)(match_dup 2))]
1291 (set (reg:CC FLAGS_REG)
1292 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1294 [(set_attr "type" "multi")
1295 (set_attr "unit" "i387")
1297 (cond [(match_operand:SF 1 "" "")
1299 (match_operand:DF 1 "" "")
1302 (const_string "XF")))])
1304 (define_insn "*cmpfp_xf"
1305 [(set (match_operand:HI 0 "register_operand" "=a")
1308 (match_operand:XF 1 "register_operand" "f")
1309 (match_operand:XF 2 "register_operand" "f"))]
1312 "* return output_fp_compare (insn, operands, 0, 0);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "XF")])
1317 (define_insn_and_split "*cmpfp_xf_cc"
1318 [(set (reg:CCFP FLAGS_REG)
1320 (match_operand:XF 1 "register_operand" "f")
1321 (match_operand:XF 2 "register_operand" "f")))
1322 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1324 && TARGET_SAHF && !TARGET_CMOVE"
1326 "&& reload_completed"
1329 [(compare:CCFP (match_dup 1)(match_dup 2))]
1331 (set (reg:CC FLAGS_REG)
1332 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1334 [(set_attr "type" "multi")
1335 (set_attr "unit" "i387")
1336 (set_attr "mode" "XF")])
1338 (define_insn "*cmpfp_<mode>"
1339 [(set (match_operand:HI 0 "register_operand" "=a")
1342 (match_operand:MODEF 1 "register_operand" "f")
1343 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1346 "* return output_fp_compare (insn, operands, 0, 0);"
1347 [(set_attr "type" "multi")
1348 (set_attr "unit" "i387")
1349 (set_attr "mode" "<MODE>")])
1351 (define_insn_and_split "*cmpfp_<mode>_cc"
1352 [(set (reg:CCFP FLAGS_REG)
1354 (match_operand:MODEF 1 "register_operand" "f")
1355 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1356 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1358 && TARGET_SAHF && !TARGET_CMOVE"
1360 "&& reload_completed"
1363 [(compare:CCFP (match_dup 1)(match_dup 2))]
1365 (set (reg:CC FLAGS_REG)
1366 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1368 [(set_attr "type" "multi")
1369 (set_attr "unit" "i387")
1370 (set_attr "mode" "<MODE>")])
1372 (define_insn "*cmpfp_u"
1373 [(set (match_operand:HI 0 "register_operand" "=a")
1376 (match_operand 1 "register_operand" "f")
1377 (match_operand 2 "register_operand" "f"))]
1379 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1380 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1381 "* return output_fp_compare (insn, operands, 0, 1);"
1382 [(set_attr "type" "multi")
1383 (set_attr "unit" "i387")
1385 (cond [(match_operand:SF 1 "" "")
1387 (match_operand:DF 1 "" "")
1390 (const_string "XF")))])
1392 (define_insn_and_split "*cmpfp_u_cc"
1393 [(set (reg:CCFPU FLAGS_REG)
1395 (match_operand 1 "register_operand" "f")
1396 (match_operand 2 "register_operand" "f")))
1397 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1398 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1399 && TARGET_SAHF && !TARGET_CMOVE
1400 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1402 "&& reload_completed"
1405 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1407 (set (reg:CC FLAGS_REG)
1408 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1410 [(set_attr "type" "multi")
1411 (set_attr "unit" "i387")
1413 (cond [(match_operand:SF 1 "" "")
1415 (match_operand:DF 1 "" "")
1418 (const_string "XF")))])
1420 (define_insn "*cmpfp_<mode>"
1421 [(set (match_operand:HI 0 "register_operand" "=a")
1424 (match_operand 1 "register_operand" "f")
1425 (match_operator 3 "float_operator"
1426 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1428 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1430 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1431 "* return output_fp_compare (insn, operands, 0, 0);"
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set_attr "fp_int_src" "true")
1435 (set_attr "mode" "<MODE>")])
1437 (define_insn_and_split "*cmpfp_<mode>_cc"
1438 [(set (reg:CCFP FLAGS_REG)
1440 (match_operand 1 "register_operand" "f")
1441 (match_operator 3 "float_operator"
1442 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1443 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1444 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1445 && TARGET_SAHF && !TARGET_CMOVE
1446 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1447 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1449 "&& reload_completed"
1454 (match_op_dup 3 [(match_dup 2)]))]
1456 (set (reg:CC FLAGS_REG)
1457 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1459 [(set_attr "type" "multi")
1460 (set_attr "unit" "i387")
1461 (set_attr "fp_int_src" "true")
1462 (set_attr "mode" "<MODE>")])
1464 ;; FP compares, step 2
1465 ;; Move the fpsw to ax.
1467 (define_insn "x86_fnstsw_1"
1468 [(set (match_operand:HI 0 "register_operand" "=a")
1469 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1472 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1473 (set_attr "mode" "SI")
1474 (set_attr "unit" "i387")])
1476 ;; FP compares, step 3
1477 ;; Get ax into flags, general case.
1479 (define_insn "x86_sahf_1"
1480 [(set (reg:CC FLAGS_REG)
1481 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1485 #ifndef HAVE_AS_IX86_SAHF
1487 return ASM_BYTE "0x9e";
1492 [(set_attr "length" "1")
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")
1495 (set_attr "bdver1_decode" "direct")
1496 (set_attr "mode" "SI")])
1498 ;; Pentium Pro can do steps 1 through 3 in one go.
1499 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1500 (define_insn "*cmpfp_i_mixed"
1501 [(set (reg:CCFP FLAGS_REG)
1502 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1503 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1504 "TARGET_MIX_SSE_I387
1505 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1506 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507 "* return output_fp_compare (insn, operands, 1, 0);"
1508 [(set_attr "type" "fcmp,ssecomi")
1509 (set_attr "prefix" "orig,maybe_vex")
1511 (if_then_else (match_operand:SF 1 "" "")
1513 (const_string "DF")))
1514 (set (attr "prefix_rep")
1515 (if_then_else (eq_attr "type" "ssecomi")
1517 (const_string "*")))
1518 (set (attr "prefix_data16")
1519 (cond [(eq_attr "type" "fcmp")
1521 (eq_attr "mode" "DF")
1524 (const_string "0")))
1525 (set_attr "athlon_decode" "vector")
1526 (set_attr "amdfam10_decode" "direct")
1527 (set_attr "bdver1_decode" "double")])
1529 (define_insn "*cmpfp_i_sse"
1530 [(set (reg:CCFP FLAGS_REG)
1531 (compare:CCFP (match_operand 0 "register_operand" "x")
1532 (match_operand 1 "nonimmediate_operand" "xm")))]
1534 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1535 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1536 "* return output_fp_compare (insn, operands, 1, 0);"
1537 [(set_attr "type" "ssecomi")
1538 (set_attr "prefix" "maybe_vex")
1540 (if_then_else (match_operand:SF 1 "" "")
1542 (const_string "DF")))
1543 (set_attr "prefix_rep" "0")
1544 (set (attr "prefix_data16")
1545 (if_then_else (eq_attr "mode" "DF")
1547 (const_string "0")))
1548 (set_attr "athlon_decode" "vector")
1549 (set_attr "amdfam10_decode" "direct")
1550 (set_attr "bdver1_decode" "double")])
1552 (define_insn "*cmpfp_i_i387"
1553 [(set (reg:CCFP FLAGS_REG)
1554 (compare:CCFP (match_operand 0 "register_operand" "f")
1555 (match_operand 1 "register_operand" "f")))]
1556 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1558 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1559 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560 "* return output_fp_compare (insn, operands, 1, 0);"
1561 [(set_attr "type" "fcmp")
1563 (cond [(match_operand:SF 1 "" "")
1565 (match_operand:DF 1 "" "")
1568 (const_string "XF")))
1569 (set_attr "athlon_decode" "vector")
1570 (set_attr "amdfam10_decode" "direct")
1571 (set_attr "bdver1_decode" "double")])
1573 (define_insn "*cmpfp_iu_mixed"
1574 [(set (reg:CCFPU FLAGS_REG)
1575 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1576 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1577 "TARGET_MIX_SSE_I387
1578 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1579 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580 "* return output_fp_compare (insn, operands, 1, 1);"
1581 [(set_attr "type" "fcmp,ssecomi")
1582 (set_attr "prefix" "orig,maybe_vex")
1584 (if_then_else (match_operand:SF 1 "" "")
1586 (const_string "DF")))
1587 (set (attr "prefix_rep")
1588 (if_then_else (eq_attr "type" "ssecomi")
1590 (const_string "*")))
1591 (set (attr "prefix_data16")
1592 (cond [(eq_attr "type" "fcmp")
1594 (eq_attr "mode" "DF")
1597 (const_string "0")))
1598 (set_attr "athlon_decode" "vector")
1599 (set_attr "amdfam10_decode" "direct")
1600 (set_attr "bdver1_decode" "double")])
1602 (define_insn "*cmpfp_iu_sse"
1603 [(set (reg:CCFPU FLAGS_REG)
1604 (compare:CCFPU (match_operand 0 "register_operand" "x")
1605 (match_operand 1 "nonimmediate_operand" "xm")))]
1607 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1608 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1609 "* return output_fp_compare (insn, operands, 1, 1);"
1610 [(set_attr "type" "ssecomi")
1611 (set_attr "prefix" "maybe_vex")
1613 (if_then_else (match_operand:SF 1 "" "")
1615 (const_string "DF")))
1616 (set_attr "prefix_rep" "0")
1617 (set (attr "prefix_data16")
1618 (if_then_else (eq_attr "mode" "DF")
1620 (const_string "0")))
1621 (set_attr "athlon_decode" "vector")
1622 (set_attr "amdfam10_decode" "direct")
1623 (set_attr "bdver1_decode" "double")])
1625 (define_insn "*cmpfp_iu_387"
1626 [(set (reg:CCFPU FLAGS_REG)
1627 (compare:CCFPU (match_operand 0 "register_operand" "f")
1628 (match_operand 1 "register_operand" "f")))]
1629 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1631 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1632 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1633 "* return output_fp_compare (insn, operands, 1, 1);"
1634 [(set_attr "type" "fcmp")
1636 (cond [(match_operand:SF 1 "" "")
1638 (match_operand:DF 1 "" "")
1641 (const_string "XF")))
1642 (set_attr "athlon_decode" "vector")
1643 (set_attr "amdfam10_decode" "direct")
1644 (set_attr "bdver1_decode" "direct")])
1646 ;; Push/pop instructions.
1648 (define_insn "*push<mode>2"
1649 [(set (match_operand:DWI 0 "push_operand" "=<")
1650 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1655 [(set (match_operand:TI 0 "push_operand" "")
1656 (match_operand:TI 1 "general_operand" ""))]
1657 "TARGET_64BIT && reload_completed
1658 && !SSE_REG_P (operands[1])"
1660 "ix86_split_long_move (operands); DONE;")
1662 (define_insn "*pushdi2_rex64"
1663 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1664 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1669 [(set_attr "type" "push,multi")
1670 (set_attr "mode" "DI")])
1672 ;; Convert impossible pushes of immediate to existing instructions.
1673 ;; First try to get scratch register and go through it. In case this
1674 ;; fails, push sign extended lower part first and then overwrite
1675 ;; upper part by 32bit move.
1677 [(match_scratch:DI 2 "r")
1678 (set (match_operand:DI 0 "push_operand" "")
1679 (match_operand:DI 1 "immediate_operand" ""))]
1680 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1681 && !x86_64_immediate_operand (operands[1], DImode)"
1682 [(set (match_dup 2) (match_dup 1))
1683 (set (match_dup 0) (match_dup 2))])
1685 ;; We need to define this as both peepholer and splitter for case
1686 ;; peephole2 pass is not run.
1687 ;; "&& 1" is needed to keep it from matching the previous pattern.
1689 [(set (match_operand:DI 0 "push_operand" "")
1690 (match_operand:DI 1 "immediate_operand" ""))]
1691 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1692 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1693 [(set (match_dup 0) (match_dup 1))
1694 (set (match_dup 2) (match_dup 3))]
1696 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1698 operands[1] = gen_lowpart (DImode, operands[2]);
1699 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1704 [(set (match_operand:DI 0 "push_operand" "")
1705 (match_operand:DI 1 "immediate_operand" ""))]
1706 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1707 ? epilogue_completed : reload_completed)
1708 && !symbolic_operand (operands[1], DImode)
1709 && !x86_64_immediate_operand (operands[1], DImode)"
1710 [(set (match_dup 0) (match_dup 1))
1711 (set (match_dup 2) (match_dup 3))]
1713 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1715 operands[1] = gen_lowpart (DImode, operands[2]);
1716 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1721 [(set (match_operand:DI 0 "push_operand" "")
1722 (match_operand:DI 1 "general_operand" ""))]
1723 "!TARGET_64BIT && reload_completed
1724 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1726 "ix86_split_long_move (operands); DONE;")
1728 (define_insn "*pushsi2"
1729 [(set (match_operand:SI 0 "push_operand" "=<")
1730 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1733 [(set_attr "type" "push")
1734 (set_attr "mode" "SI")])
1736 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1737 ;; "push a byte/word". But actually we use pushl, which has the effect
1738 ;; of rounding the amount pushed up to a word.
1740 ;; For TARGET_64BIT we always round up to 8 bytes.
1741 (define_insn "*push<mode>2_rex64"
1742 [(set (match_operand:SWI124 0 "push_operand" "=X")
1743 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1746 [(set_attr "type" "push")
1747 (set_attr "mode" "DI")])
1749 (define_insn "*push<mode>2"
1750 [(set (match_operand:SWI12 0 "push_operand" "=X")
1751 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1754 [(set_attr "type" "push")
1755 (set_attr "mode" "SI")])
1757 (define_insn "*push<mode>2_prologue"
1758 [(set (match_operand:P 0 "push_operand" "=<")
1759 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1760 (clobber (mem:BLK (scratch)))]
1762 "push{<imodesuffix>}\t%1"
1763 [(set_attr "type" "push")
1764 (set_attr "mode" "<MODE>")])
1766 (define_insn "*pop<mode>1"
1767 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1768 (match_operand:P 1 "pop_operand" ">"))]
1770 "pop{<imodesuffix>}\t%0"
1771 [(set_attr "type" "pop")
1772 (set_attr "mode" "<MODE>")])
1774 (define_insn "*pop<mode>1_epilogue"
1775 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1776 (match_operand:P 1 "pop_operand" ">"))
1777 (clobber (mem:BLK (scratch)))]
1779 "pop{<imodesuffix>}\t%0"
1780 [(set_attr "type" "pop")
1781 (set_attr "mode" "<MODE>")])
1783 ;; Move instructions.
1785 (define_expand "movoi"
1786 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1787 (match_operand:OI 1 "general_operand" ""))]
1789 "ix86_expand_move (OImode, operands); DONE;")
1791 (define_expand "movti"
1792 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1793 (match_operand:TI 1 "nonimmediate_operand" ""))]
1794 "TARGET_64BIT || TARGET_SSE"
1797 ix86_expand_move (TImode, operands);
1798 else if (push_operand (operands[0], TImode))
1799 ix86_expand_push (TImode, operands[1]);
1801 ix86_expand_vector_move (TImode, operands);
1805 ;; This expands to what emit_move_complex would generate if we didn't
1806 ;; have a movti pattern. Having this avoids problems with reload on
1807 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1808 ;; to have around all the time.
1809 (define_expand "movcdi"
1810 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1811 (match_operand:CDI 1 "general_operand" ""))]
1814 if (push_operand (operands[0], CDImode))
1815 emit_move_complex_push (CDImode, operands[0], operands[1]);
1817 emit_move_complex_parts (operands[0], operands[1]);
1821 (define_expand "mov<mode>"
1822 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1823 (match_operand:SWI1248x 1 "general_operand" ""))]
1825 "ix86_expand_move (<MODE>mode, operands); DONE;")
1827 (define_insn "*mov<mode>_xor"
1828 [(set (match_operand:SWI48 0 "register_operand" "=r")
1829 (match_operand:SWI48 1 "const0_operand" ""))
1830 (clobber (reg:CC FLAGS_REG))]
1833 [(set_attr "type" "alu1")
1834 (set_attr "mode" "SI")
1835 (set_attr "length_immediate" "0")])
1837 (define_insn "*mov<mode>_or"
1838 [(set (match_operand:SWI48 0 "register_operand" "=r")
1839 (match_operand:SWI48 1 "const_int_operand" ""))
1840 (clobber (reg:CC FLAGS_REG))]
1842 && operands[1] == constm1_rtx"
1843 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1844 [(set_attr "type" "alu1")
1845 (set_attr "mode" "<MODE>")
1846 (set_attr "length_immediate" "1")])
1848 (define_insn "*movoi_internal_avx"
1849 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1850 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1851 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1853 switch (which_alternative)
1856 return "vxorps\t%0, %0, %0";
1859 if (misaligned_operand (operands[0], OImode)
1860 || misaligned_operand (operands[1], OImode))
1861 return "vmovdqu\t{%1, %0|%0, %1}";
1863 return "vmovdqa\t{%1, %0|%0, %1}";
1868 [(set_attr "type" "sselog1,ssemov,ssemov")
1869 (set_attr "prefix" "vex")
1870 (set_attr "mode" "OI")])
1872 (define_insn "*movti_internal_rex64"
1873 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1874 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1875 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1877 switch (which_alternative)
1883 if (get_attr_mode (insn) == MODE_V4SF)
1884 return "%vxorps\t%0, %d0";
1886 return "%vpxor\t%0, %d0";
1889 /* TDmode values are passed as TImode on the stack. Moving them
1890 to stack may result in unaligned memory access. */
1891 if (misaligned_operand (operands[0], TImode)
1892 || misaligned_operand (operands[1], TImode))
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovups\t{%1, %0|%0, %1}";
1897 return "%vmovdqu\t{%1, %0|%0, %1}";
1901 if (get_attr_mode (insn) == MODE_V4SF)
1902 return "%vmovaps\t{%1, %0|%0, %1}";
1904 return "%vmovdqa\t{%1, %0|%0, %1}";
1910 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1911 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1913 (cond [(eq_attr "alternative" "2,3")
1915 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1917 (const_string "V4SF")
1918 (const_string "TI"))
1919 (eq_attr "alternative" "4")
1921 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1923 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1925 (const_string "V4SF")
1926 (const_string "TI"))]
1927 (const_string "DI")))])
1930 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1931 (match_operand:TI 1 "general_operand" ""))]
1933 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1935 "ix86_split_long_move (operands); DONE;")
1937 (define_insn "*movti_internal_sse"
1938 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1939 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1940 "TARGET_SSE && !TARGET_64BIT
1941 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943 switch (which_alternative)
1946 if (get_attr_mode (insn) == MODE_V4SF)
1947 return "%vxorps\t%0, %d0";
1949 return "%vpxor\t%0, %d0";
1952 /* TDmode values are passed as TImode on the stack. Moving them
1953 to stack may result in unaligned memory access. */
1954 if (misaligned_operand (operands[0], TImode)
1955 || misaligned_operand (operands[1], TImode))
1957 if (get_attr_mode (insn) == MODE_V4SF)
1958 return "%vmovups\t{%1, %0|%0, %1}";
1960 return "%vmovdqu\t{%1, %0|%0, %1}";
1964 if (get_attr_mode (insn) == MODE_V4SF)
1965 return "%vmovaps\t{%1, %0|%0, %1}";
1967 return "%vmovdqa\t{%1, %0|%0, %1}";
1973 [(set_attr "type" "sselog1,ssemov,ssemov")
1974 (set_attr "prefix" "maybe_vex")
1976 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1977 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1979 (const_string "V4SF")
1980 (and (eq_attr "alternative" "2")
1981 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1983 (const_string "V4SF")]
1984 (const_string "TI")))])
1986 (define_insn "*movdi_internal_rex64"
1987 [(set (match_operand:DI 0 "nonimmediate_operand"
1988 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1989 (match_operand:DI 1 "general_operand"
1990 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1991 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1993 switch (get_attr_type (insn))
1996 if (SSE_REG_P (operands[0]))
1997 return "movq2dq\t{%1, %0|%0, %1}";
1999 return "movdq2q\t{%1, %0|%0, %1}";
2004 if (get_attr_mode (insn) == MODE_TI)
2005 return "vmovdqa\t{%1, %0|%0, %1}";
2007 return "vmovq\t{%1, %0|%0, %1}";
2010 if (get_attr_mode (insn) == MODE_TI)
2011 return "movdqa\t{%1, %0|%0, %1}";
2015 /* Moves from and into integer register is done using movd
2016 opcode with REX prefix. */
2017 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2018 return "movd\t{%1, %0|%0, %1}";
2019 return "movq\t{%1, %0|%0, %1}";
2022 return "%vpxor\t%0, %d0";
2025 return "pxor\t%0, %0";
2031 return "lea{q}\t{%a1, %0|%0, %a1}";
2034 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2035 if (get_attr_mode (insn) == MODE_SI)
2036 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2037 else if (which_alternative == 2)
2038 return "movabs{q}\t{%1, %0|%0, %1}";
2040 return "mov{q}\t{%1, %0|%0, %1}";
2044 (cond [(eq_attr "alternative" "5")
2045 (const_string "mmx")
2046 (eq_attr "alternative" "6,7,8,9,10")
2047 (const_string "mmxmov")
2048 (eq_attr "alternative" "11")
2049 (const_string "sselog1")
2050 (eq_attr "alternative" "12,13,14,15,16")
2051 (const_string "ssemov")
2052 (eq_attr "alternative" "17,18")
2053 (const_string "ssecvt")
2054 (eq_attr "alternative" "4")
2055 (const_string "multi")
2056 (match_operand:DI 1 "pic_32bit_operand" "")
2057 (const_string "lea")
2059 (const_string "imov")))
2062 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2064 (const_string "*")))
2065 (set (attr "length_immediate")
2067 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2069 (const_string "*")))
2070 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2071 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2072 (set (attr "prefix")
2073 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2074 (const_string "maybe_vex")
2075 (const_string "orig")))
2076 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2078 ;; Convert impossible stores of immediate to existing instructions.
2079 ;; First try to get scratch register and go through it. In case this
2080 ;; fails, move by 32bit parts.
2082 [(match_scratch:DI 2 "r")
2083 (set (match_operand:DI 0 "memory_operand" "")
2084 (match_operand:DI 1 "immediate_operand" ""))]
2085 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2086 && !x86_64_immediate_operand (operands[1], DImode)"
2087 [(set (match_dup 2) (match_dup 1))
2088 (set (match_dup 0) (match_dup 2))])
2090 ;; We need to define this as both peepholer and splitter for case
2091 ;; peephole2 pass is not run.
2092 ;; "&& 1" is needed to keep it from matching the previous pattern.
2094 [(set (match_operand:DI 0 "memory_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2097 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2098 [(set (match_dup 2) (match_dup 3))
2099 (set (match_dup 4) (match_dup 5))]
2100 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2103 [(set (match_operand:DI 0 "memory_operand" "")
2104 (match_operand:DI 1 "immediate_operand" ""))]
2105 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2106 ? epilogue_completed : reload_completed)
2107 && !symbolic_operand (operands[1], DImode)
2108 && !x86_64_immediate_operand (operands[1], DImode)"
2109 [(set (match_dup 2) (match_dup 3))
2110 (set (match_dup 4) (match_dup 5))]
2111 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2113 (define_insn "*movdi_internal"
2114 [(set (match_operand:DI 0 "nonimmediate_operand"
2115 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2116 (match_operand:DI 1 "general_operand"
2117 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2118 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2123 movq\t{%1, %0|%0, %1}
2124 movq\t{%1, %0|%0, %1}
2126 %vmovq\t{%1, %0|%0, %1}
2127 %vmovdqa\t{%1, %0|%0, %1}
2128 %vmovq\t{%1, %0|%0, %1}
2130 movlps\t{%1, %0|%0, %1}
2131 movaps\t{%1, %0|%0, %1}
2132 movlps\t{%1, %0|%0, %1}"
2133 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2134 (set (attr "prefix")
2135 (if_then_else (eq_attr "alternative" "5,6,7,8")
2136 (const_string "vex")
2137 (const_string "orig")))
2138 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2141 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2142 (match_operand:DI 1 "general_operand" ""))]
2143 "!TARGET_64BIT && reload_completed
2144 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2145 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2147 "ix86_split_long_move (operands); DONE;")
2149 (define_insn "*movsi_internal"
2150 [(set (match_operand:SI 0 "nonimmediate_operand"
2151 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2152 (match_operand:SI 1 "general_operand"
2153 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2154 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2156 switch (get_attr_type (insn))
2159 if (get_attr_mode (insn) == MODE_TI)
2160 return "%vpxor\t%0, %d0";
2161 return "%vxorps\t%0, %d0";
2164 switch (get_attr_mode (insn))
2167 return "%vmovdqa\t{%1, %0|%0, %1}";
2169 return "%vmovaps\t{%1, %0|%0, %1}";
2171 return "%vmovd\t{%1, %0|%0, %1}";
2173 return "%vmovss\t{%1, %0|%0, %1}";
2179 return "pxor\t%0, %0";
2182 if (get_attr_mode (insn) == MODE_DI)
2183 return "movq\t{%1, %0|%0, %1}";
2184 return "movd\t{%1, %0|%0, %1}";
2187 return "lea{l}\t{%a1, %0|%0, %a1}";
2190 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2191 return "mov{l}\t{%1, %0|%0, %1}";
2195 (cond [(eq_attr "alternative" "2")
2196 (const_string "mmx")
2197 (eq_attr "alternative" "3,4,5")
2198 (const_string "mmxmov")
2199 (eq_attr "alternative" "6")
2200 (const_string "sselog1")
2201 (eq_attr "alternative" "7,8,9,10,11")
2202 (const_string "ssemov")
2203 (match_operand:DI 1 "pic_32bit_operand" "")
2204 (const_string "lea")
2206 (const_string "imov")))
2207 (set (attr "prefix")
2208 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2209 (const_string "orig")
2210 (const_string "maybe_vex")))
2211 (set (attr "prefix_data16")
2212 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2214 (const_string "*")))
2216 (cond [(eq_attr "alternative" "2,3")
2218 (eq_attr "alternative" "6,7")
2220 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2221 (const_string "V4SF")
2222 (const_string "TI"))
2223 (and (eq_attr "alternative" "8,9,10,11")
2224 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2227 (const_string "SI")))])
2229 (define_insn "*movhi_internal"
2230 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2231 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2232 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2234 switch (get_attr_type (insn))
2237 /* movzwl is faster than movw on p2 due to partial word stalls,
2238 though not as fast as an aligned movl. */
2239 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2241 if (get_attr_mode (insn) == MODE_SI)
2242 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2244 return "mov{w}\t{%1, %0|%0, %1}";
2248 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2250 (const_string "imov")
2251 (and (eq_attr "alternative" "0")
2252 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2254 (eq (symbol_ref "TARGET_HIMODE_MATH")
2256 (const_string "imov")
2257 (and (eq_attr "alternative" "1,2")
2258 (match_operand:HI 1 "aligned_operand" ""))
2259 (const_string "imov")
2260 (and (ne (symbol_ref "TARGET_MOVX")
2262 (eq_attr "alternative" "0,2"))
2263 (const_string "imovx")
2265 (const_string "imov")))
2267 (cond [(eq_attr "type" "imovx")
2269 (and (eq_attr "alternative" "1,2")
2270 (match_operand:HI 1 "aligned_operand" ""))
2272 (and (eq_attr "alternative" "0")
2273 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2275 (eq (symbol_ref "TARGET_HIMODE_MATH")
2279 (const_string "HI")))])
2281 ;; Situation is quite tricky about when to choose full sized (SImode) move
2282 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2283 ;; partial register dependency machines (such as AMD Athlon), where QImode
2284 ;; moves issue extra dependency and for partial register stalls machines
2285 ;; that don't use QImode patterns (and QImode move cause stall on the next
2288 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2289 ;; register stall machines with, where we use QImode instructions, since
2290 ;; partial register stall can be caused there. Then we use movzx.
2291 (define_insn "*movqi_internal"
2292 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2293 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2294 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2296 switch (get_attr_type (insn))
2299 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2300 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2302 if (get_attr_mode (insn) == MODE_SI)
2303 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2305 return "mov{b}\t{%1, %0|%0, %1}";
2309 (cond [(and (eq_attr "alternative" "5")
2310 (not (match_operand:QI 1 "aligned_operand" "")))
2311 (const_string "imovx")
2312 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2314 (const_string "imov")
2315 (and (eq_attr "alternative" "3")
2316 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2318 (eq (symbol_ref "TARGET_QIMODE_MATH")
2320 (const_string "imov")
2321 (eq_attr "alternative" "3,5")
2322 (const_string "imovx")
2323 (and (ne (symbol_ref "TARGET_MOVX")
2325 (eq_attr "alternative" "2"))
2326 (const_string "imovx")
2328 (const_string "imov")))
2330 (cond [(eq_attr "alternative" "3,4,5")
2332 (eq_attr "alternative" "6")
2334 (eq_attr "type" "imovx")
2336 (and (eq_attr "type" "imov")
2337 (and (eq_attr "alternative" "0,1")
2338 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2340 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2342 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2345 ;; Avoid partial register stalls when not using QImode arithmetic
2346 (and (eq_attr "type" "imov")
2347 (and (eq_attr "alternative" "0,1")
2348 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2350 (eq (symbol_ref "TARGET_QIMODE_MATH")
2354 (const_string "QI")))])
2356 ;; Stores and loads of ax to arbitrary constant address.
2357 ;; We fake an second form of instruction to force reload to load address
2358 ;; into register when rax is not available
2359 (define_insn "*movabs<mode>_1"
2360 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2361 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2362 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2364 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2365 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2366 [(set_attr "type" "imov")
2367 (set_attr "modrm" "0,*")
2368 (set_attr "length_address" "8,0")
2369 (set_attr "length_immediate" "0,*")
2370 (set_attr "memory" "store")
2371 (set_attr "mode" "<MODE>")])
2373 (define_insn "*movabs<mode>_2"
2374 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2375 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2376 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2378 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2379 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2380 [(set_attr "type" "imov")
2381 (set_attr "modrm" "0,*")
2382 (set_attr "length_address" "8,0")
2383 (set_attr "length_immediate" "0")
2384 (set_attr "memory" "load")
2385 (set_attr "mode" "<MODE>")])
2387 (define_insn "*swap<mode>"
2388 [(set (match_operand:SWI48 0 "register_operand" "+r")
2389 (match_operand:SWI48 1 "register_operand" "+r"))
2393 "xchg{<imodesuffix>}\t%1, %0"
2394 [(set_attr "type" "imov")
2395 (set_attr "mode" "<MODE>")
2396 (set_attr "pent_pair" "np")
2397 (set_attr "athlon_decode" "vector")
2398 (set_attr "amdfam10_decode" "double")
2399 (set_attr "bdver1_decode" "double")])
2401 (define_insn "*swap<mode>_1"
2402 [(set (match_operand:SWI12 0 "register_operand" "+r")
2403 (match_operand:SWI12 1 "register_operand" "+r"))
2406 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2408 [(set_attr "type" "imov")
2409 (set_attr "mode" "SI")
2410 (set_attr "pent_pair" "np")
2411 (set_attr "athlon_decode" "vector")
2412 (set_attr "amdfam10_decode" "double")
2413 (set_attr "bdver1_decode" "double")])
2415 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2416 ;; is disabled for AMDFAM10
2417 (define_insn "*swap<mode>_2"
2418 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2419 (match_operand:SWI12 1 "register_operand" "+<r>"))
2422 "TARGET_PARTIAL_REG_STALL"
2423 "xchg{<imodesuffix>}\t%1, %0"
2424 [(set_attr "type" "imov")
2425 (set_attr "mode" "<MODE>")
2426 (set_attr "pent_pair" "np")
2427 (set_attr "athlon_decode" "vector")])
2429 (define_expand "movstrict<mode>"
2430 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2431 (match_operand:SWI12 1 "general_operand" ""))]
2434 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2436 if (GET_CODE (operands[0]) == SUBREG
2437 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2439 /* Don't generate memory->memory moves, go through a register */
2440 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2441 operands[1] = force_reg (<MODE>mode, operands[1]);
2444 (define_insn "*movstrict<mode>_1"
2445 [(set (strict_low_part
2446 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2447 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2448 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2449 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2450 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2451 [(set_attr "type" "imov")
2452 (set_attr "mode" "<MODE>")])
2454 (define_insn "*movstrict<mode>_xor"
2455 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2456 (match_operand:SWI12 1 "const0_operand" ""))
2457 (clobber (reg:CC FLAGS_REG))]
2459 "xor{<imodesuffix>}\t%0, %0"
2460 [(set_attr "type" "alu1")
2461 (set_attr "mode" "<MODE>")
2462 (set_attr "length_immediate" "0")])
2464 (define_insn "*mov<mode>_extv_1"
2465 [(set (match_operand:SWI24 0 "register_operand" "=R")
2466 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2470 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2471 [(set_attr "type" "imovx")
2472 (set_attr "mode" "SI")])
2474 (define_insn "*movqi_extv_1_rex64"
2475 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2476 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2481 switch (get_attr_type (insn))
2484 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2486 return "mov{b}\t{%h1, %0|%0, %h1}";
2490 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2491 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2492 (ne (symbol_ref "TARGET_MOVX")
2494 (const_string "imovx")
2495 (const_string "imov")))
2497 (if_then_else (eq_attr "type" "imovx")
2499 (const_string "QI")))])
2501 (define_insn "*movqi_extv_1"
2502 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2503 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2508 switch (get_attr_type (insn))
2511 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2513 return "mov{b}\t{%h1, %0|%0, %h1}";
2517 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2518 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2519 (ne (symbol_ref "TARGET_MOVX")
2521 (const_string "imovx")
2522 (const_string "imov")))
2524 (if_then_else (eq_attr "type" "imovx")
2526 (const_string "QI")))])
2528 (define_insn "*mov<mode>_extzv_1"
2529 [(set (match_operand:SWI48 0 "register_operand" "=R")
2530 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2534 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535 [(set_attr "type" "imovx")
2536 (set_attr "mode" "SI")])
2538 (define_insn "*movqi_extzv_2_rex64"
2539 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2541 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2546 switch (get_attr_type (insn))
2549 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2551 return "mov{b}\t{%h1, %0|%0, %h1}";
2555 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2556 (ne (symbol_ref "TARGET_MOVX")
2558 (const_string "imovx")
2559 (const_string "imov")))
2561 (if_then_else (eq_attr "type" "imovx")
2563 (const_string "QI")))])
2565 (define_insn "*movqi_extzv_2"
2566 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2568 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2573 switch (get_attr_type (insn))
2576 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2578 return "mov{b}\t{%h1, %0|%0, %h1}";
2582 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2583 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2584 (ne (symbol_ref "TARGET_MOVX")
2586 (const_string "imovx")
2587 (const_string "imov")))
2589 (if_then_else (eq_attr "type" "imovx")
2591 (const_string "QI")))])
2593 (define_expand "mov<mode>_insv_1"
2594 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2597 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2599 (define_insn "*mov<mode>_insv_1_rex64"
2600 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2603 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2605 "mov{b}\t{%b1, %h0|%h0, %b1}"
2606 [(set_attr "type" "imov")
2607 (set_attr "mode" "QI")])
2609 (define_insn "*movsi_insv_1"
2610 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2613 (match_operand:SI 1 "general_operand" "Qmn"))]
2615 "mov{b}\t{%b1, %h0|%h0, %b1}"
2616 [(set_attr "type" "imov")
2617 (set_attr "mode" "QI")])
2619 (define_insn "*movqi_insv_2"
2620 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2623 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2626 "mov{b}\t{%h1, %h0|%h0, %h1}"
2627 [(set_attr "type" "imov")
2628 (set_attr "mode" "QI")])
2630 ;; Floating point push instructions.
2632 (define_insn "*pushtf"
2633 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2634 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2637 /* This insn should be already split before reg-stack. */
2640 [(set_attr "type" "multi")
2641 (set_attr "unit" "sse,*,*")
2642 (set_attr "mode" "TF,SI,SI")])
2645 [(set (match_operand:TF 0 "push_operand" "")
2646 (match_operand:TF 1 "sse_reg_operand" ""))]
2647 "TARGET_SSE2 && reload_completed"
2648 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2649 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2652 [(set (match_operand:TF 0 "push_operand" "")
2653 (match_operand:TF 1 "general_operand" ""))]
2654 "TARGET_SSE2 && reload_completed
2655 && !SSE_REG_P (operands[1])"
2657 "ix86_split_long_move (operands); DONE;")
2659 (define_insn "*pushxf"
2660 [(set (match_operand:XF 0 "push_operand" "=<,<")
2661 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2662 "optimize_function_for_speed_p (cfun)"
2664 /* This insn should be already split before reg-stack. */
2667 [(set_attr "type" "multi")
2668 (set_attr "unit" "i387,*")
2669 (set_attr "mode" "XF,SI")])
2671 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2672 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2673 ;; Pushing using integer instructions is longer except for constants
2674 ;; and direct memory references (assuming that any given constant is pushed
2675 ;; only once, but this ought to be handled elsewhere).
2677 (define_insn "*pushxf_nointeger"
2678 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2679 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2680 "optimize_function_for_size_p (cfun)"
2682 /* This insn should be already split before reg-stack. */
2685 [(set_attr "type" "multi")
2686 (set_attr "unit" "i387,*,*")
2687 (set_attr "mode" "XF,SI,SI")])
2690 [(set (match_operand:XF 0 "push_operand" "")
2691 (match_operand:XF 1 "fp_register_operand" ""))]
2693 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2694 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2695 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2698 [(set (match_operand:XF 0 "push_operand" "")
2699 (match_operand:XF 1 "general_operand" ""))]
2701 && !FP_REG_P (operands[1])"
2703 "ix86_split_long_move (operands); DONE;")
2705 (define_insn "*pushdf"
2706 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2707 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2708 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2710 /* This insn should be already split before reg-stack. */
2713 [(set_attr "type" "multi")
2714 (set_attr "unit" "i387,*,*")
2715 (set_attr "mode" "DF,SI,DF")])
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2719 ;; On the average, pushdf using integers can be still shorter. Allow this
2720 ;; pattern for optimize_size too.
2722 (define_insn "*pushdf_nointeger"
2723 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2724 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2725 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2727 /* This insn should be already split before reg-stack. */
2730 [(set_attr "type" "multi")
2731 (set_attr "unit" "i387,*,*,*")
2732 (set_attr "mode" "DF,SI,SI,DF")])
2734 ;; %%% Kill this when call knows how to work this out.
2736 [(set (match_operand:DF 0 "push_operand" "")
2737 (match_operand:DF 1 "any_fp_register_operand" ""))]
2739 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2740 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2743 [(set (match_operand:DF 0 "push_operand" "")
2744 (match_operand:DF 1 "general_operand" ""))]
2746 && !ANY_FP_REG_P (operands[1])"
2748 "ix86_split_long_move (operands); DONE;")
2750 (define_insn "*pushsf_rex64"
2751 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2752 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2755 /* Anything else should be already split before reg-stack. */
2756 gcc_assert (which_alternative == 1);
2757 return "push{q}\t%q1";
2759 [(set_attr "type" "multi,push,multi")
2760 (set_attr "unit" "i387,*,*")
2761 (set_attr "mode" "SF,DI,SF")])
2763 (define_insn "*pushsf"
2764 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2765 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2768 /* Anything else should be already split before reg-stack. */
2769 gcc_assert (which_alternative == 1);
2770 return "push{l}\t%1";
2772 [(set_attr "type" "multi,push,multi")
2773 (set_attr "unit" "i387,*,*")
2774 (set_attr "mode" "SF,SI,SF")])
2777 [(set (match_operand:SF 0 "push_operand" "")
2778 (match_operand:SF 1 "memory_operand" ""))]
2780 && MEM_P (operands[1])
2781 && (operands[2] = find_constant_src (insn))"
2785 ;; %%% Kill this when call knows how to work this out.
2787 [(set (match_operand:SF 0 "push_operand" "")
2788 (match_operand:SF 1 "any_fp_register_operand" ""))]
2790 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2791 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2792 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2794 ;; Floating point move instructions.
2796 (define_expand "movtf"
2797 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2798 (match_operand:TF 1 "nonimmediate_operand" ""))]
2801 ix86_expand_move (TFmode, operands);
2805 (define_expand "mov<mode>"
2806 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2807 (match_operand:X87MODEF 1 "general_operand" ""))]
2809 "ix86_expand_move (<MODE>mode, operands); DONE;")
2811 (define_insn "*movtf_internal"
2812 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2813 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2815 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2817 switch (which_alternative)
2821 if (get_attr_mode (insn) == MODE_V4SF)
2822 return "%vmovaps\t{%1, %0|%0, %1}";
2824 return "%vmovdqa\t{%1, %0|%0, %1}";
2826 if (get_attr_mode (insn) == MODE_V4SF)
2827 return "%vxorps\t%0, %d0";
2829 return "%vpxor\t%0, %d0";
2837 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2838 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2840 (cond [(eq_attr "alternative" "0,2")
2842 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2844 (const_string "V4SF")
2845 (const_string "TI"))
2846 (eq_attr "alternative" "1")
2848 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2850 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2852 (const_string "V4SF")
2853 (const_string "TI"))]
2854 (const_string "DI")))])
2857 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2858 (match_operand:TF 1 "general_operand" ""))]
2860 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2862 "ix86_split_long_move (operands); DONE;")
2864 (define_insn "*movxf_internal"
2865 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2866 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2867 "optimize_function_for_speed_p (cfun)
2868 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2869 && (reload_in_progress || reload_completed
2870 || GET_CODE (operands[1]) != CONST_DOUBLE
2871 || memory_operand (operands[0], XFmode))"
2873 switch (which_alternative)
2877 return output_387_reg_move (insn, operands);
2880 return standard_80387_constant_opcode (operands[1]);
2889 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2890 (set_attr "mode" "XF,XF,XF,SI,SI")])
2892 ;; Do not use integer registers when optimizing for size
2893 (define_insn "*movxf_internal_nointeger"
2894 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2895 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2896 "optimize_function_for_size_p (cfun)
2897 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2898 && (reload_in_progress || reload_completed
2899 || standard_80387_constant_p (operands[1])
2900 || GET_CODE (operands[1]) != CONST_DOUBLE
2901 || memory_operand (operands[0], XFmode))"
2903 switch (which_alternative)
2907 return output_387_reg_move (insn, operands);
2910 return standard_80387_constant_opcode (operands[1]);
2918 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2919 (set_attr "mode" "XF,XF,XF,SI,SI")])
2922 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2923 (match_operand:XF 1 "general_operand" ""))]
2925 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2926 && ! (FP_REG_P (operands[0]) ||
2927 (GET_CODE (operands[0]) == SUBREG
2928 && FP_REG_P (SUBREG_REG (operands[0]))))
2929 && ! (FP_REG_P (operands[1]) ||
2930 (GET_CODE (operands[1]) == SUBREG
2931 && FP_REG_P (SUBREG_REG (operands[1]))))"
2933 "ix86_split_long_move (operands); DONE;")
2935 (define_insn "*movdf_internal_rex64"
2936 [(set (match_operand:DF 0 "nonimmediate_operand"
2937 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2938 (match_operand:DF 1 "general_operand"
2939 "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2940 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2941 && (reload_in_progress || reload_completed
2942 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2943 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2944 && optimize_function_for_size_p (cfun)
2945 && standard_80387_constant_p (operands[1]))
2946 || GET_CODE (operands[1]) != CONST_DOUBLE
2947 || memory_operand (operands[0], DFmode))"
2949 switch (which_alternative)
2953 return output_387_reg_move (insn, operands);
2956 return standard_80387_constant_opcode (operands[1]);
2960 return "mov{q}\t{%1, %0|%0, %1}";
2963 return "movabs{q}\t{%1, %0|%0, %1}";
2969 switch (get_attr_mode (insn))
2972 return "%vxorps\t%0, %d0";
2974 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2975 return "%vxorps\t%0, %d0";
2977 return "%vxorpd\t%0, %d0";
2979 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2980 return "%vxorps\t%0, %d0";
2982 return "%vpxor\t%0, %d0";
2989 switch (get_attr_mode (insn))
2992 return "%vmovaps\t{%1, %0|%0, %1}";
2994 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2995 return "%vmovaps\t{%1, %0|%0, %1}";
2997 return "%vmovapd\t{%1, %0|%0, %1}";
2999 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3000 return "%vmovaps\t{%1, %0|%0, %1}";
3002 return "%vmovdqa\t{%1, %0|%0, %1}";
3004 return "%vmovq\t{%1, %0|%0, %1}";
3008 if (REG_P (operands[0]) && REG_P (operands[1]))
3009 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3011 return "vmovsd\t{%1, %0|%0, %1}";
3014 return "movsd\t{%1, %0|%0, %1}";
3016 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3018 return "%vmovlps\t{%1, %d0|%d0, %1}";
3025 return "%vmovd\t{%1, %0|%0, %1}";
3031 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3034 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3036 (const_string "*")))
3037 (set (attr "length_immediate")
3039 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3041 (const_string "*")))
3042 (set (attr "prefix")
3043 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3044 (const_string "orig")
3045 (const_string "maybe_vex")))
3046 (set (attr "prefix_data16")
3047 (if_then_else (eq_attr "mode" "V1DF")
3049 (const_string "*")))
3051 (cond [(eq_attr "alternative" "0,1,2")
3053 (eq_attr "alternative" "3,4,5,6,11,12")
3056 /* For SSE1, we have many fewer alternatives. */
3057 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3058 (cond [(eq_attr "alternative" "7,8")
3059 (const_string "V4SF")
3061 (const_string "V2SF"))
3063 /* xorps is one byte shorter. */
3064 (eq_attr "alternative" "7")
3065 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3067 (const_string "V4SF")
3068 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3072 (const_string "V2DF"))
3074 /* For architectures resolving dependencies on
3075 whole SSE registers use APD move to break dependency
3076 chains, otherwise use short move to avoid extra work.
3078 movaps encodes one byte shorter. */
3079 (eq_attr "alternative" "8")
3081 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3083 (const_string "V4SF")
3084 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3086 (const_string "V2DF")
3088 (const_string "DF"))
3089 /* For architectures resolving dependencies on register
3090 parts we may avoid extra work to zero out upper part
3092 (eq_attr "alternative" "9")
3094 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3096 (const_string "V1DF")
3097 (const_string "DF"))
3099 (const_string "DF")))])
3101 (define_insn "*movdf_internal"
3102 [(set (match_operand:DF 0 "nonimmediate_operand"
3103 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3104 (match_operand:DF 1 "general_operand"
3105 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3106 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3107 && optimize_function_for_speed_p (cfun)
3108 && TARGET_INTEGER_DFMODE_MOVES
3109 && (reload_in_progress || reload_completed
3110 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3111 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3112 && optimize_function_for_size_p (cfun)
3113 && standard_80387_constant_p (operands[1]))
3114 || GET_CODE (operands[1]) != CONST_DOUBLE
3115 || memory_operand (operands[0], DFmode))"
3117 switch (which_alternative)
3121 return output_387_reg_move (insn, operands);
3124 return standard_80387_constant_opcode (operands[1]);
3131 switch (get_attr_mode (insn))
3134 return "xorps\t%0, %0";
3136 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3137 return "xorps\t%0, %0";
3139 return "xorpd\t%0, %0";
3141 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3142 return "xorps\t%0, %0";
3144 return "pxor\t%0, %0";
3151 switch (get_attr_mode (insn))
3154 return "movaps\t{%1, %0|%0, %1}";
3156 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3157 return "movaps\t{%1, %0|%0, %1}";
3159 return "movapd\t{%1, %0|%0, %1}";
3161 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3162 return "movaps\t{%1, %0|%0, %1}";
3164 return "movdqa\t{%1, %0|%0, %1}";
3166 return "movq\t{%1, %0|%0, %1}";
3168 return "movsd\t{%1, %0|%0, %1}";
3170 return "movlpd\t{%1, %0|%0, %1}";
3172 return "movlps\t{%1, %0|%0, %1}";
3181 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3182 (set (attr "prefix_data16")
3183 (if_then_else (eq_attr "mode" "V1DF")
3185 (const_string "*")))
3187 (cond [(eq_attr "alternative" "0,1,2")
3189 (eq_attr "alternative" "3,4")
3192 /* For SSE1, we have many fewer alternatives. */
3193 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3194 (cond [(eq_attr "alternative" "5,6")
3195 (const_string "V4SF")
3197 (const_string "V2SF"))
3199 /* xorps is one byte shorter. */
3200 (eq_attr "alternative" "5")
3201 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3203 (const_string "V4SF")
3204 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3208 (const_string "V2DF"))
3210 /* For architectures resolving dependencies on
3211 whole SSE registers use APD move to break dependency
3212 chains, otherwise use short move to avoid extra work.
3214 movaps encodes one byte shorter. */
3215 (eq_attr "alternative" "6")
3217 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3219 (const_string "V4SF")
3220 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3222 (const_string "V2DF")
3224 (const_string "DF"))
3225 /* For architectures resolving dependencies on register
3226 parts we may avoid extra work to zero out upper part
3228 (eq_attr "alternative" "7")
3230 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3232 (const_string "V1DF")
3233 (const_string "DF"))
3235 (const_string "DF")))])
3237 ;; Moving is usually shorter when only FP registers are used. This separate
3238 ;; movdf pattern avoids the use of integer registers for FP operations
3239 ;; when optimizing for size.
3241 (define_insn "*movdf_internal_nointeger"
3242 [(set (match_operand:DF 0 "nonimmediate_operand"
3243 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3244 (match_operand:DF 1 "general_operand"
3245 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3246 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3247 && (optimize_function_for_size_p (cfun)
3248 || !TARGET_INTEGER_DFMODE_MOVES)
3249 && (reload_in_progress || reload_completed
3250 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3251 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3252 && optimize_function_for_size_p (cfun)
3253 && !memory_operand (operands[0], DFmode)
3254 && standard_80387_constant_p (operands[1]))
3255 || GET_CODE (operands[1]) != CONST_DOUBLE
3256 || ((optimize_function_for_size_p (cfun)
3257 || !TARGET_MEMORY_MISMATCH_STALL
3258 || reload_in_progress || reload_completed)
3259 && memory_operand (operands[0], DFmode)))"
3261 switch (which_alternative)
3265 return output_387_reg_move (insn, operands);
3268 return standard_80387_constant_opcode (operands[1]);
3275 switch (get_attr_mode (insn))
3278 return "%vxorps\t%0, %d0";
3280 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3281 return "%vxorps\t%0, %d0";
3283 return "%vxorpd\t%0, %d0";
3285 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3286 return "%vxorps\t%0, %d0";
3288 return "%vpxor\t%0, %d0";
3295 switch (get_attr_mode (insn))
3298 return "%vmovaps\t{%1, %0|%0, %1}";
3300 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3301 return "%vmovaps\t{%1, %0|%0, %1}";
3303 return "%vmovapd\t{%1, %0|%0, %1}";
3305 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3306 return "%vmovaps\t{%1, %0|%0, %1}";
3308 return "%vmovdqa\t{%1, %0|%0, %1}";
3310 return "%vmovq\t{%1, %0|%0, %1}";
3314 if (REG_P (operands[0]) && REG_P (operands[1]))
3315 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3317 return "vmovsd\t{%1, %0|%0, %1}";
3320 return "movsd\t{%1, %0|%0, %1}";
3324 if (REG_P (operands[0]))
3325 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3327 return "vmovlpd\t{%1, %0|%0, %1}";
3330 return "movlpd\t{%1, %0|%0, %1}";
3334 if (REG_P (operands[0]))
3335 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3337 return "vmovlps\t{%1, %0|%0, %1}";
3340 return "movlps\t{%1, %0|%0, %1}";
3349 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3350 (set (attr "prefix")
3351 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3352 (const_string "orig")
3353 (const_string "maybe_vex")))
3354 (set (attr "prefix_data16")
3355 (if_then_else (eq_attr "mode" "V1DF")
3357 (const_string "*")))
3359 (cond [(eq_attr "alternative" "0,1,2")
3361 (eq_attr "alternative" "3,4")
3364 /* For SSE1, we have many fewer alternatives. */
3365 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3366 (cond [(eq_attr "alternative" "5,6")
3367 (const_string "V4SF")
3369 (const_string "V2SF"))
3371 /* xorps is one byte shorter. */
3372 (eq_attr "alternative" "5")
3373 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3375 (const_string "V4SF")
3376 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3380 (const_string "V2DF"))
3382 /* For architectures resolving dependencies on
3383 whole SSE registers use APD move to break dependency
3384 chains, otherwise use short move to avoid extra work.
3386 movaps encodes one byte shorter. */
3387 (eq_attr "alternative" "6")
3389 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3391 (const_string "V4SF")
3392 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3394 (const_string "V2DF")
3396 (const_string "DF"))
3397 /* For architectures resolving dependencies on register
3398 parts we may avoid extra work to zero out upper part
3400 (eq_attr "alternative" "7")
3402 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3404 (const_string "V1DF")
3405 (const_string "DF"))
3407 (const_string "DF")))])
3410 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3411 (match_operand:DF 1 "general_operand" ""))]
3413 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3414 && ! (ANY_FP_REG_P (operands[0]) ||
3415 (GET_CODE (operands[0]) == SUBREG
3416 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3417 && ! (ANY_FP_REG_P (operands[1]) ||
3418 (GET_CODE (operands[1]) == SUBREG
3419 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3421 "ix86_split_long_move (operands); DONE;")
3423 (define_insn "*movsf_internal"
3424 [(set (match_operand:SF 0 "nonimmediate_operand"
3425 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3426 (match_operand:SF 1 "general_operand"
3427 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3428 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3429 && (reload_in_progress || reload_completed
3430 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3431 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3432 && standard_80387_constant_p (operands[1]))
3433 || GET_CODE (operands[1]) != CONST_DOUBLE
3434 || memory_operand (operands[0], SFmode))"
3436 switch (which_alternative)
3440 return output_387_reg_move (insn, operands);
3443 return standard_80387_constant_opcode (operands[1]);
3447 return "mov{l}\t{%1, %0|%0, %1}";
3449 if (get_attr_mode (insn) == MODE_TI)
3450 return "%vpxor\t%0, %d0";
3452 return "%vxorps\t%0, %d0";
3454 if (get_attr_mode (insn) == MODE_V4SF)
3455 return "%vmovaps\t{%1, %0|%0, %1}";
3457 return "%vmovss\t{%1, %d0|%d0, %1}";
3460 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3461 : "vmovss\t{%1, %0|%0, %1}";
3463 return "movss\t{%1, %0|%0, %1}";
3465 return "%vmovss\t{%1, %0|%0, %1}";
3467 case 9: case 10: case 14: case 15:
3468 return "movd\t{%1, %0|%0, %1}";
3470 return "%vmovd\t{%1, %0|%0, %1}";
3473 return "movq\t{%1, %0|%0, %1}";
3479 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3480 (set (attr "prefix")
3481 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3482 (const_string "maybe_vex")
3483 (const_string "orig")))
3485 (cond [(eq_attr "alternative" "3,4,9,10")
3487 (eq_attr "alternative" "5")
3489 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3491 (ne (symbol_ref "TARGET_SSE2")
3493 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3496 (const_string "V4SF"))
3497 /* For architectures resolving dependencies on
3498 whole SSE registers use APS move to break dependency
3499 chains, otherwise use short move to avoid extra work.
3501 Do the same for architectures resolving dependencies on
3502 the parts. While in DF mode it is better to always handle
3503 just register parts, the SF mode is different due to lack
3504 of instructions to load just part of the register. It is
3505 better to maintain the whole registers in single format
3506 to avoid problems on using packed logical operations. */
3507 (eq_attr "alternative" "6")
3509 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3511 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3513 (const_string "V4SF")
3514 (const_string "SF"))
3515 (eq_attr "alternative" "11")
3516 (const_string "DI")]
3517 (const_string "SF")))])
3520 [(set (match_operand 0 "register_operand" "")
3521 (match_operand 1 "memory_operand" ""))]
3523 && MEM_P (operands[1])
3524 && (GET_MODE (operands[0]) == TFmode
3525 || GET_MODE (operands[0]) == XFmode
3526 || GET_MODE (operands[0]) == DFmode
3527 || GET_MODE (operands[0]) == SFmode)
3528 && (operands[2] = find_constant_src (insn))"
3529 [(set (match_dup 0) (match_dup 2))]
3531 rtx c = operands[2];
3532 rtx r = operands[0];
3534 if (GET_CODE (r) == SUBREG)
3539 if (!standard_sse_constant_p (c))
3542 else if (FP_REG_P (r))
3544 if (!standard_80387_constant_p (c))
3547 else if (MMX_REG_P (r))
3552 [(set (match_operand 0 "register_operand" "")
3553 (float_extend (match_operand 1 "memory_operand" "")))]
3555 && MEM_P (operands[1])
3556 && (GET_MODE (operands[0]) == TFmode
3557 || GET_MODE (operands[0]) == XFmode
3558 || GET_MODE (operands[0]) == DFmode
3559 || GET_MODE (operands[0]) == SFmode)
3560 && (operands[2] = find_constant_src (insn))"
3561 [(set (match_dup 0) (match_dup 2))]
3563 rtx c = operands[2];
3564 rtx r = operands[0];
3566 if (GET_CODE (r) == SUBREG)
3571 if (!standard_sse_constant_p (c))
3574 else if (FP_REG_P (r))
3576 if (!standard_80387_constant_p (c))
3579 else if (MMX_REG_P (r))
3583 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3585 [(set (match_operand:X87MODEF 0 "register_operand" "")
3586 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3587 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3588 && (standard_80387_constant_p (operands[1]) == 8
3589 || standard_80387_constant_p (operands[1]) == 9)"
3590 [(set (match_dup 0)(match_dup 1))
3592 (neg:X87MODEF (match_dup 0)))]
3596 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3597 if (real_isnegzero (&r))
3598 operands[1] = CONST0_RTX (<MODE>mode);
3600 operands[1] = CONST1_RTX (<MODE>mode);
3603 (define_insn "swapxf"
3604 [(set (match_operand:XF 0 "register_operand" "+f")
3605 (match_operand:XF 1 "register_operand" "+f"))
3610 if (STACK_TOP_P (operands[0]))
3615 [(set_attr "type" "fxch")
3616 (set_attr "mode" "XF")])
3618 (define_insn "*swap<mode>"
3619 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3620 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3623 "TARGET_80387 || reload_completed"
3625 if (STACK_TOP_P (operands[0]))
3630 [(set_attr "type" "fxch")
3631 (set_attr "mode" "<MODE>")])
3633 ;; Zero extension instructions
3635 (define_expand "zero_extendsidi2"
3636 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3637 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3642 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3647 (define_insn "*zero_extendsidi2_rex64"
3648 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3650 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3653 mov\t{%k1, %k0|%k0, %k1}
3655 movd\t{%1, %0|%0, %1}
3656 movd\t{%1, %0|%0, %1}
3657 %vmovd\t{%1, %0|%0, %1}
3658 %vmovd\t{%1, %0|%0, %1}"
3659 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3660 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3661 (set_attr "prefix_0f" "0,*,*,*,*,*")
3662 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3665 [(set (match_operand:DI 0 "memory_operand" "")
3666 (zero_extend:DI (match_dup 0)))]
3668 [(set (match_dup 4) (const_int 0))]
3669 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3671 ;; %%% Kill me once multi-word ops are sane.
3672 (define_insn "zero_extendsidi2_1"
3673 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3675 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3676 (clobber (reg:CC FLAGS_REG))]
3682 movd\t{%1, %0|%0, %1}
3683 movd\t{%1, %0|%0, %1}
3684 %vmovd\t{%1, %0|%0, %1}
3685 %vmovd\t{%1, %0|%0, %1}"
3686 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3687 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3688 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3691 [(set (match_operand:DI 0 "register_operand" "")
3692 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3693 (clobber (reg:CC FLAGS_REG))]
3694 "!TARGET_64BIT && reload_completed
3695 && true_regnum (operands[0]) == true_regnum (operands[1])"
3696 [(set (match_dup 4) (const_int 0))]
3697 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3700 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3701 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3702 (clobber (reg:CC FLAGS_REG))]
3703 "!TARGET_64BIT && reload_completed
3704 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3705 [(set (match_dup 3) (match_dup 1))
3706 (set (match_dup 4) (const_int 0))]
3707 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3709 (define_insn "zero_extend<mode>di2"
3710 [(set (match_operand:DI 0 "register_operand" "=r")
3712 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3714 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3715 [(set_attr "type" "imovx")
3716 (set_attr "mode" "SI")])
3718 (define_expand "zero_extendhisi2"
3719 [(set (match_operand:SI 0 "register_operand" "")
3720 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3723 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3725 operands[1] = force_reg (HImode, operands[1]);
3726 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3731 (define_insn_and_split "zero_extendhisi2_and"
3732 [(set (match_operand:SI 0 "register_operand" "=r")
3733 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3734 (clobber (reg:CC FLAGS_REG))]
3735 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3737 "&& reload_completed"
3738 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3739 (clobber (reg:CC FLAGS_REG))])]
3741 [(set_attr "type" "alu1")
3742 (set_attr "mode" "SI")])
3744 (define_insn "*zero_extendhisi2_movzwl"
3745 [(set (match_operand:SI 0 "register_operand" "=r")
3746 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3747 "!TARGET_ZERO_EXTEND_WITH_AND
3748 || optimize_function_for_size_p (cfun)"
3749 "movz{wl|x}\t{%1, %0|%0, %1}"
3750 [(set_attr "type" "imovx")
3751 (set_attr "mode" "SI")])
3753 (define_expand "zero_extendqi<mode>2"
3755 [(set (match_operand:SWI24 0 "register_operand" "")
3756 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3757 (clobber (reg:CC FLAGS_REG))])])
3759 (define_insn "*zero_extendqi<mode>2_and"
3760 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3761 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3762 (clobber (reg:CC FLAGS_REG))]
3763 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3765 [(set_attr "type" "alu1")
3766 (set_attr "mode" "<MODE>")])
3768 ;; When source and destination does not overlap, clear destination
3769 ;; first and then do the movb
3771 [(set (match_operand:SWI24 0 "register_operand" "")
3772 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3773 (clobber (reg:CC FLAGS_REG))]
3775 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3776 && ANY_QI_REG_P (operands[0])
3777 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3778 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3779 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3781 operands[2] = gen_lowpart (QImode, operands[0]);
3782 ix86_expand_clear (operands[0]);
3785 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3786 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3787 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3788 (clobber (reg:CC FLAGS_REG))]
3789 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3791 [(set_attr "type" "imovx,alu1")
3792 (set_attr "mode" "<MODE>")])
3794 ;; For the movzbl case strip only the clobber
3796 [(set (match_operand:SWI24 0 "register_operand" "")
3797 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3798 (clobber (reg:CC FLAGS_REG))]
3800 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3801 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3803 (zero_extend:SWI24 (match_dup 1)))])
3805 ; zero extend to SImode to avoid partial register stalls
3806 (define_insn "*zero_extendqi<mode>2_movzbl"
3807 [(set (match_operand:SWI24 0 "register_operand" "=r")
3808 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3810 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3811 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3812 [(set_attr "type" "imovx")
3813 (set_attr "mode" "SI")])
3815 ;; Rest is handled by single and.
3817 [(set (match_operand:SWI24 0 "register_operand" "")
3818 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3819 (clobber (reg:CC FLAGS_REG))]
3821 && true_regnum (operands[0]) == true_regnum (operands[1])"
3822 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3823 (clobber (reg:CC FLAGS_REG))])])
3825 ;; Sign extension instructions
3827 (define_expand "extendsidi2"
3828 [(set (match_operand:DI 0 "register_operand" "")
3829 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3834 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3839 (define_insn "*extendsidi2_rex64"
3840 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3841 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3845 movs{lq|x}\t{%1, %0|%0, %1}"
3846 [(set_attr "type" "imovx")
3847 (set_attr "mode" "DI")
3848 (set_attr "prefix_0f" "0")
3849 (set_attr "modrm" "0,1")])
3851 (define_insn "extendsidi2_1"
3852 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3853 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3854 (clobber (reg:CC FLAGS_REG))
3855 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3859 ;; Extend to memory case when source register does die.
3861 [(set (match_operand:DI 0 "memory_operand" "")
3862 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3863 (clobber (reg:CC FLAGS_REG))
3864 (clobber (match_operand:SI 2 "register_operand" ""))]
3866 && dead_or_set_p (insn, operands[1])
3867 && !reg_mentioned_p (operands[1], operands[0]))"
3868 [(set (match_dup 3) (match_dup 1))
3869 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3870 (clobber (reg:CC FLAGS_REG))])
3871 (set (match_dup 4) (match_dup 1))]
3872 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3874 ;; Extend to memory case when source register does not die.
3876 [(set (match_operand:DI 0 "memory_operand" "")
3877 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3878 (clobber (reg:CC FLAGS_REG))
3879 (clobber (match_operand:SI 2 "register_operand" ""))]
3883 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3885 emit_move_insn (operands[3], operands[1]);
3887 /* Generate a cltd if possible and doing so it profitable. */
3888 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3889 && true_regnum (operands[1]) == AX_REG
3890 && true_regnum (operands[2]) == DX_REG)
3892 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3896 emit_move_insn (operands[2], operands[1]);
3897 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3899 emit_move_insn (operands[4], operands[2]);
3903 ;; Extend to register case. Optimize case where source and destination
3904 ;; registers match and cases where we can use cltd.
3906 [(set (match_operand:DI 0 "register_operand" "")
3907 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3908 (clobber (reg:CC FLAGS_REG))
3909 (clobber (match_scratch:SI 2 ""))]
3913 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3915 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3916 emit_move_insn (operands[3], operands[1]);
3918 /* Generate a cltd if possible and doing so it profitable. */
3919 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3920 && true_regnum (operands[3]) == AX_REG
3921 && true_regnum (operands[4]) == DX_REG)
3923 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3927 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3928 emit_move_insn (operands[4], operands[1]);
3930 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3934 (define_insn "extend<mode>di2"
3935 [(set (match_operand:DI 0 "register_operand" "=r")
3937 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3939 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3940 [(set_attr "type" "imovx")
3941 (set_attr "mode" "DI")])
3943 (define_insn "extendhisi2"
3944 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3945 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3948 switch (get_attr_prefix_0f (insn))
3951 return "{cwtl|cwde}";
3953 return "movs{wl|x}\t{%1, %0|%0, %1}";
3956 [(set_attr "type" "imovx")
3957 (set_attr "mode" "SI")
3958 (set (attr "prefix_0f")
3959 ;; movsx is short decodable while cwtl is vector decoded.
3960 (if_then_else (and (eq_attr "cpu" "!k6")
3961 (eq_attr "alternative" "0"))
3963 (const_string "1")))
3965 (if_then_else (eq_attr "prefix_0f" "0")
3967 (const_string "1")))])
3969 (define_insn "*extendhisi2_zext"
3970 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3973 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3976 switch (get_attr_prefix_0f (insn))
3979 return "{cwtl|cwde}";
3981 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3984 [(set_attr "type" "imovx")
3985 (set_attr "mode" "SI")
3986 (set (attr "prefix_0f")
3987 ;; movsx is short decodable while cwtl is vector decoded.
3988 (if_then_else (and (eq_attr "cpu" "!k6")
3989 (eq_attr "alternative" "0"))
3991 (const_string "1")))
3993 (if_then_else (eq_attr "prefix_0f" "0")
3995 (const_string "1")))])
3997 (define_insn "extendqisi2"
3998 [(set (match_operand:SI 0 "register_operand" "=r")
3999 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4001 "movs{bl|x}\t{%1, %0|%0, %1}"
4002 [(set_attr "type" "imovx")
4003 (set_attr "mode" "SI")])
4005 (define_insn "*extendqisi2_zext"
4006 [(set (match_operand:DI 0 "register_operand" "=r")
4008 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4010 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4011 [(set_attr "type" "imovx")
4012 (set_attr "mode" "SI")])
4014 (define_insn "extendqihi2"
4015 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4016 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4019 switch (get_attr_prefix_0f (insn))
4022 return "{cbtw|cbw}";
4024 return "movs{bw|x}\t{%1, %0|%0, %1}";
4027 [(set_attr "type" "imovx")
4028 (set_attr "mode" "HI")
4029 (set (attr "prefix_0f")
4030 ;; movsx is short decodable while cwtl is vector decoded.
4031 (if_then_else (and (eq_attr "cpu" "!k6")
4032 (eq_attr "alternative" "0"))
4034 (const_string "1")))
4036 (if_then_else (eq_attr "prefix_0f" "0")
4038 (const_string "1")))])
4040 ;; Conversions between float and double.
4042 ;; These are all no-ops in the model used for the 80387.
4043 ;; So just emit moves.
4045 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4047 [(set (match_operand:DF 0 "push_operand" "")
4048 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4050 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4051 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4054 [(set (match_operand:XF 0 "push_operand" "")
4055 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4057 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4058 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4059 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4061 (define_expand "extendsfdf2"
4062 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4063 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4064 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4066 /* ??? Needed for compress_float_constant since all fp constants
4067 are TARGET_LEGITIMATE_CONSTANT_P. */
4068 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4070 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4071 && standard_80387_constant_p (operands[1]) > 0)
4073 operands[1] = simplify_const_unary_operation
4074 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4075 emit_move_insn_1 (operands[0], operands[1]);
4078 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4082 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4084 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4086 We do the conversion post reload to avoid producing of 128bit spills
4087 that might lead to ICE on 32bit target. The sequence unlikely combine
4090 [(set (match_operand:DF 0 "register_operand" "")
4092 (match_operand:SF 1 "nonimmediate_operand" "")))]
4093 "TARGET_USE_VECTOR_FP_CONVERTS
4094 && optimize_insn_for_speed_p ()
4095 && reload_completed && SSE_REG_P (operands[0])"
4100 (parallel [(const_int 0) (const_int 1)]))))]
4102 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4103 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4104 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4105 Try to avoid move when unpacking can be done in source. */
4106 if (REG_P (operands[1]))
4108 /* If it is unsafe to overwrite upper half of source, we need
4109 to move to destination and unpack there. */
4110 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4111 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4112 && true_regnum (operands[0]) != true_regnum (operands[1]))
4114 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4115 emit_move_insn (tmp, operands[1]);
4118 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4119 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4123 emit_insn (gen_vec_setv4sf_0 (operands[3],
4124 CONST0_RTX (V4SFmode), operands[1]));
4127 (define_insn "*extendsfdf2_mixed"
4128 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4130 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4131 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4133 switch (which_alternative)
4137 return output_387_reg_move (insn, operands);
4140 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4146 [(set_attr "type" "fmov,fmov,ssecvt")
4147 (set_attr "prefix" "orig,orig,maybe_vex")
4148 (set_attr "mode" "SF,XF,DF")])
4150 (define_insn "*extendsfdf2_sse"
4151 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4152 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4153 "TARGET_SSE2 && TARGET_SSE_MATH"
4154 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4155 [(set_attr "type" "ssecvt")
4156 (set_attr "prefix" "maybe_vex")
4157 (set_attr "mode" "DF")])
4159 (define_insn "*extendsfdf2_i387"
4160 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4161 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4163 "* return output_387_reg_move (insn, operands);"
4164 [(set_attr "type" "fmov")
4165 (set_attr "mode" "SF,XF")])
4167 (define_expand "extend<mode>xf2"
4168 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4169 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4172 /* ??? Needed for compress_float_constant since all fp constants
4173 are TARGET_LEGITIMATE_CONSTANT_P. */
4174 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4176 if (standard_80387_constant_p (operands[1]) > 0)
4178 operands[1] = simplify_const_unary_operation
4179 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4180 emit_move_insn_1 (operands[0], operands[1]);
4183 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4187 (define_insn "*extend<mode>xf2_i387"
4188 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4190 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4192 "* return output_387_reg_move (insn, operands);"
4193 [(set_attr "type" "fmov")
4194 (set_attr "mode" "<MODE>,XF")])
4196 ;; %%% This seems bad bad news.
4197 ;; This cannot output into an f-reg because there is no way to be sure
4198 ;; of truncating in that case. Otherwise this is just like a simple move
4199 ;; insn. So we pretend we can output to a reg in order to get better
4200 ;; register preferencing, but we really use a stack slot.
4202 ;; Conversion from DFmode to SFmode.
4204 (define_expand "truncdfsf2"
4205 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4207 (match_operand:DF 1 "nonimmediate_operand" "")))]
4208 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4210 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4212 else if (flag_unsafe_math_optimizations)
4216 enum ix86_stack_slot slot = (virtuals_instantiated
4219 rtx temp = assign_386_stack_local (SFmode, slot);
4220 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4225 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4227 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4229 We do the conversion post reload to avoid producing of 128bit spills
4230 that might lead to ICE on 32bit target. The sequence unlikely combine
4233 [(set (match_operand:SF 0 "register_operand" "")
4235 (match_operand:DF 1 "nonimmediate_operand" "")))]
4236 "TARGET_USE_VECTOR_FP_CONVERTS
4237 && optimize_insn_for_speed_p ()
4238 && reload_completed && SSE_REG_P (operands[0])"
4241 (float_truncate:V2SF
4245 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4246 operands[3] = CONST0_RTX (V2SFmode);
4247 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4248 /* Use movsd for loading from memory, unpcklpd for registers.
4249 Try to avoid move when unpacking can be done in source, or SSE3
4250 movddup is available. */
4251 if (REG_P (operands[1]))
4254 && true_regnum (operands[0]) != true_regnum (operands[1])
4255 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4256 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4258 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4259 emit_move_insn (tmp, operands[1]);
4262 else if (!TARGET_SSE3)
4263 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4264 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4267 emit_insn (gen_sse2_loadlpd (operands[4],
4268 CONST0_RTX (V2DFmode), operands[1]));
4271 (define_expand "truncdfsf2_with_temp"
4272 [(parallel [(set (match_operand:SF 0 "" "")
4273 (float_truncate:SF (match_operand:DF 1 "" "")))
4274 (clobber (match_operand:SF 2 "" ""))])])
4276 (define_insn "*truncdfsf_fast_mixed"
4277 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4279 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4280 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4282 switch (which_alternative)
4285 return output_387_reg_move (insn, operands);
4287 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4292 [(set_attr "type" "fmov,ssecvt")
4293 (set_attr "prefix" "orig,maybe_vex")
4294 (set_attr "mode" "SF")])
4296 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4297 ;; because nothing we do here is unsafe.
4298 (define_insn "*truncdfsf_fast_sse"
4299 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4301 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4302 "TARGET_SSE2 && TARGET_SSE_MATH"
4303 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4304 [(set_attr "type" "ssecvt")
4305 (set_attr "prefix" "maybe_vex")
4306 (set_attr "mode" "SF")])
4308 (define_insn "*truncdfsf_fast_i387"
4309 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4311 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4312 "TARGET_80387 && flag_unsafe_math_optimizations"
4313 "* return output_387_reg_move (insn, operands);"
4314 [(set_attr "type" "fmov")
4315 (set_attr "mode" "SF")])
4317 (define_insn "*truncdfsf_mixed"
4318 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4320 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4321 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4322 "TARGET_MIX_SSE_I387"
4324 switch (which_alternative)
4327 return output_387_reg_move (insn, operands);
4329 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4335 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4336 (set_attr "unit" "*,*,i387,i387,i387")
4337 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4338 (set_attr "mode" "SF")])
4340 (define_insn "*truncdfsf_i387"
4341 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4343 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4344 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4347 switch (which_alternative)
4350 return output_387_reg_move (insn, operands);
4356 [(set_attr "type" "fmov,multi,multi,multi")
4357 (set_attr "unit" "*,i387,i387,i387")
4358 (set_attr "mode" "SF")])
4360 (define_insn "*truncdfsf2_i387_1"
4361 [(set (match_operand:SF 0 "memory_operand" "=m")
4363 (match_operand:DF 1 "register_operand" "f")))]
4365 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4366 && !TARGET_MIX_SSE_I387"
4367 "* return output_387_reg_move (insn, operands);"
4368 [(set_attr "type" "fmov")
4369 (set_attr "mode" "SF")])
4372 [(set (match_operand:SF 0 "register_operand" "")
4374 (match_operand:DF 1 "fp_register_operand" "")))
4375 (clobber (match_operand 2 "" ""))]
4377 [(set (match_dup 2) (match_dup 1))
4378 (set (match_dup 0) (match_dup 2))]
4379 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4381 ;; Conversion from XFmode to {SF,DF}mode
4383 (define_expand "truncxf<mode>2"
4384 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4385 (float_truncate:MODEF
4386 (match_operand:XF 1 "register_operand" "")))
4387 (clobber (match_dup 2))])]
4390 if (flag_unsafe_math_optimizations)
4392 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4393 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4394 if (reg != operands[0])
4395 emit_move_insn (operands[0], reg);
4400 enum ix86_stack_slot slot = (virtuals_instantiated
4403 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4407 (define_insn "*truncxfsf2_mixed"
4408 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4410 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4411 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4414 gcc_assert (!which_alternative);
4415 return output_387_reg_move (insn, operands);
4417 [(set_attr "type" "fmov,multi,multi,multi")
4418 (set_attr "unit" "*,i387,i387,i387")
4419 (set_attr "mode" "SF")])
4421 (define_insn "*truncxfdf2_mixed"
4422 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4424 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4425 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4428 gcc_assert (!which_alternative);
4429 return output_387_reg_move (insn, operands);
4431 [(set_attr "type" "fmov,multi,multi,multi")
4432 (set_attr "unit" "*,i387,i387,i387")
4433 (set_attr "mode" "DF")])
4435 (define_insn "truncxf<mode>2_i387_noop"
4436 [(set (match_operand:MODEF 0 "register_operand" "=f")
4437 (float_truncate:MODEF
4438 (match_operand:XF 1 "register_operand" "f")))]
4439 "TARGET_80387 && flag_unsafe_math_optimizations"
4440 "* return output_387_reg_move (insn, operands);"
4441 [(set_attr "type" "fmov")
4442 (set_attr "mode" "<MODE>")])
4444 (define_insn "*truncxf<mode>2_i387"
4445 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4446 (float_truncate:MODEF
4447 (match_operand:XF 1 "register_operand" "f")))]
4449 "* return output_387_reg_move (insn, operands);"
4450 [(set_attr "type" "fmov")
4451 (set_attr "mode" "<MODE>")])
4454 [(set (match_operand:MODEF 0 "register_operand" "")
4455 (float_truncate:MODEF
4456 (match_operand:XF 1 "register_operand" "")))
4457 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4458 "TARGET_80387 && reload_completed"
4459 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4460 (set (match_dup 0) (match_dup 2))])
4463 [(set (match_operand:MODEF 0 "memory_operand" "")
4464 (float_truncate:MODEF
4465 (match_operand:XF 1 "register_operand" "")))
4466 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4468 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4470 ;; Signed conversion to DImode.
4472 (define_expand "fix_truncxfdi2"
4473 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4474 (fix:DI (match_operand:XF 1 "register_operand" "")))
4475 (clobber (reg:CC FLAGS_REG))])]
4480 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4485 (define_expand "fix_trunc<mode>di2"
4486 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4487 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4488 (clobber (reg:CC FLAGS_REG))])]
4489 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4492 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4494 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4497 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4499 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4500 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4501 if (out != operands[0])
4502 emit_move_insn (operands[0], out);
4507 ;; Signed conversion to SImode.
4509 (define_expand "fix_truncxfsi2"
4510 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4511 (fix:SI (match_operand:XF 1 "register_operand" "")))
4512 (clobber (reg:CC FLAGS_REG))])]
4517 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4522 (define_expand "fix_trunc<mode>si2"
4523 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4524 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4525 (clobber (reg:CC FLAGS_REG))])]
4526 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4529 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4531 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4534 if (SSE_FLOAT_MODE_P (<MODE>mode))
4536 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4537 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4538 if (out != operands[0])
4539 emit_move_insn (operands[0], out);
4544 ;; Signed conversion to HImode.
4546 (define_expand "fix_trunc<mode>hi2"
4547 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4548 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4549 (clobber (reg:CC FLAGS_REG))])]
4551 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4555 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4560 ;; Unsigned conversion to SImode.
4562 (define_expand "fixuns_trunc<mode>si2"
4564 [(set (match_operand:SI 0 "register_operand" "")
4566 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4568 (clobber (match_scratch:<ssevecmode> 3 ""))
4569 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4570 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4572 enum machine_mode mode = <MODE>mode;
4573 enum machine_mode vecmode = <ssevecmode>mode;
4574 REAL_VALUE_TYPE TWO31r;
4577 if (optimize_insn_for_size_p ())
4580 real_ldexp (&TWO31r, &dconst1, 31);
4581 two31 = const_double_from_real_value (TWO31r, mode);
4582 two31 = ix86_build_const_vector (vecmode, true, two31);
4583 operands[2] = force_reg (vecmode, two31);
4586 (define_insn_and_split "*fixuns_trunc<mode>_1"
4587 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4589 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4590 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4591 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4592 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4593 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4594 && optimize_function_for_speed_p (cfun)"
4596 "&& reload_completed"
4599 ix86_split_convert_uns_si_sse (operands);
4603 ;; Unsigned conversion to HImode.
4604 ;; Without these patterns, we'll try the unsigned SI conversion which
4605 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4607 (define_expand "fixuns_trunc<mode>hi2"
4609 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4610 (set (match_operand:HI 0 "nonimmediate_operand" "")
4611 (subreg:HI (match_dup 2) 0))]
4612 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4613 "operands[2] = gen_reg_rtx (SImode);")
4615 ;; When SSE is available, it is always faster to use it!
4616 (define_insn "fix_trunc<mode>di_sse"
4617 [(set (match_operand:DI 0 "register_operand" "=r,r")
4618 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4619 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4620 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4621 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4622 [(set_attr "type" "sseicvt")
4623 (set_attr "prefix" "maybe_vex")
4624 (set_attr "prefix_rex" "1")
4625 (set_attr "mode" "<MODE>")
4626 (set_attr "athlon_decode" "double,vector")
4627 (set_attr "amdfam10_decode" "double,double")
4628 (set_attr "bdver1_decode" "double,double")])
4630 (define_insn "fix_trunc<mode>si_sse"
4631 [(set (match_operand:SI 0 "register_operand" "=r,r")
4632 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4633 "SSE_FLOAT_MODE_P (<MODE>mode)
4634 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4635 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4636 [(set_attr "type" "sseicvt")
4637 (set_attr "prefix" "maybe_vex")
4638 (set_attr "mode" "<MODE>")
4639 (set_attr "athlon_decode" "double,vector")
4640 (set_attr "amdfam10_decode" "double,double")
4641 (set_attr "bdver1_decode" "double,double")])
4643 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4645 [(set (match_operand:MODEF 0 "register_operand" "")
4646 (match_operand:MODEF 1 "memory_operand" ""))
4647 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4648 (fix:SSEMODEI24 (match_dup 0)))]
4649 "TARGET_SHORTEN_X87_SSE
4650 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4651 && peep2_reg_dead_p (2, operands[0])"
4652 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4654 ;; Avoid vector decoded forms of the instruction.
4656 [(match_scratch:DF 2 "Y2")
4657 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4658 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4659 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4660 [(set (match_dup 2) (match_dup 1))
4661 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4664 [(match_scratch:SF 2 "x")
4665 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4666 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4667 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4668 [(set (match_dup 2) (match_dup 1))
4669 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4671 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4672 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4673 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4674 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4676 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4677 && (TARGET_64BIT || <MODE>mode != DImode))
4679 && can_create_pseudo_p ()"
4684 if (memory_operand (operands[0], VOIDmode))
4685 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4688 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4689 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4695 [(set_attr "type" "fisttp")
4696 (set_attr "mode" "<MODE>")])
4698 (define_insn "fix_trunc<mode>_i387_fisttp"
4699 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4700 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4701 (clobber (match_scratch:XF 2 "=&1f"))]
4702 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4704 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4705 && (TARGET_64BIT || <MODE>mode != DImode))
4706 && TARGET_SSE_MATH)"
4707 "* return output_fix_trunc (insn, operands, 1);"
4708 [(set_attr "type" "fisttp")
4709 (set_attr "mode" "<MODE>")])
4711 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4712 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4713 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4714 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4715 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4716 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4718 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4719 && (TARGET_64BIT || <MODE>mode != DImode))
4720 && TARGET_SSE_MATH)"
4722 [(set_attr "type" "fisttp")
4723 (set_attr "mode" "<MODE>")])
4726 [(set (match_operand:X87MODEI 0 "register_operand" "")
4727 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4728 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4729 (clobber (match_scratch 3 ""))]
4731 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4732 (clobber (match_dup 3))])
4733 (set (match_dup 0) (match_dup 2))])
4736 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4737 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4738 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4739 (clobber (match_scratch 3 ""))]
4741 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4742 (clobber (match_dup 3))])])
4744 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4745 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4746 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4747 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4748 ;; function in i386.c.
4749 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4750 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4751 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4752 (clobber (reg:CC FLAGS_REG))]
4753 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4755 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4756 && (TARGET_64BIT || <MODE>mode != DImode))
4757 && can_create_pseudo_p ()"
4762 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4764 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4765 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4766 if (memory_operand (operands[0], VOIDmode))
4767 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4768 operands[2], operands[3]));
4771 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4772 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4773 operands[2], operands[3],
4778 [(set_attr "type" "fistp")
4779 (set_attr "i387_cw" "trunc")
4780 (set_attr "mode" "<MODE>")])
4782 (define_insn "fix_truncdi_i387"
4783 [(set (match_operand:DI 0 "memory_operand" "=m")
4784 (fix:DI (match_operand 1 "register_operand" "f")))
4785 (use (match_operand:HI 2 "memory_operand" "m"))
4786 (use (match_operand:HI 3 "memory_operand" "m"))
4787 (clobber (match_scratch:XF 4 "=&1f"))]
4788 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4790 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4791 "* return output_fix_trunc (insn, operands, 0);"
4792 [(set_attr "type" "fistp")
4793 (set_attr "i387_cw" "trunc")
4794 (set_attr "mode" "DI")])
4796 (define_insn "fix_truncdi_i387_with_temp"
4797 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4798 (fix:DI (match_operand 1 "register_operand" "f,f")))
4799 (use (match_operand:HI 2 "memory_operand" "m,m"))
4800 (use (match_operand:HI 3 "memory_operand" "m,m"))
4801 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4802 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4803 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4805 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4807 [(set_attr "type" "fistp")
4808 (set_attr "i387_cw" "trunc")
4809 (set_attr "mode" "DI")])
4812 [(set (match_operand:DI 0 "register_operand" "")
4813 (fix:DI (match_operand 1 "register_operand" "")))
4814 (use (match_operand:HI 2 "memory_operand" ""))
4815 (use (match_operand:HI 3 "memory_operand" ""))
4816 (clobber (match_operand:DI 4 "memory_operand" ""))
4817 (clobber (match_scratch 5 ""))]
4819 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4822 (clobber (match_dup 5))])
4823 (set (match_dup 0) (match_dup 4))])
4826 [(set (match_operand:DI 0 "memory_operand" "")
4827 (fix:DI (match_operand 1 "register_operand" "")))
4828 (use (match_operand:HI 2 "memory_operand" ""))
4829 (use (match_operand:HI 3 "memory_operand" ""))
4830 (clobber (match_operand:DI 4 "memory_operand" ""))
4831 (clobber (match_scratch 5 ""))]
4833 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4836 (clobber (match_dup 5))])])
4838 (define_insn "fix_trunc<mode>_i387"
4839 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4840 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4841 (use (match_operand:HI 2 "memory_operand" "m"))
4842 (use (match_operand:HI 3 "memory_operand" "m"))]
4843 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4845 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4846 "* return output_fix_trunc (insn, operands, 0);"
4847 [(set_attr "type" "fistp")
4848 (set_attr "i387_cw" "trunc")
4849 (set_attr "mode" "<MODE>")])
4851 (define_insn "fix_trunc<mode>_i387_with_temp"
4852 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4853 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4854 (use (match_operand:HI 2 "memory_operand" "m,m"))
4855 (use (match_operand:HI 3 "memory_operand" "m,m"))
4856 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4857 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4859 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4861 [(set_attr "type" "fistp")
4862 (set_attr "i387_cw" "trunc")
4863 (set_attr "mode" "<MODE>")])
4866 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4867 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4868 (use (match_operand:HI 2 "memory_operand" ""))
4869 (use (match_operand:HI 3 "memory_operand" ""))
4870 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4872 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4874 (use (match_dup 3))])
4875 (set (match_dup 0) (match_dup 4))])
4878 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4879 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4880 (use (match_operand:HI 2 "memory_operand" ""))
4881 (use (match_operand:HI 3 "memory_operand" ""))
4882 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4884 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4886 (use (match_dup 3))])])
4888 (define_insn "x86_fnstcw_1"
4889 [(set (match_operand:HI 0 "memory_operand" "=m")
4890 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4893 [(set (attr "length")
4894 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4895 (set_attr "mode" "HI")
4896 (set_attr "unit" "i387")
4897 (set_attr "bdver1_decode" "vector")])
4899 (define_insn "x86_fldcw_1"
4900 [(set (reg:HI FPCR_REG)
4901 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4904 [(set (attr "length")
4905 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4906 (set_attr "mode" "HI")
4907 (set_attr "unit" "i387")
4908 (set_attr "athlon_decode" "vector")
4909 (set_attr "amdfam10_decode" "vector")
4910 (set_attr "bdver1_decode" "vector")])
4912 ;; Conversion between fixed point and floating point.
4914 ;; Even though we only accept memory inputs, the backend _really_
4915 ;; wants to be able to do this between registers.
4917 (define_expand "floathi<mode>2"
4918 [(set (match_operand:X87MODEF 0 "register_operand" "")
4919 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4921 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4922 || TARGET_MIX_SSE_I387)")
4924 ;; Pre-reload splitter to add memory clobber to the pattern.
4925 (define_insn_and_split "*floathi<mode>2_1"
4926 [(set (match_operand:X87MODEF 0 "register_operand" "")
4927 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4929 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4930 || TARGET_MIX_SSE_I387)
4931 && can_create_pseudo_p ()"
4934 [(parallel [(set (match_dup 0)
4935 (float:X87MODEF (match_dup 1)))
4936 (clobber (match_dup 2))])]
4937 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4939 (define_insn "*floathi<mode>2_i387_with_temp"
4940 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4941 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4942 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4944 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4945 || TARGET_MIX_SSE_I387)"
4947 [(set_attr "type" "fmov,multi")
4948 (set_attr "mode" "<MODE>")
4949 (set_attr "unit" "*,i387")
4950 (set_attr "fp_int_src" "true")])
4952 (define_insn "*floathi<mode>2_i387"
4953 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4954 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4956 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4957 || TARGET_MIX_SSE_I387)"
4959 [(set_attr "type" "fmov")
4960 (set_attr "mode" "<MODE>")
4961 (set_attr "fp_int_src" "true")])
4964 [(set (match_operand:X87MODEF 0 "register_operand" "")
4965 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4966 (clobber (match_operand:HI 2 "memory_operand" ""))]
4968 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4969 || TARGET_MIX_SSE_I387)
4970 && reload_completed"
4971 [(set (match_dup 2) (match_dup 1))
4972 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4975 [(set (match_operand:X87MODEF 0 "register_operand" "")
4976 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4977 (clobber (match_operand:HI 2 "memory_operand" ""))]
4979 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4980 || TARGET_MIX_SSE_I387)
4981 && reload_completed"
4982 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4984 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4985 [(set (match_operand:X87MODEF 0 "register_operand" "")
4987 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4989 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4990 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4992 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4993 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4994 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4996 rtx reg = gen_reg_rtx (XFmode);
4997 rtx (*insn)(rtx, rtx);
4999 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5001 if (<X87MODEF:MODE>mode == SFmode)
5002 insn = gen_truncxfsf2;
5003 else if (<X87MODEF:MODE>mode == DFmode)
5004 insn = gen_truncxfdf2;
5008 emit_insn (insn (operands[0], reg));
5013 ;; Pre-reload splitter to add memory clobber to the pattern.
5014 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5015 [(set (match_operand:X87MODEF 0 "register_operand" "")
5016 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5018 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5019 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5020 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5021 || TARGET_MIX_SSE_I387))
5022 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5023 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5024 && ((<SSEMODEI24:MODE>mode == SImode
5025 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5026 && optimize_function_for_speed_p (cfun)
5027 && flag_trapping_math)
5028 || !(TARGET_INTER_UNIT_CONVERSIONS
5029 || optimize_function_for_size_p (cfun)))))
5030 && can_create_pseudo_p ()"
5033 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5034 (clobber (match_dup 2))])]
5036 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5038 /* Avoid store forwarding (partial memory) stall penalty
5039 by passing DImode value through XMM registers. */
5040 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5041 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5042 && optimize_function_for_speed_p (cfun))
5044 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5051 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5052 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5054 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5055 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5056 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5057 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5059 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5060 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5061 (set_attr "unit" "*,i387,*,*,*")
5062 (set_attr "athlon_decode" "*,*,double,direct,double")
5063 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5064 (set_attr "bdver1_decode" "*,*,double,direct,double")
5065 (set_attr "fp_int_src" "true")])
5067 (define_insn "*floatsi<mode>2_vector_mixed"
5068 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5069 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5070 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5071 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5075 [(set_attr "type" "fmov,sseicvt")
5076 (set_attr "mode" "<MODE>,<ssevecmode>")
5077 (set_attr "unit" "i387,*")
5078 (set_attr "athlon_decode" "*,direct")
5079 (set_attr "amdfam10_decode" "*,double")
5080 (set_attr "bdver1_decode" "*,direct")
5081 (set_attr "fp_int_src" "true")])
5083 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5084 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5086 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5087 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5088 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5089 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5091 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5092 (set_attr "mode" "<MODEF:MODE>")
5093 (set_attr "unit" "*,i387,*,*")
5094 (set_attr "athlon_decode" "*,*,double,direct")
5095 (set_attr "amdfam10_decode" "*,*,vector,double")
5096 (set_attr "bdver1_decode" "*,*,double,direct")
5097 (set_attr "fp_int_src" "true")])
5100 [(set (match_operand:MODEF 0 "register_operand" "")
5101 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5102 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5103 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5104 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5105 && TARGET_INTER_UNIT_CONVERSIONS
5107 && (SSE_REG_P (operands[0])
5108 || (GET_CODE (operands[0]) == SUBREG
5109 && SSE_REG_P (operands[0])))"
5110 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5113 [(set (match_operand:MODEF 0 "register_operand" "")
5114 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5115 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5116 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5117 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5118 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5120 && (SSE_REG_P (operands[0])
5121 || (GET_CODE (operands[0]) == SUBREG
5122 && SSE_REG_P (operands[0])))"
5123 [(set (match_dup 2) (match_dup 1))
5124 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5126 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5127 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5129 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5130 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5131 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5132 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5135 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5136 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5137 [(set_attr "type" "fmov,sseicvt,sseicvt")
5138 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5139 (set_attr "mode" "<MODEF:MODE>")
5140 (set (attr "prefix_rex")
5142 (and (eq_attr "prefix" "maybe_vex")
5143 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5145 (const_string "*")))
5146 (set_attr "unit" "i387,*,*")
5147 (set_attr "athlon_decode" "*,double,direct")
5148 (set_attr "amdfam10_decode" "*,vector,double")
5149 (set_attr "bdver1_decode" "*,double,direct")
5150 (set_attr "fp_int_src" "true")])
5152 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5153 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5155 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5156 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5157 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5158 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5161 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5162 [(set_attr "type" "fmov,sseicvt")
5163 (set_attr "prefix" "orig,maybe_vex")
5164 (set_attr "mode" "<MODEF:MODE>")
5165 (set (attr "prefix_rex")
5167 (and (eq_attr "prefix" "maybe_vex")
5168 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5170 (const_string "*")))
5171 (set_attr "athlon_decode" "*,direct")
5172 (set_attr "amdfam10_decode" "*,double")
5173 (set_attr "bdver1_decode" "*,direct")
5174 (set_attr "fp_int_src" "true")])
5176 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5177 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5179 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5180 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5181 "TARGET_SSE2 && TARGET_SSE_MATH
5182 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5184 [(set_attr "type" "sseicvt")
5185 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5186 (set_attr "athlon_decode" "double,direct,double")
5187 (set_attr "amdfam10_decode" "vector,double,double")
5188 (set_attr "bdver1_decode" "double,direct,double")
5189 (set_attr "fp_int_src" "true")])
5191 (define_insn "*floatsi<mode>2_vector_sse"
5192 [(set (match_operand:MODEF 0 "register_operand" "=x")
5193 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5194 "TARGET_SSE2 && TARGET_SSE_MATH
5195 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5197 [(set_attr "type" "sseicvt")
5198 (set_attr "mode" "<MODE>")
5199 (set_attr "athlon_decode" "direct")
5200 (set_attr "amdfam10_decode" "double")
5201 (set_attr "bdver1_decode" "direct")
5202 (set_attr "fp_int_src" "true")])
5205 [(set (match_operand:MODEF 0 "register_operand" "")
5206 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5207 (clobber (match_operand:SI 2 "memory_operand" ""))]
5208 "TARGET_SSE2 && TARGET_SSE_MATH
5209 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5211 && (SSE_REG_P (operands[0])
5212 || (GET_CODE (operands[0]) == SUBREG
5213 && SSE_REG_P (operands[0])))"
5216 rtx op1 = operands[1];
5218 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5220 if (GET_CODE (op1) == SUBREG)
5221 op1 = SUBREG_REG (op1);
5223 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5225 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5226 emit_insn (gen_sse2_loadld (operands[4],
5227 CONST0_RTX (V4SImode), operands[1]));
5229 /* We can ignore possible trapping value in the
5230 high part of SSE register for non-trapping math. */
5231 else if (SSE_REG_P (op1) && !flag_trapping_math)
5232 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5235 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5236 emit_move_insn (operands[2], operands[1]);
5237 emit_insn (gen_sse2_loadld (operands[4],
5238 CONST0_RTX (V4SImode), operands[2]));
5241 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5246 [(set (match_operand:MODEF 0 "register_operand" "")
5247 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5248 (clobber (match_operand:SI 2 "memory_operand" ""))]
5249 "TARGET_SSE2 && TARGET_SSE_MATH
5250 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5252 && (SSE_REG_P (operands[0])
5253 || (GET_CODE (operands[0]) == SUBREG
5254 && SSE_REG_P (operands[0])))"
5257 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5259 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5261 emit_insn (gen_sse2_loadld (operands[4],
5262 CONST0_RTX (V4SImode), operands[1]));
5264 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5269 [(set (match_operand:MODEF 0 "register_operand" "")
5270 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5271 "TARGET_SSE2 && TARGET_SSE_MATH
5272 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5274 && (SSE_REG_P (operands[0])
5275 || (GET_CODE (operands[0]) == SUBREG
5276 && SSE_REG_P (operands[0])))"
5279 rtx op1 = operands[1];
5281 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5283 if (GET_CODE (op1) == SUBREG)
5284 op1 = SUBREG_REG (op1);
5286 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5288 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5289 emit_insn (gen_sse2_loadld (operands[4],
5290 CONST0_RTX (V4SImode), operands[1]));
5292 /* We can ignore possible trapping value in the
5293 high part of SSE register for non-trapping math. */
5294 else if (SSE_REG_P (op1) && !flag_trapping_math)
5295 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5299 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5304 [(set (match_operand:MODEF 0 "register_operand" "")
5305 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5306 "TARGET_SSE2 && TARGET_SSE_MATH
5307 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5309 && (SSE_REG_P (operands[0])
5310 || (GET_CODE (operands[0]) == SUBREG
5311 && SSE_REG_P (operands[0])))"
5314 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5316 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5318 emit_insn (gen_sse2_loadld (operands[4],
5319 CONST0_RTX (V4SImode), operands[1]));
5321 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5325 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5326 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5328 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5329 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5330 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5331 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5333 [(set_attr "type" "sseicvt")
5334 (set_attr "mode" "<MODEF:MODE>")
5335 (set_attr "athlon_decode" "double,direct")
5336 (set_attr "amdfam10_decode" "vector,double")
5337 (set_attr "bdver1_decode" "double,direct")
5338 (set_attr "fp_int_src" "true")])
5340 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5341 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5343 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5344 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5345 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5346 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5347 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5348 [(set_attr "type" "sseicvt")
5349 (set_attr "prefix" "maybe_vex")
5350 (set_attr "mode" "<MODEF:MODE>")
5351 (set (attr "prefix_rex")
5353 (and (eq_attr "prefix" "maybe_vex")
5354 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5356 (const_string "*")))
5357 (set_attr "athlon_decode" "double,direct")
5358 (set_attr "amdfam10_decode" "vector,double")
5359 (set_attr "bdver1_decode" "double,direct")
5360 (set_attr "fp_int_src" "true")])
5363 [(set (match_operand:MODEF 0 "register_operand" "")
5364 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5365 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5366 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5367 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5368 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5370 && (SSE_REG_P (operands[0])
5371 || (GET_CODE (operands[0]) == SUBREG
5372 && SSE_REG_P (operands[0])))"
5373 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5375 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5376 [(set (match_operand:MODEF 0 "register_operand" "=x")
5378 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5379 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5380 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5381 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5382 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5383 [(set_attr "type" "sseicvt")
5384 (set_attr "prefix" "maybe_vex")
5385 (set_attr "mode" "<MODEF:MODE>")
5386 (set (attr "prefix_rex")
5388 (and (eq_attr "prefix" "maybe_vex")
5389 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5391 (const_string "*")))
5392 (set_attr "athlon_decode" "direct")
5393 (set_attr "amdfam10_decode" "double")
5394 (set_attr "bdver1_decode" "direct")
5395 (set_attr "fp_int_src" "true")])
5398 [(set (match_operand:MODEF 0 "register_operand" "")
5399 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5400 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5401 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5402 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5403 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5405 && (SSE_REG_P (operands[0])
5406 || (GET_CODE (operands[0]) == SUBREG
5407 && SSE_REG_P (operands[0])))"
5408 [(set (match_dup 2) (match_dup 1))
5409 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5412 [(set (match_operand:MODEF 0 "register_operand" "")
5413 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5414 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5415 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5416 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5418 && (SSE_REG_P (operands[0])
5419 || (GET_CODE (operands[0]) == SUBREG
5420 && SSE_REG_P (operands[0])))"
5421 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5423 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5424 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5426 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5427 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5429 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5433 [(set_attr "type" "fmov,multi")
5434 (set_attr "mode" "<X87MODEF:MODE>")
5435 (set_attr "unit" "*,i387")
5436 (set_attr "fp_int_src" "true")])
5438 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5439 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5441 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5443 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5445 [(set_attr "type" "fmov")
5446 (set_attr "mode" "<X87MODEF:MODE>")
5447 (set_attr "fp_int_src" "true")])
5450 [(set (match_operand:X87MODEF 0 "register_operand" "")
5451 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5452 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5454 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5456 && FP_REG_P (operands[0])"
5457 [(set (match_dup 2) (match_dup 1))
5458 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5461 [(set (match_operand:X87MODEF 0 "register_operand" "")
5462 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5463 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5465 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5467 && FP_REG_P (operands[0])"
5468 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5470 ;; Avoid store forwarding (partial memory) stall penalty
5471 ;; by passing DImode value through XMM registers. */
5473 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5474 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5476 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5477 (clobber (match_scratch:V4SI 3 "=X,x"))
5478 (clobber (match_scratch:V4SI 4 "=X,x"))
5479 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5480 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5481 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5482 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5484 [(set_attr "type" "multi")
5485 (set_attr "mode" "<X87MODEF:MODE>")
5486 (set_attr "unit" "i387")
5487 (set_attr "fp_int_src" "true")])
5490 [(set (match_operand:X87MODEF 0 "register_operand" "")
5491 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5492 (clobber (match_scratch:V4SI 3 ""))
5493 (clobber (match_scratch:V4SI 4 ""))
5494 (clobber (match_operand:DI 2 "memory_operand" ""))]
5495 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5496 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5497 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5499 && FP_REG_P (operands[0])"
5500 [(set (match_dup 2) (match_dup 3))
5501 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5503 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5504 Assemble the 64-bit DImode value in an xmm register. */
5505 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5506 gen_rtx_SUBREG (SImode, operands[1], 0)));
5507 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5508 gen_rtx_SUBREG (SImode, operands[1], 4)));
5509 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5512 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5516 [(set (match_operand:X87MODEF 0 "register_operand" "")
5517 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5518 (clobber (match_scratch:V4SI 3 ""))
5519 (clobber (match_scratch:V4SI 4 ""))
5520 (clobber (match_operand:DI 2 "memory_operand" ""))]
5521 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5522 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5523 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5525 && FP_REG_P (operands[0])"
5526 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5528 ;; Avoid store forwarding (partial memory) stall penalty by extending
5529 ;; SImode value to DImode through XMM register instead of pushing two
5530 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5531 ;; targets benefit from this optimization. Also note that fild
5532 ;; loads from memory only.
5534 (define_insn "*floatunssi<mode>2_1"
5535 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5536 (unsigned_float:X87MODEF
5537 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5538 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5539 (clobber (match_scratch:SI 3 "=X,x"))]
5541 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5544 [(set_attr "type" "multi")
5545 (set_attr "mode" "<MODE>")])
5548 [(set (match_operand:X87MODEF 0 "register_operand" "")
5549 (unsigned_float:X87MODEF
5550 (match_operand:SI 1 "register_operand" "")))
5551 (clobber (match_operand:DI 2 "memory_operand" ""))
5552 (clobber (match_scratch:SI 3 ""))]
5554 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5556 && reload_completed"
5557 [(set (match_dup 2) (match_dup 1))
5559 (float:X87MODEF (match_dup 2)))]
5560 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5563 [(set (match_operand:X87MODEF 0 "register_operand" "")
5564 (unsigned_float:X87MODEF
5565 (match_operand:SI 1 "memory_operand" "")))
5566 (clobber (match_operand:DI 2 "memory_operand" ""))
5567 (clobber (match_scratch:SI 3 ""))]
5569 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5571 && reload_completed"
5572 [(set (match_dup 2) (match_dup 3))
5574 (float:X87MODEF (match_dup 2)))]
5576 emit_move_insn (operands[3], operands[1]);
5577 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5580 (define_expand "floatunssi<mode>2"
5582 [(set (match_operand:X87MODEF 0 "register_operand" "")
5583 (unsigned_float:X87MODEF
5584 (match_operand:SI 1 "nonimmediate_operand" "")))
5585 (clobber (match_dup 2))
5586 (clobber (match_scratch:SI 3 ""))])]
5588 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5590 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5592 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5594 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5599 enum ix86_stack_slot slot = (virtuals_instantiated
5602 operands[2] = assign_386_stack_local (DImode, slot);
5606 (define_expand "floatunsdisf2"
5607 [(use (match_operand:SF 0 "register_operand" ""))
5608 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5609 "TARGET_64BIT && TARGET_SSE_MATH"
5610 "x86_emit_floatuns (operands); DONE;")
5612 (define_expand "floatunsdidf2"
5613 [(use (match_operand:DF 0 "register_operand" ""))
5614 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5615 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5616 && TARGET_SSE2 && TARGET_SSE_MATH"
5619 x86_emit_floatuns (operands);
5621 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5627 (define_expand "add<mode>3"
5628 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5629 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5630 (match_operand:SDWIM 2 "<general_operand>" "")))]
5632 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5634 (define_insn_and_split "*add<dwi>3_doubleword"
5635 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5637 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5638 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5639 (clobber (reg:CC FLAGS_REG))]
5640 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5643 [(parallel [(set (reg:CC FLAGS_REG)
5644 (unspec:CC [(match_dup 1) (match_dup 2)]
5647 (plus:DWIH (match_dup 1) (match_dup 2)))])
5648 (parallel [(set (match_dup 3)
5652 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5654 (clobber (reg:CC FLAGS_REG))])]
5655 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5657 (define_insn "*add<mode>3_cc"
5658 [(set (reg:CC FLAGS_REG)
5660 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5661 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5663 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5664 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5665 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5666 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5667 [(set_attr "type" "alu")
5668 (set_attr "mode" "<MODE>")])
5670 (define_insn "addqi3_cc"
5671 [(set (reg:CC FLAGS_REG)
5673 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5674 (match_operand:QI 2 "general_operand" "qn,qm")]
5676 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5677 (plus:QI (match_dup 1) (match_dup 2)))]
5678 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5679 "add{b}\t{%2, %0|%0, %2}"
5680 [(set_attr "type" "alu")
5681 (set_attr "mode" "QI")])
5683 (define_insn "*lea_1"
5684 [(set (match_operand:P 0 "register_operand" "=r")
5685 (match_operand:P 1 "no_seg_address_operand" "p"))]
5687 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5688 [(set_attr "type" "lea")
5689 (set_attr "mode" "<MODE>")])
5691 (define_insn "*lea_2"
5692 [(set (match_operand:SI 0 "register_operand" "=r")
5693 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5695 "lea{l}\t{%a1, %0|%0, %a1}"
5696 [(set_attr "type" "lea")
5697 (set_attr "mode" "SI")])
5699 (define_insn "*lea_2_zext"
5700 [(set (match_operand:DI 0 "register_operand" "=r")
5702 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5704 "lea{l}\t{%a1, %k0|%k0, %a1}"
5705 [(set_attr "type" "lea")
5706 (set_attr "mode" "SI")])
5708 (define_insn "*add<mode>_1"
5709 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5711 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5712 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5713 (clobber (reg:CC FLAGS_REG))]
5714 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5716 switch (get_attr_type (insn))
5722 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5723 if (operands[2] == const1_rtx)
5724 return "inc{<imodesuffix>}\t%0";
5727 gcc_assert (operands[2] == constm1_rtx);
5728 return "dec{<imodesuffix>}\t%0";
5732 /* For most processors, ADD is faster than LEA. This alternative
5733 was added to use ADD as much as possible. */
5734 if (which_alternative == 2)
5737 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5740 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5741 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5742 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5744 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5748 (cond [(eq_attr "alternative" "3")
5749 (const_string "lea")
5750 (match_operand:SWI48 2 "incdec_operand" "")
5751 (const_string "incdec")
5753 (const_string "alu")))
5754 (set (attr "length_immediate")
5756 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5758 (const_string "*")))
5759 (set_attr "mode" "<MODE>")])
5761 ;; It may seem that nonimmediate operand is proper one for operand 1.
5762 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5763 ;; we take care in ix86_binary_operator_ok to not allow two memory
5764 ;; operands so proper swapping will be done in reload. This allow
5765 ;; patterns constructed from addsi_1 to match.
5767 (define_insn "*addsi_1_zext"
5768 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5770 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5771 (match_operand:SI 2 "general_operand" "g,0,li"))))
5772 (clobber (reg:CC FLAGS_REG))]
5773 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5775 switch (get_attr_type (insn))
5781 if (operands[2] == const1_rtx)
5782 return "inc{l}\t%k0";
5785 gcc_assert (operands[2] == constm1_rtx);
5786 return "dec{l}\t%k0";
5790 /* For most processors, ADD is faster than LEA. This alternative
5791 was added to use ADD as much as possible. */
5792 if (which_alternative == 1)
5795 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5798 if (x86_maybe_negate_const_int (&operands[2], SImode))
5799 return "sub{l}\t{%2, %k0|%k0, %2}";
5801 return "add{l}\t{%2, %k0|%k0, %2}";
5805 (cond [(eq_attr "alternative" "2")
5806 (const_string "lea")
5807 (match_operand:SI 2 "incdec_operand" "")
5808 (const_string "incdec")
5810 (const_string "alu")))
5811 (set (attr "length_immediate")
5813 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5815 (const_string "*")))
5816 (set_attr "mode" "SI")])
5818 (define_insn "*addhi_1"
5819 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5820 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5821 (match_operand:HI 2 "general_operand" "rn,rm")))
5822 (clobber (reg:CC FLAGS_REG))]
5823 "TARGET_PARTIAL_REG_STALL
5824 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5826 switch (get_attr_type (insn))
5829 if (operands[2] == const1_rtx)
5830 return "inc{w}\t%0";
5833 gcc_assert (operands[2] == constm1_rtx);
5834 return "dec{w}\t%0";
5838 if (x86_maybe_negate_const_int (&operands[2], HImode))
5839 return "sub{w}\t{%2, %0|%0, %2}";
5841 return "add{w}\t{%2, %0|%0, %2}";
5845 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5846 (const_string "incdec")
5847 (const_string "alu")))
5848 (set (attr "length_immediate")
5850 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5852 (const_string "*")))
5853 (set_attr "mode" "HI")])
5855 (define_insn "*addhi_1_lea"
5856 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5857 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5858 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5859 (clobber (reg:CC FLAGS_REG))]
5860 "!TARGET_PARTIAL_REG_STALL
5861 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5863 switch (get_attr_type (insn))
5869 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5870 if (operands[2] == const1_rtx)
5871 return "inc{w}\t%0";
5874 gcc_assert (operands[2] == constm1_rtx);
5875 return "dec{w}\t%0";
5879 /* For most processors, ADD is faster than LEA. This alternative
5880 was added to use ADD as much as possible. */
5881 if (which_alternative == 2)
5884 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5887 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5888 if (x86_maybe_negate_const_int (&operands[2], HImode))
5889 return "sub{w}\t{%2, %0|%0, %2}";
5891 return "add{w}\t{%2, %0|%0, %2}";
5895 (cond [(eq_attr "alternative" "3")
5896 (const_string "lea")
5897 (match_operand:HI 2 "incdec_operand" "")
5898 (const_string "incdec")
5900 (const_string "alu")))
5901 (set (attr "length_immediate")
5903 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5905 (const_string "*")))
5906 (set_attr "mode" "HI,HI,HI,SI")])
5908 ;; %%% Potential partial reg stall on alternative 2. What to do?
5909 (define_insn "*addqi_1"
5910 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5911 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5912 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5913 (clobber (reg:CC FLAGS_REG))]
5914 "TARGET_PARTIAL_REG_STALL
5915 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5917 int widen = (which_alternative == 2);
5918 switch (get_attr_type (insn))
5921 if (operands[2] == const1_rtx)
5922 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5925 gcc_assert (operands[2] == constm1_rtx);
5926 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5930 if (x86_maybe_negate_const_int (&operands[2], QImode))
5933 return "sub{l}\t{%2, %k0|%k0, %2}";
5935 return "sub{b}\t{%2, %0|%0, %2}";
5938 return "add{l}\t{%k2, %k0|%k0, %k2}";
5940 return "add{b}\t{%2, %0|%0, %2}";
5944 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5945 (const_string "incdec")
5946 (const_string "alu")))
5947 (set (attr "length_immediate")
5949 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5951 (const_string "*")))
5952 (set_attr "mode" "QI,QI,SI")])
5954 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5955 (define_insn "*addqi_1_lea"
5956 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5957 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5958 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5959 (clobber (reg:CC FLAGS_REG))]
5960 "!TARGET_PARTIAL_REG_STALL
5961 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5963 int widen = (which_alternative == 3 || which_alternative == 4);
5965 switch (get_attr_type (insn))
5971 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5972 if (operands[2] == const1_rtx)
5973 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5976 gcc_assert (operands[2] == constm1_rtx);
5977 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5981 /* For most processors, ADD is faster than LEA. These alternatives
5982 were added to use ADD as much as possible. */
5983 if (which_alternative == 2 || which_alternative == 4)
5986 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5989 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5990 if (x86_maybe_negate_const_int (&operands[2], QImode))
5993 return "sub{l}\t{%2, %k0|%k0, %2}";
5995 return "sub{b}\t{%2, %0|%0, %2}";
5998 return "add{l}\t{%k2, %k0|%k0, %k2}";
6000 return "add{b}\t{%2, %0|%0, %2}";
6004 (cond [(eq_attr "alternative" "5")
6005 (const_string "lea")
6006 (match_operand:QI 2 "incdec_operand" "")
6007 (const_string "incdec")
6009 (const_string "alu")))
6010 (set (attr "length_immediate")
6012 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6014 (const_string "*")))
6015 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
6017 (define_insn "*addqi_1_slp"
6018 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6019 (plus:QI (match_dup 0)
6020 (match_operand:QI 1 "general_operand" "qn,qnm")))
6021 (clobber (reg:CC FLAGS_REG))]
6022 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6023 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6025 switch (get_attr_type (insn))
6028 if (operands[1] == const1_rtx)
6029 return "inc{b}\t%0";
6032 gcc_assert (operands[1] == constm1_rtx);
6033 return "dec{b}\t%0";
6037 if (x86_maybe_negate_const_int (&operands[1], QImode))
6038 return "sub{b}\t{%1, %0|%0, %1}";
6040 return "add{b}\t{%1, %0|%0, %1}";
6044 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6045 (const_string "incdec")
6046 (const_string "alu1")))
6047 (set (attr "memory")
6048 (if_then_else (match_operand 1 "memory_operand" "")
6049 (const_string "load")
6050 (const_string "none")))
6051 (set_attr "mode" "QI")])
6053 ;; Convert lea to the lea pattern to avoid flags dependency.
6055 [(set (match_operand 0 "register_operand" "")
6056 (plus (match_operand 1 "register_operand" "")
6057 (match_operand 2 "nonmemory_operand" "")))
6058 (clobber (reg:CC FLAGS_REG))]
6059 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6063 enum machine_mode mode = GET_MODE (operands[0]);
6065 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6066 may confuse gen_lowpart. */
6069 operands[1] = gen_lowpart (Pmode, operands[1]);
6070 operands[2] = gen_lowpart (Pmode, operands[2]);
6073 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6075 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6076 operands[0] = gen_lowpart (SImode, operands[0]);
6078 if (TARGET_64BIT && mode != Pmode)
6079 pat = gen_rtx_SUBREG (SImode, pat, 0);
6081 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6085 ;; Convert lea to the lea pattern to avoid flags dependency.
6086 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6087 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
6089 [(set (match_operand:DI 0 "register_operand" "")
6090 (plus:DI (match_operand:DI 1 "register_operand" "")
6091 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6092 (clobber (reg:CC FLAGS_REG))]
6093 "TARGET_64BIT && reload_completed
6094 && true_regnum (operands[0]) != true_regnum (operands[1])"
6096 (plus:DI (match_dup 1) (match_dup 2)))])
6098 ;; Convert lea to the lea pattern to avoid flags dependency.
6100 [(set (match_operand:DI 0 "register_operand" "")
6102 (plus:SI (match_operand:SI 1 "register_operand" "")
6103 (match_operand:SI 2 "nonmemory_operand" ""))))
6104 (clobber (reg:CC FLAGS_REG))]
6105 "TARGET_64BIT && reload_completed
6106 && ix86_lea_for_add_ok (insn, operands)"
6108 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6110 operands[1] = gen_lowpart (DImode, operands[1]);
6111 operands[2] = gen_lowpart (DImode, operands[2]);
6114 (define_insn "*add<mode>_2"
6115 [(set (reg FLAGS_REG)
6118 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6119 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6121 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6122 (plus:SWI (match_dup 1) (match_dup 2)))]
6123 "ix86_match_ccmode (insn, CCGOCmode)
6124 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6126 switch (get_attr_type (insn))
6129 if (operands[2] == const1_rtx)
6130 return "inc{<imodesuffix>}\t%0";
6133 gcc_assert (operands[2] == constm1_rtx);
6134 return "dec{<imodesuffix>}\t%0";
6138 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6139 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6141 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6145 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6146 (const_string "incdec")
6147 (const_string "alu")))
6148 (set (attr "length_immediate")
6150 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6152 (const_string "*")))
6153 (set_attr "mode" "<MODE>")])
6155 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6156 (define_insn "*addsi_2_zext"
6157 [(set (reg FLAGS_REG)
6159 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6160 (match_operand:SI 2 "general_operand" "g"))
6162 (set (match_operand:DI 0 "register_operand" "=r")
6163 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6164 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6165 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6167 switch (get_attr_type (insn))
6170 if (operands[2] == const1_rtx)
6171 return "inc{l}\t%k0";
6174 gcc_assert (operands[2] == constm1_rtx);
6175 return "dec{l}\t%k0";
6179 if (x86_maybe_negate_const_int (&operands[2], SImode))
6180 return "sub{l}\t{%2, %k0|%k0, %2}";
6182 return "add{l}\t{%2, %k0|%k0, %2}";
6186 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6187 (const_string "incdec")
6188 (const_string "alu")))
6189 (set (attr "length_immediate")
6191 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6193 (const_string "*")))
6194 (set_attr "mode" "SI")])
6196 (define_insn "*add<mode>_3"
6197 [(set (reg FLAGS_REG)
6199 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6200 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6201 (clobber (match_scratch:SWI 0 "=<r>"))]
6202 "ix86_match_ccmode (insn, CCZmode)
6203 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6205 switch (get_attr_type (insn))
6208 if (operands[2] == const1_rtx)
6209 return "inc{<imodesuffix>}\t%0";
6212 gcc_assert (operands[2] == constm1_rtx);
6213 return "dec{<imodesuffix>}\t%0";
6217 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6218 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6220 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6224 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6225 (const_string "incdec")
6226 (const_string "alu")))
6227 (set (attr "length_immediate")
6229 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6231 (const_string "*")))
6232 (set_attr "mode" "<MODE>")])
6234 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6235 (define_insn "*addsi_3_zext"
6236 [(set (reg FLAGS_REG)
6238 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6239 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6240 (set (match_operand:DI 0 "register_operand" "=r")
6241 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6242 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6243 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6245 switch (get_attr_type (insn))
6248 if (operands[2] == const1_rtx)
6249 return "inc{l}\t%k0";
6252 gcc_assert (operands[2] == constm1_rtx);
6253 return "dec{l}\t%k0";
6257 if (x86_maybe_negate_const_int (&operands[2], SImode))
6258 return "sub{l}\t{%2, %k0|%k0, %2}";
6260 return "add{l}\t{%2, %k0|%k0, %2}";
6264 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6265 (const_string "incdec")
6266 (const_string "alu")))
6267 (set (attr "length_immediate")
6269 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6271 (const_string "*")))
6272 (set_attr "mode" "SI")])
6274 ; For comparisons against 1, -1 and 128, we may generate better code
6275 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6276 ; is matched then. We can't accept general immediate, because for
6277 ; case of overflows, the result is messed up.
6278 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6279 ; only for comparisons not depending on it.
6281 (define_insn "*adddi_4"
6282 [(set (reg FLAGS_REG)
6284 (match_operand:DI 1 "nonimmediate_operand" "0")
6285 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6286 (clobber (match_scratch:DI 0 "=rm"))]
6288 && ix86_match_ccmode (insn, CCGCmode)"
6290 switch (get_attr_type (insn))
6293 if (operands[2] == constm1_rtx)
6294 return "inc{q}\t%0";
6297 gcc_assert (operands[2] == const1_rtx);
6298 return "dec{q}\t%0";
6302 if (x86_maybe_negate_const_int (&operands[2], DImode))
6303 return "add{q}\t{%2, %0|%0, %2}";
6305 return "sub{q}\t{%2, %0|%0, %2}";
6309 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6310 (const_string "incdec")
6311 (const_string "alu")))
6312 (set (attr "length_immediate")
6314 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6316 (const_string "*")))
6317 (set_attr "mode" "DI")])
6319 ; For comparisons against 1, -1 and 128, we may generate better code
6320 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6321 ; is matched then. We can't accept general immediate, because for
6322 ; case of overflows, the result is messed up.
6323 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6324 ; only for comparisons not depending on it.
6326 (define_insn "*add<mode>_4"
6327 [(set (reg FLAGS_REG)
6329 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6330 (match_operand:SWI124 2 "const_int_operand" "n")))
6331 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6332 "ix86_match_ccmode (insn, CCGCmode)"
6334 switch (get_attr_type (insn))
6337 if (operands[2] == constm1_rtx)
6338 return "inc{<imodesuffix>}\t%0";
6341 gcc_assert (operands[2] == const1_rtx);
6342 return "dec{<imodesuffix>}\t%0";
6346 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6347 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6349 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6353 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6354 (const_string "incdec")
6355 (const_string "alu")))
6356 (set (attr "length_immediate")
6358 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6360 (const_string "*")))
6361 (set_attr "mode" "<MODE>")])
6363 (define_insn "*add<mode>_5"
6364 [(set (reg FLAGS_REG)
6367 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6368 (match_operand:SWI 2 "<general_operand>" "<g>"))
6370 (clobber (match_scratch:SWI 0 "=<r>"))]
6371 "ix86_match_ccmode (insn, CCGOCmode)
6372 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6374 switch (get_attr_type (insn))
6377 if (operands[2] == const1_rtx)
6378 return "inc{<imodesuffix>}\t%0";
6381 gcc_assert (operands[2] == constm1_rtx);
6382 return "dec{<imodesuffix>}\t%0";
6386 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6387 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6389 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6393 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6394 (const_string "incdec")
6395 (const_string "alu")))
6396 (set (attr "length_immediate")
6398 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6400 (const_string "*")))
6401 (set_attr "mode" "<MODE>")])
6403 (define_insn "*addqi_ext_1_rex64"
6404 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6409 (match_operand 1 "ext_register_operand" "0")
6412 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6413 (clobber (reg:CC FLAGS_REG))]
6416 switch (get_attr_type (insn))
6419 if (operands[2] == const1_rtx)
6420 return "inc{b}\t%h0";
6423 gcc_assert (operands[2] == constm1_rtx);
6424 return "dec{b}\t%h0";
6428 return "add{b}\t{%2, %h0|%h0, %2}";
6432 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6433 (const_string "incdec")
6434 (const_string "alu")))
6435 (set_attr "modrm" "1")
6436 (set_attr "mode" "QI")])
6438 (define_insn "addqi_ext_1"
6439 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6444 (match_operand 1 "ext_register_operand" "0")
6447 (match_operand:QI 2 "general_operand" "Qmn")))
6448 (clobber (reg:CC FLAGS_REG))]
6451 switch (get_attr_type (insn))
6454 if (operands[2] == const1_rtx)
6455 return "inc{b}\t%h0";
6458 gcc_assert (operands[2] == constm1_rtx);
6459 return "dec{b}\t%h0";
6463 return "add{b}\t{%2, %h0|%h0, %2}";
6467 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6468 (const_string "incdec")
6469 (const_string "alu")))
6470 (set_attr "modrm" "1")
6471 (set_attr "mode" "QI")])
6473 (define_insn "*addqi_ext_2"
6474 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6479 (match_operand 1 "ext_register_operand" "%0")
6483 (match_operand 2 "ext_register_operand" "Q")
6486 (clobber (reg:CC FLAGS_REG))]
6488 "add{b}\t{%h2, %h0|%h0, %h2}"
6489 [(set_attr "type" "alu")
6490 (set_attr "mode" "QI")])
6492 ;; The lea patterns for non-Pmodes needs to be matched by
6493 ;; several insns converted to real lea by splitters.
6495 (define_insn_and_split "*lea_general_1"
6496 [(set (match_operand 0 "register_operand" "=r")
6497 (plus (plus (match_operand 1 "index_register_operand" "l")
6498 (match_operand 2 "register_operand" "r"))
6499 (match_operand 3 "immediate_operand" "i")))]
6500 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6501 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6502 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6503 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6504 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6505 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6506 || GET_MODE (operands[3]) == VOIDmode)"
6508 "&& reload_completed"
6512 operands[0] = gen_lowpart (SImode, operands[0]);
6513 operands[1] = gen_lowpart (Pmode, operands[1]);
6514 operands[2] = gen_lowpart (Pmode, operands[2]);
6515 operands[3] = gen_lowpart (Pmode, operands[3]);
6516 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6518 if (Pmode != SImode)
6519 pat = gen_rtx_SUBREG (SImode, pat, 0);
6520 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6523 [(set_attr "type" "lea")
6524 (set_attr "mode" "SI")])
6526 (define_insn_and_split "*lea_general_1_zext"
6527 [(set (match_operand:DI 0 "register_operand" "=r")
6530 (match_operand:SI 1 "index_register_operand" "l")
6531 (match_operand:SI 2 "register_operand" "r"))
6532 (match_operand:SI 3 "immediate_operand" "i"))))]
6535 "&& reload_completed"
6537 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6539 (match_dup 3)) 0)))]
6541 operands[1] = gen_lowpart (Pmode, operands[1]);
6542 operands[2] = gen_lowpart (Pmode, operands[2]);
6543 operands[3] = gen_lowpart (Pmode, operands[3]);
6545 [(set_attr "type" "lea")
6546 (set_attr "mode" "SI")])
6548 (define_insn_and_split "*lea_general_2"
6549 [(set (match_operand 0 "register_operand" "=r")
6550 (plus (mult (match_operand 1 "index_register_operand" "l")
6551 (match_operand 2 "const248_operand" "i"))
6552 (match_operand 3 "nonmemory_operand" "ri")))]
6553 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6554 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6555 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6556 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6557 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6558 || GET_MODE (operands[3]) == VOIDmode)"
6560 "&& reload_completed"
6564 operands[0] = gen_lowpart (SImode, operands[0]);
6565 operands[1] = gen_lowpart (Pmode, operands[1]);
6566 operands[3] = gen_lowpart (Pmode, operands[3]);
6567 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6569 if (Pmode != SImode)
6570 pat = gen_rtx_SUBREG (SImode, pat, 0);
6571 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6574 [(set_attr "type" "lea")
6575 (set_attr "mode" "SI")])
6577 (define_insn_and_split "*lea_general_2_zext"
6578 [(set (match_operand:DI 0 "register_operand" "=r")
6581 (match_operand:SI 1 "index_register_operand" "l")
6582 (match_operand:SI 2 "const248_operand" "n"))
6583 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6586 "&& reload_completed"
6588 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6590 (match_dup 3)) 0)))]
6592 operands[1] = gen_lowpart (Pmode, operands[1]);
6593 operands[3] = gen_lowpart (Pmode, operands[3]);
6595 [(set_attr "type" "lea")
6596 (set_attr "mode" "SI")])
6598 (define_insn_and_split "*lea_general_3"
6599 [(set (match_operand 0 "register_operand" "=r")
6600 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6601 (match_operand 2 "const248_operand" "i"))
6602 (match_operand 3 "register_operand" "r"))
6603 (match_operand 4 "immediate_operand" "i")))]
6604 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6605 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6606 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6607 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6608 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6610 "&& reload_completed"
6614 operands[0] = gen_lowpart (SImode, operands[0]);
6615 operands[1] = gen_lowpart (Pmode, operands[1]);
6616 operands[3] = gen_lowpart (Pmode, operands[3]);
6617 operands[4] = gen_lowpart (Pmode, operands[4]);
6618 pat = gen_rtx_PLUS (Pmode,
6619 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6623 if (Pmode != SImode)
6624 pat = gen_rtx_SUBREG (SImode, pat, 0);
6625 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6628 [(set_attr "type" "lea")
6629 (set_attr "mode" "SI")])
6631 (define_insn_and_split "*lea_general_3_zext"
6632 [(set (match_operand:DI 0 "register_operand" "=r")
6636 (match_operand:SI 1 "index_register_operand" "l")
6637 (match_operand:SI 2 "const248_operand" "n"))
6638 (match_operand:SI 3 "register_operand" "r"))
6639 (match_operand:SI 4 "immediate_operand" "i"))))]
6642 "&& reload_completed"
6644 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6647 (match_dup 4)) 0)))]
6649 operands[1] = gen_lowpart (Pmode, operands[1]);
6650 operands[3] = gen_lowpart (Pmode, operands[3]);
6651 operands[4] = gen_lowpart (Pmode, operands[4]);
6653 [(set_attr "type" "lea")
6654 (set_attr "mode" "SI")])
6656 ;; Subtract instructions
6658 (define_expand "sub<mode>3"
6659 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6660 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6661 (match_operand:SDWIM 2 "<general_operand>" "")))]
6663 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6665 (define_insn_and_split "*sub<dwi>3_doubleword"
6666 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6668 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6669 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6670 (clobber (reg:CC FLAGS_REG))]
6671 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6674 [(parallel [(set (reg:CC FLAGS_REG)
6675 (compare:CC (match_dup 1) (match_dup 2)))
6677 (minus:DWIH (match_dup 1) (match_dup 2)))])
6678 (parallel [(set (match_dup 3)
6682 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6684 (clobber (reg:CC FLAGS_REG))])]
6685 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6687 (define_insn "*sub<mode>_1"
6688 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6690 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6691 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6692 (clobber (reg:CC FLAGS_REG))]
6693 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6694 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6695 [(set_attr "type" "alu")
6696 (set_attr "mode" "<MODE>")])
6698 (define_insn "*subsi_1_zext"
6699 [(set (match_operand:DI 0 "register_operand" "=r")
6701 (minus:SI (match_operand:SI 1 "register_operand" "0")
6702 (match_operand:SI 2 "general_operand" "g"))))
6703 (clobber (reg:CC FLAGS_REG))]
6704 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6705 "sub{l}\t{%2, %k0|%k0, %2}"
6706 [(set_attr "type" "alu")
6707 (set_attr "mode" "SI")])
6709 (define_insn "*subqi_1_slp"
6710 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6711 (minus:QI (match_dup 0)
6712 (match_operand:QI 1 "general_operand" "qn,qm")))
6713 (clobber (reg:CC FLAGS_REG))]
6714 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6715 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6716 "sub{b}\t{%1, %0|%0, %1}"
6717 [(set_attr "type" "alu1")
6718 (set_attr "mode" "QI")])
6720 (define_insn "*sub<mode>_2"
6721 [(set (reg FLAGS_REG)
6724 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6725 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6727 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6728 (minus:SWI (match_dup 1) (match_dup 2)))]
6729 "ix86_match_ccmode (insn, CCGOCmode)
6730 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6731 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6732 [(set_attr "type" "alu")
6733 (set_attr "mode" "<MODE>")])
6735 (define_insn "*subsi_2_zext"
6736 [(set (reg FLAGS_REG)
6738 (minus:SI (match_operand:SI 1 "register_operand" "0")
6739 (match_operand:SI 2 "general_operand" "g"))
6741 (set (match_operand:DI 0 "register_operand" "=r")
6743 (minus:SI (match_dup 1)
6745 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6746 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6747 "sub{l}\t{%2, %k0|%k0, %2}"
6748 [(set_attr "type" "alu")
6749 (set_attr "mode" "SI")])
6751 (define_insn "*sub<mode>_3"
6752 [(set (reg FLAGS_REG)
6753 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6754 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6755 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6756 (minus:SWI (match_dup 1) (match_dup 2)))]
6757 "ix86_match_ccmode (insn, CCmode)
6758 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6759 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6760 [(set_attr "type" "alu")
6761 (set_attr "mode" "<MODE>")])
6763 (define_insn "*subsi_3_zext"
6764 [(set (reg FLAGS_REG)
6765 (compare (match_operand:SI 1 "register_operand" "0")
6766 (match_operand:SI 2 "general_operand" "g")))
6767 (set (match_operand:DI 0 "register_operand" "=r")
6769 (minus:SI (match_dup 1)
6771 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6772 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6773 "sub{l}\t{%2, %1|%1, %2}"
6774 [(set_attr "type" "alu")
6775 (set_attr "mode" "SI")])
6777 ;; Add with carry and subtract with borrow
6779 (define_expand "<plusminus_insn><mode>3_carry"
6781 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6783 (match_operand:SWI 1 "nonimmediate_operand" "")
6784 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6785 [(match_operand 3 "flags_reg_operand" "")
6787 (match_operand:SWI 2 "<general_operand>" ""))))
6788 (clobber (reg:CC FLAGS_REG))])]
6789 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6791 (define_insn "*<plusminus_insn><mode>3_carry"
6792 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6794 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6796 (match_operator 3 "ix86_carry_flag_operator"
6797 [(reg FLAGS_REG) (const_int 0)])
6798 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6799 (clobber (reg:CC FLAGS_REG))]
6800 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6801 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6802 [(set_attr "type" "alu")
6803 (set_attr "use_carry" "1")
6804 (set_attr "pent_pair" "pu")
6805 (set_attr "mode" "<MODE>")])
6807 (define_insn "*addsi3_carry_zext"
6808 [(set (match_operand:DI 0 "register_operand" "=r")
6810 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6811 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6812 [(reg FLAGS_REG) (const_int 0)])
6813 (match_operand:SI 2 "general_operand" "g")))))
6814 (clobber (reg:CC FLAGS_REG))]
6815 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6816 "adc{l}\t{%2, %k0|%k0, %2}"
6817 [(set_attr "type" "alu")
6818 (set_attr "use_carry" "1")
6819 (set_attr "pent_pair" "pu")
6820 (set_attr "mode" "SI")])
6822 (define_insn "*subsi3_carry_zext"
6823 [(set (match_operand:DI 0 "register_operand" "=r")
6825 (minus:SI (match_operand:SI 1 "register_operand" "0")
6826 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6827 [(reg FLAGS_REG) (const_int 0)])
6828 (match_operand:SI 2 "general_operand" "g")))))
6829 (clobber (reg:CC FLAGS_REG))]
6830 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6831 "sbb{l}\t{%2, %k0|%k0, %2}"
6832 [(set_attr "type" "alu")
6833 (set_attr "pent_pair" "pu")
6834 (set_attr "mode" "SI")])
6836 ;; Overflow setting add and subtract instructions
6838 (define_insn "*add<mode>3_cconly_overflow"
6839 [(set (reg:CCC FLAGS_REG)
6842 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6843 (match_operand:SWI 2 "<general_operand>" "<g>"))
6845 (clobber (match_scratch:SWI 0 "=<r>"))]
6846 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6847 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6848 [(set_attr "type" "alu")
6849 (set_attr "mode" "<MODE>")])
6851 (define_insn "*sub<mode>3_cconly_overflow"
6852 [(set (reg:CCC FLAGS_REG)
6855 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6856 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6859 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6860 [(set_attr "type" "icmp")
6861 (set_attr "mode" "<MODE>")])
6863 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6864 [(set (reg:CCC FLAGS_REG)
6867 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6868 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6870 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6871 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6872 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6873 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6874 [(set_attr "type" "alu")
6875 (set_attr "mode" "<MODE>")])
6877 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6878 [(set (reg:CCC FLAGS_REG)
6881 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6882 (match_operand:SI 2 "general_operand" "g"))
6884 (set (match_operand:DI 0 "register_operand" "=r")
6885 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6886 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6887 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6888 [(set_attr "type" "alu")
6889 (set_attr "mode" "SI")])
6891 ;; The patterns that match these are at the end of this file.
6893 (define_expand "<plusminus_insn>xf3"
6894 [(set (match_operand:XF 0 "register_operand" "")
6896 (match_operand:XF 1 "register_operand" "")
6897 (match_operand:XF 2 "register_operand" "")))]
6900 (define_expand "<plusminus_insn><mode>3"
6901 [(set (match_operand:MODEF 0 "register_operand" "")
6903 (match_operand:MODEF 1 "register_operand" "")
6904 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6905 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6906 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6908 ;; Multiply instructions
6910 (define_expand "mul<mode>3"
6911 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6913 (match_operand:SWIM248 1 "register_operand" "")
6914 (match_operand:SWIM248 2 "<general_operand>" "")))
6915 (clobber (reg:CC FLAGS_REG))])])
6917 (define_expand "mulqi3"
6918 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6920 (match_operand:QI 1 "register_operand" "")
6921 (match_operand:QI 2 "nonimmediate_operand" "")))
6922 (clobber (reg:CC FLAGS_REG))])]
6923 "TARGET_QIMODE_MATH")
6926 ;; IMUL reg32/64, reg32/64, imm8 Direct
6927 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6928 ;; IMUL reg32/64, reg32/64, imm32 Direct
6929 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6930 ;; IMUL reg32/64, reg32/64 Direct
6931 ;; IMUL reg32/64, mem32/64 Direct
6933 ;; On BDVER1, all above IMULs use DirectPath
6935 (define_insn "*mul<mode>3_1"
6936 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6938 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6939 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6940 (clobber (reg:CC FLAGS_REG))]
6941 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6943 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6944 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6945 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6946 [(set_attr "type" "imul")
6947 (set_attr "prefix_0f" "0,0,1")
6948 (set (attr "athlon_decode")
6949 (cond [(eq_attr "cpu" "athlon")
6950 (const_string "vector")
6951 (eq_attr "alternative" "1")
6952 (const_string "vector")
6953 (and (eq_attr "alternative" "2")
6954 (match_operand 1 "memory_operand" ""))
6955 (const_string "vector")]
6956 (const_string "direct")))
6957 (set (attr "amdfam10_decode")
6958 (cond [(and (eq_attr "alternative" "0,1")
6959 (match_operand 1 "memory_operand" ""))
6960 (const_string "vector")]
6961 (const_string "direct")))
6962 (set_attr "bdver1_decode" "direct")
6963 (set_attr "mode" "<MODE>")])
6965 (define_insn "*mulsi3_1_zext"
6966 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6968 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6969 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6970 (clobber (reg:CC FLAGS_REG))]
6972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6974 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6975 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6976 imul{l}\t{%2, %k0|%k0, %2}"
6977 [(set_attr "type" "imul")
6978 (set_attr "prefix_0f" "0,0,1")
6979 (set (attr "athlon_decode")
6980 (cond [(eq_attr "cpu" "athlon")
6981 (const_string "vector")
6982 (eq_attr "alternative" "1")
6983 (const_string "vector")
6984 (and (eq_attr "alternative" "2")
6985 (match_operand 1 "memory_operand" ""))
6986 (const_string "vector")]
6987 (const_string "direct")))
6988 (set (attr "amdfam10_decode")
6989 (cond [(and (eq_attr "alternative" "0,1")
6990 (match_operand 1 "memory_operand" ""))
6991 (const_string "vector")]
6992 (const_string "direct")))
6993 (set_attr "bdver1_decode" "direct")
6994 (set_attr "mode" "SI")])
6997 ;; IMUL reg16, reg16, imm8 VectorPath
6998 ;; IMUL reg16, mem16, imm8 VectorPath
6999 ;; IMUL reg16, reg16, imm16 VectorPath
7000 ;; IMUL reg16, mem16, imm16 VectorPath
7001 ;; IMUL reg16, reg16 Direct
7002 ;; IMUL reg16, mem16 Direct
7004 ;; On BDVER1, all HI MULs use DoublePath
7006 (define_insn "*mulhi3_1"
7007 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7008 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7009 (match_operand:HI 2 "general_operand" "K,n,mr")))
7010 (clobber (reg:CC FLAGS_REG))]
7012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7014 imul{w}\t{%2, %1, %0|%0, %1, %2}
7015 imul{w}\t{%2, %1, %0|%0, %1, %2}
7016 imul{w}\t{%2, %0|%0, %2}"
7017 [(set_attr "type" "imul")
7018 (set_attr "prefix_0f" "0,0,1")
7019 (set (attr "athlon_decode")
7020 (cond [(eq_attr "cpu" "athlon")
7021 (const_string "vector")
7022 (eq_attr "alternative" "1,2")
7023 (const_string "vector")]
7024 (const_string "direct")))
7025 (set (attr "amdfam10_decode")
7026 (cond [(eq_attr "alternative" "0,1")
7027 (const_string "vector")]
7028 (const_string "direct")))
7029 (set_attr "bdver1_decode" "double")
7030 (set_attr "mode" "HI")])
7032 ;;On AMDFAM10 and BDVER1
7036 (define_insn "*mulqi3_1"
7037 [(set (match_operand:QI 0 "register_operand" "=a")
7038 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7039 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7040 (clobber (reg:CC FLAGS_REG))]
7042 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7044 [(set_attr "type" "imul")
7045 (set_attr "length_immediate" "0")
7046 (set (attr "athlon_decode")
7047 (if_then_else (eq_attr "cpu" "athlon")
7048 (const_string "vector")
7049 (const_string "direct")))
7050 (set_attr "amdfam10_decode" "direct")
7051 (set_attr "bdver1_decode" "direct")
7052 (set_attr "mode" "QI")])
7054 (define_expand "<u>mul<mode><dwi>3"
7055 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7058 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7060 (match_operand:DWIH 2 "register_operand" ""))))
7061 (clobber (reg:CC FLAGS_REG))])])
7063 (define_expand "<u>mulqihi3"
7064 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7067 (match_operand:QI 1 "nonimmediate_operand" ""))
7069 (match_operand:QI 2 "register_operand" ""))))
7070 (clobber (reg:CC FLAGS_REG))])]
7071 "TARGET_QIMODE_MATH")
7073 (define_insn "*<u>mul<mode><dwi>3_1"
7074 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7077 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7079 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7080 (clobber (reg:CC FLAGS_REG))]
7081 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7082 "<sgnprefix>mul{<imodesuffix>}\t%2"
7083 [(set_attr "type" "imul")
7084 (set_attr "length_immediate" "0")
7085 (set (attr "athlon_decode")
7086 (if_then_else (eq_attr "cpu" "athlon")
7087 (const_string "vector")
7088 (const_string "double")))
7089 (set_attr "amdfam10_decode" "double")
7090 (set_attr "bdver1_decode" "direct")
7091 (set_attr "mode" "<MODE>")])
7093 (define_insn "*<u>mulqihi3_1"
7094 [(set (match_operand:HI 0 "register_operand" "=a")
7097 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7099 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7100 (clobber (reg:CC FLAGS_REG))]
7102 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7103 "<sgnprefix>mul{b}\t%2"
7104 [(set_attr "type" "imul")
7105 (set_attr "length_immediate" "0")
7106 (set (attr "athlon_decode")
7107 (if_then_else (eq_attr "cpu" "athlon")
7108 (const_string "vector")
7109 (const_string "direct")))
7110 (set_attr "amdfam10_decode" "direct")
7111 (set_attr "bdver1_decode" "direct")
7112 (set_attr "mode" "QI")])
7114 (define_expand "<s>mul<mode>3_highpart"
7115 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7120 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7122 (match_operand:SWI48 2 "register_operand" "")))
7124 (clobber (match_scratch:SWI48 3 ""))
7125 (clobber (reg:CC FLAGS_REG))])]
7127 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7129 (define_insn "*<s>muldi3_highpart_1"
7130 [(set (match_operand:DI 0 "register_operand" "=d")
7135 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7137 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7139 (clobber (match_scratch:DI 3 "=1"))
7140 (clobber (reg:CC FLAGS_REG))]
7142 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7143 "<sgnprefix>mul{q}\t%2"
7144 [(set_attr "type" "imul")
7145 (set_attr "length_immediate" "0")
7146 (set (attr "athlon_decode")
7147 (if_then_else (eq_attr "cpu" "athlon")
7148 (const_string "vector")
7149 (const_string "double")))
7150 (set_attr "amdfam10_decode" "double")
7151 (set_attr "bdver1_decode" "direct")
7152 (set_attr "mode" "DI")])
7154 (define_insn "*<s>mulsi3_highpart_1"
7155 [(set (match_operand:SI 0 "register_operand" "=d")
7160 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7162 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7164 (clobber (match_scratch:SI 3 "=1"))
7165 (clobber (reg:CC FLAGS_REG))]
7166 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7167 "<sgnprefix>mul{l}\t%2"
7168 [(set_attr "type" "imul")
7169 (set_attr "length_immediate" "0")
7170 (set (attr "athlon_decode")
7171 (if_then_else (eq_attr "cpu" "athlon")
7172 (const_string "vector")
7173 (const_string "double")))
7174 (set_attr "amdfam10_decode" "double")
7175 (set_attr "bdver1_decode" "direct")
7176 (set_attr "mode" "SI")])
7178 (define_insn "*<s>mulsi3_highpart_zext"
7179 [(set (match_operand:DI 0 "register_operand" "=d")
7180 (zero_extend:DI (truncate:SI
7182 (mult:DI (any_extend:DI
7183 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7185 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7187 (clobber (match_scratch:SI 3 "=1"))
7188 (clobber (reg:CC FLAGS_REG))]
7190 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7191 "<sgnprefix>mul{l}\t%2"
7192 [(set_attr "type" "imul")
7193 (set_attr "length_immediate" "0")
7194 (set (attr "athlon_decode")
7195 (if_then_else (eq_attr "cpu" "athlon")
7196 (const_string "vector")
7197 (const_string "double")))
7198 (set_attr "amdfam10_decode" "double")
7199 (set_attr "bdver1_decode" "direct")
7200 (set_attr "mode" "SI")])
7202 ;; The patterns that match these are at the end of this file.
7204 (define_expand "mulxf3"
7205 [(set (match_operand:XF 0 "register_operand" "")
7206 (mult:XF (match_operand:XF 1 "register_operand" "")
7207 (match_operand:XF 2 "register_operand" "")))]
7210 (define_expand "mul<mode>3"
7211 [(set (match_operand:MODEF 0 "register_operand" "")
7212 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7213 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7214 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7215 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7217 ;; Divide instructions
7219 ;; The patterns that match these are at the end of this file.
7221 (define_expand "divxf3"
7222 [(set (match_operand:XF 0 "register_operand" "")
7223 (div:XF (match_operand:XF 1 "register_operand" "")
7224 (match_operand:XF 2 "register_operand" "")))]
7227 (define_expand "divdf3"
7228 [(set (match_operand:DF 0 "register_operand" "")
7229 (div:DF (match_operand:DF 1 "register_operand" "")
7230 (match_operand:DF 2 "nonimmediate_operand" "")))]
7231 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7232 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7234 (define_expand "divsf3"
7235 [(set (match_operand:SF 0 "register_operand" "")
7236 (div:SF (match_operand:SF 1 "register_operand" "")
7237 (match_operand:SF 2 "nonimmediate_operand" "")))]
7238 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7241 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7242 && flag_finite_math_only && !flag_trapping_math
7243 && flag_unsafe_math_optimizations)
7245 ix86_emit_swdivsf (operands[0], operands[1],
7246 operands[2], SFmode);
7251 ;; Divmod instructions.
7253 (define_expand "divmod<mode>4"
7254 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7256 (match_operand:SWIM248 1 "register_operand" "")
7257 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7258 (set (match_operand:SWIM248 3 "register_operand" "")
7259 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7260 (clobber (reg:CC FLAGS_REG))])])
7262 ;; Split with 8bit unsigned divide:
7263 ;; if (dividend an divisor are in [0-255])
7264 ;; use 8bit unsigned integer divide
7266 ;; use original integer divide
7268 [(set (match_operand:SWI48 0 "register_operand" "")
7269 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7270 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7271 (set (match_operand:SWI48 1 "register_operand" "")
7272 (mod:SWI48 (match_dup 2) (match_dup 3)))
7273 (clobber (reg:CC FLAGS_REG))]
7274 "TARGET_USE_8BIT_IDIV
7275 && TARGET_QIMODE_MATH
7276 && can_create_pseudo_p ()
7277 && !optimize_insn_for_size_p ()"
7279 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7281 (define_insn_and_split "divmod<mode>4_1"
7282 [(set (match_operand:SWI48 0 "register_operand" "=a")
7283 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7284 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7285 (set (match_operand:SWI48 1 "register_operand" "=&d")
7286 (mod:SWI48 (match_dup 2) (match_dup 3)))
7287 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7288 (clobber (reg:CC FLAGS_REG))]
7292 [(parallel [(set (match_dup 1)
7293 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7294 (clobber (reg:CC FLAGS_REG))])
7295 (parallel [(set (match_dup 0)
7296 (div:SWI48 (match_dup 2) (match_dup 3)))
7298 (mod:SWI48 (match_dup 2) (match_dup 3)))
7300 (clobber (reg:CC FLAGS_REG))])]
7302 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7304 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7305 operands[4] = operands[2];
7308 /* Avoid use of cltd in favor of a mov+shift. */
7309 emit_move_insn (operands[1], operands[2]);
7310 operands[4] = operands[1];
7313 [(set_attr "type" "multi")
7314 (set_attr "mode" "<MODE>")])
7316 (define_insn_and_split "*divmod<mode>4"
7317 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7318 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7319 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7320 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7321 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7322 (clobber (reg:CC FLAGS_REG))]
7326 [(parallel [(set (match_dup 1)
7327 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7328 (clobber (reg:CC FLAGS_REG))])
7329 (parallel [(set (match_dup 0)
7330 (div:SWIM248 (match_dup 2) (match_dup 3)))
7332 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7334 (clobber (reg:CC FLAGS_REG))])]
7336 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7338 if (<MODE>mode != HImode
7339 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7340 operands[4] = operands[2];
7343 /* Avoid use of cltd in favor of a mov+shift. */
7344 emit_move_insn (operands[1], operands[2]);
7345 operands[4] = operands[1];
7348 [(set_attr "type" "multi")
7349 (set_attr "mode" "<MODE>")])
7351 (define_insn "*divmod<mode>4_noext"
7352 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7353 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7354 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7355 (set (match_operand:SWIM248 1 "register_operand" "=d")
7356 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7357 (use (match_operand:SWIM248 4 "register_operand" "1"))
7358 (clobber (reg:CC FLAGS_REG))]
7360 "idiv{<imodesuffix>}\t%3"
7361 [(set_attr "type" "idiv")
7362 (set_attr "mode" "<MODE>")])
7364 (define_expand "divmodqi4"
7365 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7367 (match_operand:QI 1 "register_operand" "")
7368 (match_operand:QI 2 "nonimmediate_operand" "")))
7369 (set (match_operand:QI 3 "register_operand" "")
7370 (mod:QI (match_dup 1) (match_dup 2)))
7371 (clobber (reg:CC FLAGS_REG))])]
7372 "TARGET_QIMODE_MATH"
7377 tmp0 = gen_reg_rtx (HImode);
7378 tmp1 = gen_reg_rtx (HImode);
7380 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7382 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7383 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7385 /* Extract remainder from AH. */
7386 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7387 insn = emit_move_insn (operands[3], tmp1);
7389 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7390 set_unique_reg_note (insn, REG_EQUAL, mod);
7392 /* Extract quotient from AL. */
7393 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7395 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7396 set_unique_reg_note (insn, REG_EQUAL, div);
7401 ;; Divide AX by r/m8, with result stored in
7404 ;; Change div/mod to HImode and extend the second argument to HImode
7405 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7406 ;; combine may fail.
7407 (define_insn "divmodhiqi3"
7408 [(set (match_operand:HI 0 "register_operand" "=a")
7413 (mod:HI (match_operand:HI 1 "register_operand" "0")
7415 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7419 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7420 (clobber (reg:CC FLAGS_REG))]
7421 "TARGET_QIMODE_MATH"
7423 [(set_attr "type" "idiv")
7424 (set_attr "mode" "QI")])
7426 (define_expand "udivmod<mode>4"
7427 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7429 (match_operand:SWIM248 1 "register_operand" "")
7430 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7431 (set (match_operand:SWIM248 3 "register_operand" "")
7432 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7433 (clobber (reg:CC FLAGS_REG))])])
7435 ;; Split with 8bit unsigned divide:
7436 ;; if (dividend an divisor are in [0-255])
7437 ;; use 8bit unsigned integer divide
7439 ;; use original integer divide
7441 [(set (match_operand:SWI48 0 "register_operand" "")
7442 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7443 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7444 (set (match_operand:SWI48 1 "register_operand" "")
7445 (umod:SWI48 (match_dup 2) (match_dup 3)))
7446 (clobber (reg:CC FLAGS_REG))]
7447 "TARGET_USE_8BIT_IDIV
7448 && TARGET_QIMODE_MATH
7449 && can_create_pseudo_p ()
7450 && !optimize_insn_for_size_p ()"
7452 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7454 (define_insn_and_split "udivmod<mode>4_1"
7455 [(set (match_operand:SWI48 0 "register_operand" "=a")
7456 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7457 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7458 (set (match_operand:SWI48 1 "register_operand" "=&d")
7459 (umod:SWI48 (match_dup 2) (match_dup 3)))
7460 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7461 (clobber (reg:CC FLAGS_REG))]
7465 [(set (match_dup 1) (const_int 0))
7466 (parallel [(set (match_dup 0)
7467 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7469 (umod:SWI48 (match_dup 2) (match_dup 3)))
7471 (clobber (reg:CC FLAGS_REG))])]
7473 [(set_attr "type" "multi")
7474 (set_attr "mode" "<MODE>")])
7476 (define_insn_and_split "*udivmod<mode>4"
7477 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7478 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7479 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7480 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7481 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7482 (clobber (reg:CC FLAGS_REG))]
7486 [(set (match_dup 1) (const_int 0))
7487 (parallel [(set (match_dup 0)
7488 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7490 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7492 (clobber (reg:CC FLAGS_REG))])]
7494 [(set_attr "type" "multi")
7495 (set_attr "mode" "<MODE>")])
7497 (define_insn "*udivmod<mode>4_noext"
7498 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7499 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7500 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7501 (set (match_operand:SWIM248 1 "register_operand" "=d")
7502 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7503 (use (match_operand:SWIM248 4 "register_operand" "1"))
7504 (clobber (reg:CC FLAGS_REG))]
7506 "div{<imodesuffix>}\t%3"
7507 [(set_attr "type" "idiv")
7508 (set_attr "mode" "<MODE>")])
7510 (define_expand "udivmodqi4"
7511 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7513 (match_operand:QI 1 "register_operand" "")
7514 (match_operand:QI 2 "nonimmediate_operand" "")))
7515 (set (match_operand:QI 3 "register_operand" "")
7516 (umod:QI (match_dup 1) (match_dup 2)))
7517 (clobber (reg:CC FLAGS_REG))])]
7518 "TARGET_QIMODE_MATH"
7523 tmp0 = gen_reg_rtx (HImode);
7524 tmp1 = gen_reg_rtx (HImode);
7526 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7528 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7529 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7531 /* Extract remainder from AH. */
7532 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7533 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7534 insn = emit_move_insn (operands[3], tmp1);
7536 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7537 set_unique_reg_note (insn, REG_EQUAL, mod);
7539 /* Extract quotient from AL. */
7540 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7542 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7543 set_unique_reg_note (insn, REG_EQUAL, div);
7548 (define_insn "udivmodhiqi3"
7549 [(set (match_operand:HI 0 "register_operand" "=a")
7554 (mod:HI (match_operand:HI 1 "register_operand" "0")
7556 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7560 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7561 (clobber (reg:CC FLAGS_REG))]
7562 "TARGET_QIMODE_MATH"
7564 [(set_attr "type" "idiv")
7565 (set_attr "mode" "QI")])
7567 ;; We cannot use div/idiv for double division, because it causes
7568 ;; "division by zero" on the overflow and that's not what we expect
7569 ;; from truncate. Because true (non truncating) double division is
7570 ;; never generated, we can't create this insn anyway.
7573 ; [(set (match_operand:SI 0 "register_operand" "=a")
7575 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7577 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7578 ; (set (match_operand:SI 3 "register_operand" "=d")
7580 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7581 ; (clobber (reg:CC FLAGS_REG))]
7583 ; "div{l}\t{%2, %0|%0, %2}"
7584 ; [(set_attr "type" "idiv")])
7586 ;;- Logical AND instructions
7588 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7589 ;; Note that this excludes ah.
7591 (define_expand "testsi_ccno_1"
7592 [(set (reg:CCNO FLAGS_REG)
7594 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7595 (match_operand:SI 1 "nonmemory_operand" ""))
7598 (define_expand "testqi_ccz_1"
7599 [(set (reg:CCZ FLAGS_REG)
7600 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7601 (match_operand:QI 1 "nonmemory_operand" ""))
7604 (define_expand "testdi_ccno_1"
7605 [(set (reg:CCNO FLAGS_REG)
7607 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7608 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7610 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7612 (define_insn "*testdi_1"
7613 [(set (reg FLAGS_REG)
7616 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7617 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7619 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7620 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7622 test{l}\t{%k1, %k0|%k0, %k1}
7623 test{l}\t{%k1, %k0|%k0, %k1}
7624 test{q}\t{%1, %0|%0, %1}
7625 test{q}\t{%1, %0|%0, %1}
7626 test{q}\t{%1, %0|%0, %1}"
7627 [(set_attr "type" "test")
7628 (set_attr "modrm" "0,1,0,1,1")
7629 (set_attr "mode" "SI,SI,DI,DI,DI")])
7631 (define_insn "*testqi_1_maybe_si"
7632 [(set (reg FLAGS_REG)
7635 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7636 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7638 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7639 && ix86_match_ccmode (insn,
7640 CONST_INT_P (operands[1])
7641 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7643 if (which_alternative == 3)
7645 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7646 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7647 return "test{l}\t{%1, %k0|%k0, %1}";
7649 return "test{b}\t{%1, %0|%0, %1}";
7651 [(set_attr "type" "test")
7652 (set_attr "modrm" "0,1,1,1")
7653 (set_attr "mode" "QI,QI,QI,SI")
7654 (set_attr "pent_pair" "uv,np,uv,np")])
7656 (define_insn "*test<mode>_1"
7657 [(set (reg FLAGS_REG)
7660 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7661 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7663 "ix86_match_ccmode (insn, CCNOmode)
7664 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7665 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7666 [(set_attr "type" "test")
7667 (set_attr "modrm" "0,1,1")
7668 (set_attr "mode" "<MODE>")
7669 (set_attr "pent_pair" "uv,np,uv")])
7671 (define_expand "testqi_ext_ccno_0"
7672 [(set (reg:CCNO FLAGS_REG)
7676 (match_operand 0 "ext_register_operand" "")
7679 (match_operand 1 "const_int_operand" ""))
7682 (define_insn "*testqi_ext_0"
7683 [(set (reg FLAGS_REG)
7687 (match_operand 0 "ext_register_operand" "Q")
7690 (match_operand 1 "const_int_operand" "n"))
7692 "ix86_match_ccmode (insn, CCNOmode)"
7693 "test{b}\t{%1, %h0|%h0, %1}"
7694 [(set_attr "type" "test")
7695 (set_attr "mode" "QI")
7696 (set_attr "length_immediate" "1")
7697 (set_attr "modrm" "1")
7698 (set_attr "pent_pair" "np")])
7700 (define_insn "*testqi_ext_1_rex64"
7701 [(set (reg FLAGS_REG)
7705 (match_operand 0 "ext_register_operand" "Q")
7709 (match_operand:QI 1 "register_operand" "Q")))
7711 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7712 "test{b}\t{%1, %h0|%h0, %1}"
7713 [(set_attr "type" "test")
7714 (set_attr "mode" "QI")])
7716 (define_insn "*testqi_ext_1"
7717 [(set (reg FLAGS_REG)
7721 (match_operand 0 "ext_register_operand" "Q")
7725 (match_operand:QI 1 "general_operand" "Qm")))
7727 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7728 "test{b}\t{%1, %h0|%h0, %1}"
7729 [(set_attr "type" "test")
7730 (set_attr "mode" "QI")])
7732 (define_insn "*testqi_ext_2"
7733 [(set (reg FLAGS_REG)
7737 (match_operand 0 "ext_register_operand" "Q")
7741 (match_operand 1 "ext_register_operand" "Q")
7745 "ix86_match_ccmode (insn, CCNOmode)"
7746 "test{b}\t{%h1, %h0|%h0, %h1}"
7747 [(set_attr "type" "test")
7748 (set_attr "mode" "QI")])
7750 (define_insn "*testqi_ext_3_rex64"
7751 [(set (reg FLAGS_REG)
7752 (compare (zero_extract:DI
7753 (match_operand 0 "nonimmediate_operand" "rm")
7754 (match_operand:DI 1 "const_int_operand" "")
7755 (match_operand:DI 2 "const_int_operand" ""))
7758 && ix86_match_ccmode (insn, CCNOmode)
7759 && INTVAL (operands[1]) > 0
7760 && INTVAL (operands[2]) >= 0
7761 /* Ensure that resulting mask is zero or sign extended operand. */
7762 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7763 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7764 && INTVAL (operands[1]) > 32))
7765 && (GET_MODE (operands[0]) == SImode
7766 || GET_MODE (operands[0]) == DImode
7767 || GET_MODE (operands[0]) == HImode
7768 || GET_MODE (operands[0]) == QImode)"
7771 ;; Combine likes to form bit extractions for some tests. Humor it.
7772 (define_insn "*testqi_ext_3"
7773 [(set (reg FLAGS_REG)
7774 (compare (zero_extract:SI
7775 (match_operand 0 "nonimmediate_operand" "rm")
7776 (match_operand:SI 1 "const_int_operand" "")
7777 (match_operand:SI 2 "const_int_operand" ""))
7779 "ix86_match_ccmode (insn, CCNOmode)
7780 && INTVAL (operands[1]) > 0
7781 && INTVAL (operands[2]) >= 0
7782 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7783 && (GET_MODE (operands[0]) == SImode
7784 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7785 || GET_MODE (operands[0]) == HImode
7786 || GET_MODE (operands[0]) == QImode)"
7790 [(set (match_operand 0 "flags_reg_operand" "")
7791 (match_operator 1 "compare_operator"
7793 (match_operand 2 "nonimmediate_operand" "")
7794 (match_operand 3 "const_int_operand" "")
7795 (match_operand 4 "const_int_operand" ""))
7797 "ix86_match_ccmode (insn, CCNOmode)"
7798 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7800 rtx val = operands[2];
7801 HOST_WIDE_INT len = INTVAL (operands[3]);
7802 HOST_WIDE_INT pos = INTVAL (operands[4]);
7804 enum machine_mode mode, submode;
7806 mode = GET_MODE (val);
7809 /* ??? Combine likes to put non-volatile mem extractions in QImode
7810 no matter the size of the test. So find a mode that works. */
7811 if (! MEM_VOLATILE_P (val))
7813 mode = smallest_mode_for_size (pos + len, MODE_INT);
7814 val = adjust_address (val, mode, 0);
7817 else if (GET_CODE (val) == SUBREG
7818 && (submode = GET_MODE (SUBREG_REG (val)),
7819 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7820 && pos + len <= GET_MODE_BITSIZE (submode)
7821 && GET_MODE_CLASS (submode) == MODE_INT)
7823 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7825 val = SUBREG_REG (val);
7827 else if (mode == HImode && pos + len <= 8)
7829 /* Small HImode tests can be converted to QImode. */
7831 val = gen_lowpart (QImode, val);
7834 if (len == HOST_BITS_PER_WIDE_INT)
7837 mask = ((HOST_WIDE_INT)1 << len) - 1;
7840 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7843 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7844 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7845 ;; this is relatively important trick.
7846 ;; Do the conversion only post-reload to avoid limiting of the register class
7849 [(set (match_operand 0 "flags_reg_operand" "")
7850 (match_operator 1 "compare_operator"
7851 [(and (match_operand 2 "register_operand" "")
7852 (match_operand 3 "const_int_operand" ""))
7855 && QI_REG_P (operands[2])
7856 && GET_MODE (operands[2]) != QImode
7857 && ((ix86_match_ccmode (insn, CCZmode)
7858 && !(INTVAL (operands[3]) & ~(255 << 8)))
7859 || (ix86_match_ccmode (insn, CCNOmode)
7860 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7863 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7866 "operands[2] = gen_lowpart (SImode, operands[2]);
7867 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7870 [(set (match_operand 0 "flags_reg_operand" "")
7871 (match_operator 1 "compare_operator"
7872 [(and (match_operand 2 "nonimmediate_operand" "")
7873 (match_operand 3 "const_int_operand" ""))
7876 && GET_MODE (operands[2]) != QImode
7877 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7878 && ((ix86_match_ccmode (insn, CCZmode)
7879 && !(INTVAL (operands[3]) & ~255))
7880 || (ix86_match_ccmode (insn, CCNOmode)
7881 && !(INTVAL (operands[3]) & ~127)))"
7883 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7885 "operands[2] = gen_lowpart (QImode, operands[2]);
7886 operands[3] = gen_lowpart (QImode, operands[3]);")
7888 ;; %%% This used to optimize known byte-wide and operations to memory,
7889 ;; and sometimes to QImode registers. If this is considered useful,
7890 ;; it should be done with splitters.
7892 (define_expand "and<mode>3"
7893 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7894 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7895 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7897 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7899 (define_insn "*anddi_1"
7900 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7902 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7903 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7904 (clobber (reg:CC FLAGS_REG))]
7905 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7907 switch (get_attr_type (insn))
7911 enum machine_mode mode;
7913 gcc_assert (CONST_INT_P (operands[2]));
7914 if (INTVAL (operands[2]) == 0xff)
7918 gcc_assert (INTVAL (operands[2]) == 0xffff);
7922 operands[1] = gen_lowpart (mode, operands[1]);
7924 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7926 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7930 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7931 if (get_attr_mode (insn) == MODE_SI)
7932 return "and{l}\t{%k2, %k0|%k0, %k2}";
7934 return "and{q}\t{%2, %0|%0, %2}";
7937 [(set_attr "type" "alu,alu,alu,imovx")
7938 (set_attr "length_immediate" "*,*,*,0")
7939 (set (attr "prefix_rex")
7941 (and (eq_attr "type" "imovx")
7942 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7943 (match_operand 1 "ext_QIreg_operand" "")))
7945 (const_string "*")))
7946 (set_attr "mode" "SI,DI,DI,SI")])
7948 (define_insn "*andsi_1"
7949 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7950 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7951 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7952 (clobber (reg:CC FLAGS_REG))]
7953 "ix86_binary_operator_ok (AND, SImode, operands)"
7955 switch (get_attr_type (insn))
7959 enum machine_mode mode;
7961 gcc_assert (CONST_INT_P (operands[2]));
7962 if (INTVAL (operands[2]) == 0xff)
7966 gcc_assert (INTVAL (operands[2]) == 0xffff);
7970 operands[1] = gen_lowpart (mode, operands[1]);
7972 return "movz{bl|x}\t{%1, %0|%0, %1}";
7974 return "movz{wl|x}\t{%1, %0|%0, %1}";
7978 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7979 return "and{l}\t{%2, %0|%0, %2}";
7982 [(set_attr "type" "alu,alu,imovx")
7983 (set (attr "prefix_rex")
7985 (and (eq_attr "type" "imovx")
7986 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7987 (match_operand 1 "ext_QIreg_operand" "")))
7989 (const_string "*")))
7990 (set_attr "length_immediate" "*,*,0")
7991 (set_attr "mode" "SI")])
7993 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7994 (define_insn "*andsi_1_zext"
7995 [(set (match_operand:DI 0 "register_operand" "=r")
7997 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7998 (match_operand:SI 2 "general_operand" "g"))))
7999 (clobber (reg:CC FLAGS_REG))]
8000 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8001 "and{l}\t{%2, %k0|%k0, %2}"
8002 [(set_attr "type" "alu")
8003 (set_attr "mode" "SI")])
8005 (define_insn "*andhi_1"
8006 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8007 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8008 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8009 (clobber (reg:CC FLAGS_REG))]
8010 "ix86_binary_operator_ok (AND, HImode, operands)"
8012 switch (get_attr_type (insn))
8015 gcc_assert (CONST_INT_P (operands[2]));
8016 gcc_assert (INTVAL (operands[2]) == 0xff);
8017 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8020 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8022 return "and{w}\t{%2, %0|%0, %2}";
8025 [(set_attr "type" "alu,alu,imovx")
8026 (set_attr "length_immediate" "*,*,0")
8027 (set (attr "prefix_rex")
8029 (and (eq_attr "type" "imovx")
8030 (match_operand 1 "ext_QIreg_operand" ""))
8032 (const_string "*")))
8033 (set_attr "mode" "HI,HI,SI")])
8035 ;; %%% Potential partial reg stall on alternative 2. What to do?
8036 (define_insn "*andqi_1"
8037 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8038 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8039 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8040 (clobber (reg:CC FLAGS_REG))]
8041 "ix86_binary_operator_ok (AND, QImode, operands)"
8043 and{b}\t{%2, %0|%0, %2}
8044 and{b}\t{%2, %0|%0, %2}
8045 and{l}\t{%k2, %k0|%k0, %k2}"
8046 [(set_attr "type" "alu")
8047 (set_attr "mode" "QI,QI,SI")])
8049 (define_insn "*andqi_1_slp"
8050 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8051 (and:QI (match_dup 0)
8052 (match_operand:QI 1 "general_operand" "qn,qmn")))
8053 (clobber (reg:CC FLAGS_REG))]
8054 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8055 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8056 "and{b}\t{%1, %0|%0, %1}"
8057 [(set_attr "type" "alu1")
8058 (set_attr "mode" "QI")])
8061 [(set (match_operand 0 "register_operand" "")
8063 (const_int -65536)))
8064 (clobber (reg:CC FLAGS_REG))]
8065 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8066 || optimize_function_for_size_p (cfun)"
8067 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8068 "operands[1] = gen_lowpart (HImode, operands[0]);")
8071 [(set (match_operand 0 "ext_register_operand" "")
8074 (clobber (reg:CC FLAGS_REG))]
8075 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8076 && reload_completed"
8077 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8078 "operands[1] = gen_lowpart (QImode, operands[0]);")
8081 [(set (match_operand 0 "ext_register_operand" "")
8083 (const_int -65281)))
8084 (clobber (reg:CC FLAGS_REG))]
8085 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8086 && reload_completed"
8087 [(parallel [(set (zero_extract:SI (match_dup 0)
8091 (zero_extract:SI (match_dup 0)
8094 (zero_extract:SI (match_dup 0)
8097 (clobber (reg:CC FLAGS_REG))])]
8098 "operands[0] = gen_lowpart (SImode, operands[0]);")
8100 (define_insn "*anddi_2"
8101 [(set (reg FLAGS_REG)
8104 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8105 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8107 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8108 (and:DI (match_dup 1) (match_dup 2)))]
8109 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8110 && ix86_binary_operator_ok (AND, DImode, operands)"
8112 and{l}\t{%k2, %k0|%k0, %k2}
8113 and{q}\t{%2, %0|%0, %2}
8114 and{q}\t{%2, %0|%0, %2}"
8115 [(set_attr "type" "alu")
8116 (set_attr "mode" "SI,DI,DI")])
8118 (define_insn "*andqi_2_maybe_si"
8119 [(set (reg FLAGS_REG)
8121 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8122 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8124 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8125 (and:QI (match_dup 1) (match_dup 2)))]
8126 "ix86_binary_operator_ok (AND, QImode, operands)
8127 && ix86_match_ccmode (insn,
8128 CONST_INT_P (operands[2])
8129 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8131 if (which_alternative == 2)
8133 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8134 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8135 return "and{l}\t{%2, %k0|%k0, %2}";
8137 return "and{b}\t{%2, %0|%0, %2}";
8139 [(set_attr "type" "alu")
8140 (set_attr "mode" "QI,QI,SI")])
8142 (define_insn "*and<mode>_2"
8143 [(set (reg FLAGS_REG)
8144 (compare (and:SWI124
8145 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8146 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8148 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8149 (and:SWI124 (match_dup 1) (match_dup 2)))]
8150 "ix86_match_ccmode (insn, CCNOmode)
8151 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8152 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8153 [(set_attr "type" "alu")
8154 (set_attr "mode" "<MODE>")])
8156 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8157 (define_insn "*andsi_2_zext"
8158 [(set (reg FLAGS_REG)
8160 (match_operand:SI 1 "nonimmediate_operand" "%0")
8161 (match_operand:SI 2 "general_operand" "g"))
8163 (set (match_operand:DI 0 "register_operand" "=r")
8164 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8165 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8166 && ix86_binary_operator_ok (AND, SImode, operands)"
8167 "and{l}\t{%2, %k0|%k0, %2}"
8168 [(set_attr "type" "alu")
8169 (set_attr "mode" "SI")])
8171 (define_insn "*andqi_2_slp"
8172 [(set (reg FLAGS_REG)
8174 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8175 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8177 (set (strict_low_part (match_dup 0))
8178 (and:QI (match_dup 0) (match_dup 1)))]
8179 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8180 && ix86_match_ccmode (insn, CCNOmode)
8181 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8182 "and{b}\t{%1, %0|%0, %1}"
8183 [(set_attr "type" "alu1")
8184 (set_attr "mode" "QI")])
8186 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8187 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8188 ;; for a QImode operand, which of course failed.
8189 (define_insn "andqi_ext_0"
8190 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8195 (match_operand 1 "ext_register_operand" "0")
8198 (match_operand 2 "const_int_operand" "n")))
8199 (clobber (reg:CC FLAGS_REG))]
8201 "and{b}\t{%2, %h0|%h0, %2}"
8202 [(set_attr "type" "alu")
8203 (set_attr "length_immediate" "1")
8204 (set_attr "modrm" "1")
8205 (set_attr "mode" "QI")])
8207 ;; Generated by peephole translating test to and. This shows up
8208 ;; often in fp comparisons.
8209 (define_insn "*andqi_ext_0_cc"
8210 [(set (reg FLAGS_REG)
8214 (match_operand 1 "ext_register_operand" "0")
8217 (match_operand 2 "const_int_operand" "n"))
8219 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8228 "ix86_match_ccmode (insn, CCNOmode)"
8229 "and{b}\t{%2, %h0|%h0, %2}"
8230 [(set_attr "type" "alu")
8231 (set_attr "length_immediate" "1")
8232 (set_attr "modrm" "1")
8233 (set_attr "mode" "QI")])
8235 (define_insn "*andqi_ext_1_rex64"
8236 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8241 (match_operand 1 "ext_register_operand" "0")
8245 (match_operand 2 "ext_register_operand" "Q"))))
8246 (clobber (reg:CC FLAGS_REG))]
8248 "and{b}\t{%2, %h0|%h0, %2}"
8249 [(set_attr "type" "alu")
8250 (set_attr "length_immediate" "0")
8251 (set_attr "mode" "QI")])
8253 (define_insn "*andqi_ext_1"
8254 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8259 (match_operand 1 "ext_register_operand" "0")
8263 (match_operand:QI 2 "general_operand" "Qm"))))
8264 (clobber (reg:CC FLAGS_REG))]
8266 "and{b}\t{%2, %h0|%h0, %2}"
8267 [(set_attr "type" "alu")
8268 (set_attr "length_immediate" "0")
8269 (set_attr "mode" "QI")])
8271 (define_insn "*andqi_ext_2"
8272 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8277 (match_operand 1 "ext_register_operand" "%0")
8281 (match_operand 2 "ext_register_operand" "Q")
8284 (clobber (reg:CC FLAGS_REG))]
8286 "and{b}\t{%h2, %h0|%h0, %h2}"
8287 [(set_attr "type" "alu")
8288 (set_attr "length_immediate" "0")
8289 (set_attr "mode" "QI")])
8291 ;; Convert wide AND instructions with immediate operand to shorter QImode
8292 ;; equivalents when possible.
8293 ;; Don't do the splitting with memory operands, since it introduces risk
8294 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8295 ;; for size, but that can (should?) be handled by generic code instead.
8297 [(set (match_operand 0 "register_operand" "")
8298 (and (match_operand 1 "register_operand" "")
8299 (match_operand 2 "const_int_operand" "")))
8300 (clobber (reg:CC FLAGS_REG))]
8302 && QI_REG_P (operands[0])
8303 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8304 && !(~INTVAL (operands[2]) & ~(255 << 8))
8305 && GET_MODE (operands[0]) != QImode"
8306 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8307 (and:SI (zero_extract:SI (match_dup 1)
8308 (const_int 8) (const_int 8))
8310 (clobber (reg:CC FLAGS_REG))])]
8311 "operands[0] = gen_lowpart (SImode, operands[0]);
8312 operands[1] = gen_lowpart (SImode, operands[1]);
8313 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8315 ;; Since AND can be encoded with sign extended immediate, this is only
8316 ;; profitable when 7th bit is not set.
8318 [(set (match_operand 0 "register_operand" "")
8319 (and (match_operand 1 "general_operand" "")
8320 (match_operand 2 "const_int_operand" "")))
8321 (clobber (reg:CC FLAGS_REG))]
8323 && ANY_QI_REG_P (operands[0])
8324 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8325 && !(~INTVAL (operands[2]) & ~255)
8326 && !(INTVAL (operands[2]) & 128)
8327 && GET_MODE (operands[0]) != QImode"
8328 [(parallel [(set (strict_low_part (match_dup 0))
8329 (and:QI (match_dup 1)
8331 (clobber (reg:CC FLAGS_REG))])]
8332 "operands[0] = gen_lowpart (QImode, operands[0]);
8333 operands[1] = gen_lowpart (QImode, operands[1]);
8334 operands[2] = gen_lowpart (QImode, operands[2]);")
8336 ;; Logical inclusive and exclusive OR instructions
8338 ;; %%% This used to optimize known byte-wide and operations to memory.
8339 ;; If this is considered useful, it should be done with splitters.
8341 (define_expand "<code><mode>3"
8342 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8343 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8344 (match_operand:SWIM 2 "<general_operand>" "")))]
8346 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8348 (define_insn "*<code><mode>_1"
8349 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8351 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8352 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8353 (clobber (reg:CC FLAGS_REG))]
8354 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8355 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8356 [(set_attr "type" "alu")
8357 (set_attr "mode" "<MODE>")])
8359 ;; %%% Potential partial reg stall on alternative 2. What to do?
8360 (define_insn "*<code>qi_1"
8361 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8362 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8363 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8364 (clobber (reg:CC FLAGS_REG))]
8365 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8367 <logic>{b}\t{%2, %0|%0, %2}
8368 <logic>{b}\t{%2, %0|%0, %2}
8369 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8370 [(set_attr "type" "alu")
8371 (set_attr "mode" "QI,QI,SI")])
8373 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8374 (define_insn "*<code>si_1_zext"
8375 [(set (match_operand:DI 0 "register_operand" "=r")
8377 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8378 (match_operand:SI 2 "general_operand" "g"))))
8379 (clobber (reg:CC FLAGS_REG))]
8380 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8381 "<logic>{l}\t{%2, %k0|%k0, %2}"
8382 [(set_attr "type" "alu")
8383 (set_attr "mode" "SI")])
8385 (define_insn "*<code>si_1_zext_imm"
8386 [(set (match_operand:DI 0 "register_operand" "=r")
8388 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8389 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8390 (clobber (reg:CC FLAGS_REG))]
8391 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8392 "<logic>{l}\t{%2, %k0|%k0, %2}"
8393 [(set_attr "type" "alu")
8394 (set_attr "mode" "SI")])
8396 (define_insn "*<code>qi_1_slp"
8397 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8398 (any_or:QI (match_dup 0)
8399 (match_operand:QI 1 "general_operand" "qmn,qn")))
8400 (clobber (reg:CC FLAGS_REG))]
8401 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8402 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8403 "<logic>{b}\t{%1, %0|%0, %1}"
8404 [(set_attr "type" "alu1")
8405 (set_attr "mode" "QI")])
8407 (define_insn "*<code><mode>_2"
8408 [(set (reg FLAGS_REG)
8409 (compare (any_or:SWI
8410 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8411 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8413 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8414 (any_or:SWI (match_dup 1) (match_dup 2)))]
8415 "ix86_match_ccmode (insn, CCNOmode)
8416 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8417 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8418 [(set_attr "type" "alu")
8419 (set_attr "mode" "<MODE>")])
8421 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8422 ;; ??? Special case for immediate operand is missing - it is tricky.
8423 (define_insn "*<code>si_2_zext"
8424 [(set (reg FLAGS_REG)
8425 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8426 (match_operand:SI 2 "general_operand" "g"))
8428 (set (match_operand:DI 0 "register_operand" "=r")
8429 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8430 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8431 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8432 "<logic>{l}\t{%2, %k0|%k0, %2}"
8433 [(set_attr "type" "alu")
8434 (set_attr "mode" "SI")])
8436 (define_insn "*<code>si_2_zext_imm"
8437 [(set (reg FLAGS_REG)
8439 (match_operand:SI 1 "nonimmediate_operand" "%0")
8440 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8442 (set (match_operand:DI 0 "register_operand" "=r")
8443 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8444 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8445 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8446 "<logic>{l}\t{%2, %k0|%k0, %2}"
8447 [(set_attr "type" "alu")
8448 (set_attr "mode" "SI")])
8450 (define_insn "*<code>qi_2_slp"
8451 [(set (reg FLAGS_REG)
8452 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8453 (match_operand:QI 1 "general_operand" "qmn,qn"))
8455 (set (strict_low_part (match_dup 0))
8456 (any_or:QI (match_dup 0) (match_dup 1)))]
8457 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8458 && ix86_match_ccmode (insn, CCNOmode)
8459 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8460 "<logic>{b}\t{%1, %0|%0, %1}"
8461 [(set_attr "type" "alu1")
8462 (set_attr "mode" "QI")])
8464 (define_insn "*<code><mode>_3"
8465 [(set (reg FLAGS_REG)
8466 (compare (any_or:SWI
8467 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8468 (match_operand:SWI 2 "<general_operand>" "<g>"))
8470 (clobber (match_scratch:SWI 0 "=<r>"))]
8471 "ix86_match_ccmode (insn, CCNOmode)
8472 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8473 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8474 [(set_attr "type" "alu")
8475 (set_attr "mode" "<MODE>")])
8477 (define_insn "*<code>qi_ext_0"
8478 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8483 (match_operand 1 "ext_register_operand" "0")
8486 (match_operand 2 "const_int_operand" "n")))
8487 (clobber (reg:CC FLAGS_REG))]
8488 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8489 "<logic>{b}\t{%2, %h0|%h0, %2}"
8490 [(set_attr "type" "alu")
8491 (set_attr "length_immediate" "1")
8492 (set_attr "modrm" "1")
8493 (set_attr "mode" "QI")])
8495 (define_insn "*<code>qi_ext_1_rex64"
8496 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8501 (match_operand 1 "ext_register_operand" "0")
8505 (match_operand 2 "ext_register_operand" "Q"))))
8506 (clobber (reg:CC FLAGS_REG))]
8508 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8509 "<logic>{b}\t{%2, %h0|%h0, %2}"
8510 [(set_attr "type" "alu")
8511 (set_attr "length_immediate" "0")
8512 (set_attr "mode" "QI")])
8514 (define_insn "*<code>qi_ext_1"
8515 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8520 (match_operand 1 "ext_register_operand" "0")
8524 (match_operand:QI 2 "general_operand" "Qm"))))
8525 (clobber (reg:CC FLAGS_REG))]
8527 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8528 "<logic>{b}\t{%2, %h0|%h0, %2}"
8529 [(set_attr "type" "alu")
8530 (set_attr "length_immediate" "0")
8531 (set_attr "mode" "QI")])
8533 (define_insn "*<code>qi_ext_2"
8534 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8538 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8541 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8544 (clobber (reg:CC FLAGS_REG))]
8545 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8546 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8547 [(set_attr "type" "alu")
8548 (set_attr "length_immediate" "0")
8549 (set_attr "mode" "QI")])
8552 [(set (match_operand 0 "register_operand" "")
8553 (any_or (match_operand 1 "register_operand" "")
8554 (match_operand 2 "const_int_operand" "")))
8555 (clobber (reg:CC FLAGS_REG))]
8557 && QI_REG_P (operands[0])
8558 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8559 && !(INTVAL (operands[2]) & ~(255 << 8))
8560 && GET_MODE (operands[0]) != QImode"
8561 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8562 (any_or:SI (zero_extract:SI (match_dup 1)
8563 (const_int 8) (const_int 8))
8565 (clobber (reg:CC FLAGS_REG))])]
8566 "operands[0] = gen_lowpart (SImode, operands[0]);
8567 operands[1] = gen_lowpart (SImode, operands[1]);
8568 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8570 ;; Since OR can be encoded with sign extended immediate, this is only
8571 ;; profitable when 7th bit is set.
8573 [(set (match_operand 0 "register_operand" "")
8574 (any_or (match_operand 1 "general_operand" "")
8575 (match_operand 2 "const_int_operand" "")))
8576 (clobber (reg:CC FLAGS_REG))]
8578 && ANY_QI_REG_P (operands[0])
8579 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8580 && !(INTVAL (operands[2]) & ~255)
8581 && (INTVAL (operands[2]) & 128)
8582 && GET_MODE (operands[0]) != QImode"
8583 [(parallel [(set (strict_low_part (match_dup 0))
8584 (any_or:QI (match_dup 1)
8586 (clobber (reg:CC FLAGS_REG))])]
8587 "operands[0] = gen_lowpart (QImode, operands[0]);
8588 operands[1] = gen_lowpart (QImode, operands[1]);
8589 operands[2] = gen_lowpart (QImode, operands[2]);")
8591 (define_expand "xorqi_cc_ext_1"
8593 (set (reg:CCNO FLAGS_REG)
8597 (match_operand 1 "ext_register_operand" "")
8600 (match_operand:QI 2 "general_operand" ""))
8602 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8612 (define_insn "*xorqi_cc_ext_1_rex64"
8613 [(set (reg FLAGS_REG)
8617 (match_operand 1 "ext_register_operand" "0")
8620 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8622 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8631 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8632 "xor{b}\t{%2, %h0|%h0, %2}"
8633 [(set_attr "type" "alu")
8634 (set_attr "modrm" "1")
8635 (set_attr "mode" "QI")])
8637 (define_insn "*xorqi_cc_ext_1"
8638 [(set (reg FLAGS_REG)
8642 (match_operand 1 "ext_register_operand" "0")
8645 (match_operand:QI 2 "general_operand" "qmn"))
8647 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8656 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8657 "xor{b}\t{%2, %h0|%h0, %2}"
8658 [(set_attr "type" "alu")
8659 (set_attr "modrm" "1")
8660 (set_attr "mode" "QI")])
8662 ;; Negation instructions
8664 (define_expand "neg<mode>2"
8665 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8666 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8668 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8670 (define_insn_and_split "*neg<dwi>2_doubleword"
8671 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8672 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8673 (clobber (reg:CC FLAGS_REG))]
8674 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8678 [(set (reg:CCZ FLAGS_REG)
8679 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8680 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8683 (plus:DWIH (match_dup 3)
8684 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8686 (clobber (reg:CC FLAGS_REG))])
8689 (neg:DWIH (match_dup 2)))
8690 (clobber (reg:CC FLAGS_REG))])]
8691 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8693 (define_insn "*neg<mode>2_1"
8694 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8695 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8698 "neg{<imodesuffix>}\t%0"
8699 [(set_attr "type" "negnot")
8700 (set_attr "mode" "<MODE>")])
8702 ;; Combine is quite creative about this pattern.
8703 (define_insn "*negsi2_1_zext"
8704 [(set (match_operand:DI 0 "register_operand" "=r")
8706 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8709 (clobber (reg:CC FLAGS_REG))]
8710 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8712 [(set_attr "type" "negnot")
8713 (set_attr "mode" "SI")])
8715 ;; The problem with neg is that it does not perform (compare x 0),
8716 ;; it really performs (compare 0 x), which leaves us with the zero
8717 ;; flag being the only useful item.
8719 (define_insn "*neg<mode>2_cmpz"
8720 [(set (reg:CCZ FLAGS_REG)
8722 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8724 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8725 (neg:SWI (match_dup 1)))]
8726 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8727 "neg{<imodesuffix>}\t%0"
8728 [(set_attr "type" "negnot")
8729 (set_attr "mode" "<MODE>")])
8731 (define_insn "*negsi2_cmpz_zext"
8732 [(set (reg:CCZ FLAGS_REG)
8736 (match_operand:DI 1 "register_operand" "0")
8740 (set (match_operand:DI 0 "register_operand" "=r")
8741 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8744 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8746 [(set_attr "type" "negnot")
8747 (set_attr "mode" "SI")])
8749 ;; Changing of sign for FP values is doable using integer unit too.
8751 (define_expand "<code><mode>2"
8752 [(set (match_operand:X87MODEF 0 "register_operand" "")
8753 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8754 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8755 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8757 (define_insn "*absneg<mode>2_mixed"
8758 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8759 (match_operator:MODEF 3 "absneg_operator"
8760 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8761 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8762 (clobber (reg:CC FLAGS_REG))]
8763 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8766 (define_insn "*absneg<mode>2_sse"
8767 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8768 (match_operator:MODEF 3 "absneg_operator"
8769 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8770 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8771 (clobber (reg:CC FLAGS_REG))]
8772 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8775 (define_insn "*absneg<mode>2_i387"
8776 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8777 (match_operator:X87MODEF 3 "absneg_operator"
8778 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8779 (use (match_operand 2 "" ""))
8780 (clobber (reg:CC FLAGS_REG))]
8781 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8784 (define_expand "<code>tf2"
8785 [(set (match_operand:TF 0 "register_operand" "")
8786 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8788 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8790 (define_insn "*absnegtf2_sse"
8791 [(set (match_operand:TF 0 "register_operand" "=x,x")
8792 (match_operator:TF 3 "absneg_operator"
8793 [(match_operand:TF 1 "register_operand" "0,x")]))
8794 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8795 (clobber (reg:CC FLAGS_REG))]
8799 ;; Splitters for fp abs and neg.
8802 [(set (match_operand 0 "fp_register_operand" "")
8803 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8804 (use (match_operand 2 "" ""))
8805 (clobber (reg:CC FLAGS_REG))]
8807 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8810 [(set (match_operand 0 "register_operand" "")
8811 (match_operator 3 "absneg_operator"
8812 [(match_operand 1 "register_operand" "")]))
8813 (use (match_operand 2 "nonimmediate_operand" ""))
8814 (clobber (reg:CC FLAGS_REG))]
8815 "reload_completed && SSE_REG_P (operands[0])"
8816 [(set (match_dup 0) (match_dup 3))]
8818 enum machine_mode mode = GET_MODE (operands[0]);
8819 enum machine_mode vmode = GET_MODE (operands[2]);
8822 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8823 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8824 if (operands_match_p (operands[0], operands[2]))
8827 operands[1] = operands[2];
8830 if (GET_CODE (operands[3]) == ABS)
8831 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8833 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8838 [(set (match_operand:SF 0 "register_operand" "")
8839 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8840 (use (match_operand:V4SF 2 "" ""))
8841 (clobber (reg:CC FLAGS_REG))]
8843 [(parallel [(set (match_dup 0) (match_dup 1))
8844 (clobber (reg:CC FLAGS_REG))])]
8847 operands[0] = gen_lowpart (SImode, operands[0]);
8848 if (GET_CODE (operands[1]) == ABS)
8850 tmp = gen_int_mode (0x7fffffff, SImode);
8851 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8855 tmp = gen_int_mode (0x80000000, SImode);
8856 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8862 [(set (match_operand:DF 0 "register_operand" "")
8863 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8864 (use (match_operand 2 "" ""))
8865 (clobber (reg:CC FLAGS_REG))]
8867 [(parallel [(set (match_dup 0) (match_dup 1))
8868 (clobber (reg:CC FLAGS_REG))])]
8873 tmp = gen_lowpart (DImode, operands[0]);
8874 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8877 if (GET_CODE (operands[1]) == ABS)
8880 tmp = gen_rtx_NOT (DImode, tmp);
8884 operands[0] = gen_highpart (SImode, operands[0]);
8885 if (GET_CODE (operands[1]) == ABS)
8887 tmp = gen_int_mode (0x7fffffff, SImode);
8888 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8892 tmp = gen_int_mode (0x80000000, SImode);
8893 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8900 [(set (match_operand:XF 0 "register_operand" "")
8901 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8902 (use (match_operand 2 "" ""))
8903 (clobber (reg:CC FLAGS_REG))]
8905 [(parallel [(set (match_dup 0) (match_dup 1))
8906 (clobber (reg:CC FLAGS_REG))])]
8909 operands[0] = gen_rtx_REG (SImode,
8910 true_regnum (operands[0])
8911 + (TARGET_64BIT ? 1 : 2));
8912 if (GET_CODE (operands[1]) == ABS)
8914 tmp = GEN_INT (0x7fff);
8915 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8919 tmp = GEN_INT (0x8000);
8920 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8925 ;; Conditionalize these after reload. If they match before reload, we
8926 ;; lose the clobber and ability to use integer instructions.
8928 (define_insn "*<code><mode>2_1"
8929 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8930 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8932 && (reload_completed
8933 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8934 "f<absneg_mnemonic>"
8935 [(set_attr "type" "fsgn")
8936 (set_attr "mode" "<MODE>")])
8938 (define_insn "*<code>extendsfdf2"
8939 [(set (match_operand:DF 0 "register_operand" "=f")
8940 (absneg:DF (float_extend:DF
8941 (match_operand:SF 1 "register_operand" "0"))))]
8942 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8943 "f<absneg_mnemonic>"
8944 [(set_attr "type" "fsgn")
8945 (set_attr "mode" "DF")])
8947 (define_insn "*<code>extendsfxf2"
8948 [(set (match_operand:XF 0 "register_operand" "=f")
8949 (absneg:XF (float_extend:XF
8950 (match_operand:SF 1 "register_operand" "0"))))]
8952 "f<absneg_mnemonic>"
8953 [(set_attr "type" "fsgn")
8954 (set_attr "mode" "XF")])
8956 (define_insn "*<code>extenddfxf2"
8957 [(set (match_operand:XF 0 "register_operand" "=f")
8958 (absneg:XF (float_extend:XF
8959 (match_operand:DF 1 "register_operand" "0"))))]
8961 "f<absneg_mnemonic>"
8962 [(set_attr "type" "fsgn")
8963 (set_attr "mode" "XF")])
8965 ;; Copysign instructions
8967 (define_mode_iterator CSGNMODE [SF DF TF])
8968 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8970 (define_expand "copysign<mode>3"
8971 [(match_operand:CSGNMODE 0 "register_operand" "")
8972 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8973 (match_operand:CSGNMODE 2 "register_operand" "")]
8974 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8975 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8976 "ix86_expand_copysign (operands); DONE;")
8978 (define_insn_and_split "copysign<mode>3_const"
8979 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8981 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8982 (match_operand:CSGNMODE 2 "register_operand" "0")
8983 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8985 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8986 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8988 "&& reload_completed"
8990 "ix86_split_copysign_const (operands); DONE;")
8992 (define_insn "copysign<mode>3_var"
8993 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8995 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8996 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8997 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8998 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9000 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9001 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9002 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9006 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9008 [(match_operand:CSGNMODE 2 "register_operand" "")
9009 (match_operand:CSGNMODE 3 "register_operand" "")
9010 (match_operand:<CSGNVMODE> 4 "" "")
9011 (match_operand:<CSGNVMODE> 5 "" "")]
9013 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9014 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9015 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9016 && reload_completed"
9018 "ix86_split_copysign_var (operands); DONE;")
9020 ;; One complement instructions
9022 (define_expand "one_cmpl<mode>2"
9023 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9024 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9026 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9028 (define_insn "*one_cmpl<mode>2_1"
9029 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9030 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9031 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9032 "not{<imodesuffix>}\t%0"
9033 [(set_attr "type" "negnot")
9034 (set_attr "mode" "<MODE>")])
9036 ;; %%% Potential partial reg stall on alternative 1. What to do?
9037 (define_insn "*one_cmplqi2_1"
9038 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9039 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9040 "ix86_unary_operator_ok (NOT, QImode, operands)"
9044 [(set_attr "type" "negnot")
9045 (set_attr "mode" "QI,SI")])
9047 ;; ??? Currently never generated - xor is used instead.
9048 (define_insn "*one_cmplsi2_1_zext"
9049 [(set (match_operand:DI 0 "register_operand" "=r")
9051 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9052 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9054 [(set_attr "type" "negnot")
9055 (set_attr "mode" "SI")])
9057 (define_insn "*one_cmpl<mode>2_2"
9058 [(set (reg FLAGS_REG)
9059 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9061 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9062 (not:SWI (match_dup 1)))]
9063 "ix86_match_ccmode (insn, CCNOmode)
9064 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9066 [(set_attr "type" "alu1")
9067 (set_attr "mode" "<MODE>")])
9070 [(set (match_operand 0 "flags_reg_operand" "")
9071 (match_operator 2 "compare_operator"
9072 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9074 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9075 (not:SWI (match_dup 3)))]
9076 "ix86_match_ccmode (insn, CCNOmode)"
9077 [(parallel [(set (match_dup 0)
9078 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9081 (xor:SWI (match_dup 3) (const_int -1)))])])
9083 ;; ??? Currently never generated - xor is used instead.
9084 (define_insn "*one_cmplsi2_2_zext"
9085 [(set (reg FLAGS_REG)
9086 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9088 (set (match_operand:DI 0 "register_operand" "=r")
9089 (zero_extend:DI (not:SI (match_dup 1))))]
9090 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9091 && ix86_unary_operator_ok (NOT, SImode, operands)"
9093 [(set_attr "type" "alu1")
9094 (set_attr "mode" "SI")])
9097 [(set (match_operand 0 "flags_reg_operand" "")
9098 (match_operator 2 "compare_operator"
9099 [(not:SI (match_operand:SI 3 "register_operand" ""))
9101 (set (match_operand:DI 1 "register_operand" "")
9102 (zero_extend:DI (not:SI (match_dup 3))))]
9103 "ix86_match_ccmode (insn, CCNOmode)"
9104 [(parallel [(set (match_dup 0)
9105 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9108 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9110 ;; Shift instructions
9112 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9113 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9114 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9115 ;; from the assembler input.
9117 ;; This instruction shifts the target reg/mem as usual, but instead of
9118 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9119 ;; is a left shift double, bits are taken from the high order bits of
9120 ;; reg, else if the insn is a shift right double, bits are taken from the
9121 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9122 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9124 ;; Since sh[lr]d does not change the `reg' operand, that is done
9125 ;; separately, making all shifts emit pairs of shift double and normal
9126 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9127 ;; support a 63 bit shift, each shift where the count is in a reg expands
9128 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9130 ;; If the shift count is a constant, we need never emit more than one
9131 ;; shift pair, instead using moves and sign extension for counts greater
9134 (define_expand "ashl<mode>3"
9135 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9136 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9137 (match_operand:QI 2 "nonmemory_operand" "")))]
9139 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9141 (define_insn "*ashl<mode>3_doubleword"
9142 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9143 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9144 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9145 (clobber (reg:CC FLAGS_REG))]
9148 [(set_attr "type" "multi")])
9151 [(set (match_operand:DWI 0 "register_operand" "")
9152 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9153 (match_operand:QI 2 "nonmemory_operand" "")))
9154 (clobber (reg:CC FLAGS_REG))]
9155 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9157 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9159 ;; By default we don't ask for a scratch register, because when DWImode
9160 ;; values are manipulated, registers are already at a premium. But if
9161 ;; we have one handy, we won't turn it away.
9164 [(match_scratch:DWIH 3 "r")
9165 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9167 (match_operand:<DWI> 1 "nonmemory_operand" "")
9168 (match_operand:QI 2 "nonmemory_operand" "")))
9169 (clobber (reg:CC FLAGS_REG))])
9173 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9175 (define_insn "x86_64_shld"
9176 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9177 (ior:DI (ashift:DI (match_dup 0)
9178 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9179 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9180 (minus:QI (const_int 64) (match_dup 2)))))
9181 (clobber (reg:CC FLAGS_REG))]
9183 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9184 [(set_attr "type" "ishift")
9185 (set_attr "prefix_0f" "1")
9186 (set_attr "mode" "DI")
9187 (set_attr "athlon_decode" "vector")
9188 (set_attr "amdfam10_decode" "vector")
9189 (set_attr "bdver1_decode" "vector")])
9191 (define_insn "x86_shld"
9192 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9193 (ior:SI (ashift:SI (match_dup 0)
9194 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9195 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9196 (minus:QI (const_int 32) (match_dup 2)))))
9197 (clobber (reg:CC FLAGS_REG))]
9199 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9200 [(set_attr "type" "ishift")
9201 (set_attr "prefix_0f" "1")
9202 (set_attr "mode" "SI")
9203 (set_attr "pent_pair" "np")
9204 (set_attr "athlon_decode" "vector")
9205 (set_attr "amdfam10_decode" "vector")
9206 (set_attr "bdver1_decode" "vector")])
9208 (define_expand "x86_shift<mode>_adj_1"
9209 [(set (reg:CCZ FLAGS_REG)
9210 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9213 (set (match_operand:SWI48 0 "register_operand" "")
9214 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9215 (match_operand:SWI48 1 "register_operand" "")
9218 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9219 (match_operand:SWI48 3 "register_operand" "r")
9222 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9224 (define_expand "x86_shift<mode>_adj_2"
9225 [(use (match_operand:SWI48 0 "register_operand" ""))
9226 (use (match_operand:SWI48 1 "register_operand" ""))
9227 (use (match_operand:QI 2 "register_operand" ""))]
9230 rtx label = gen_label_rtx ();
9233 emit_insn (gen_testqi_ccz_1 (operands[2],
9234 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9236 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9237 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9238 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9239 gen_rtx_LABEL_REF (VOIDmode, label),
9241 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9242 JUMP_LABEL (tmp) = label;
9244 emit_move_insn (operands[0], operands[1]);
9245 ix86_expand_clear (operands[1]);
9248 LABEL_NUSES (label) = 1;
9253 ;; Avoid useless masking of count operand.
9254 (define_insn_and_split "*ashl<mode>3_mask"
9255 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9257 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9260 (match_operand:SI 2 "nonimmediate_operand" "c")
9261 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9262 (clobber (reg:CC FLAGS_REG))]
9263 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9264 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9265 == GET_MODE_BITSIZE (<MODE>mode)-1"
9268 [(parallel [(set (match_dup 0)
9269 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9270 (clobber (reg:CC FLAGS_REG))])]
9272 if (can_create_pseudo_p ())
9273 operands [2] = force_reg (SImode, operands[2]);
9275 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9277 [(set_attr "type" "ishift")
9278 (set_attr "mode" "<MODE>")])
9280 (define_insn "*ashl<mode>3_1"
9281 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9282 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9283 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9284 (clobber (reg:CC FLAGS_REG))]
9285 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9287 switch (get_attr_type (insn))
9293 gcc_assert (operands[2] == const1_rtx);
9294 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9295 return "add{<imodesuffix>}\t%0, %0";
9298 if (operands[2] == const1_rtx
9299 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9300 return "sal{<imodesuffix>}\t%0";
9302 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9306 (cond [(eq_attr "alternative" "1")
9307 (const_string "lea")
9308 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9310 (match_operand 0 "register_operand" ""))
9311 (match_operand 2 "const1_operand" ""))
9312 (const_string "alu")
9314 (const_string "ishift")))
9315 (set (attr "length_immediate")
9317 (ior (eq_attr "type" "alu")
9318 (and (eq_attr "type" "ishift")
9319 (and (match_operand 2 "const1_operand" "")
9320 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9323 (const_string "*")))
9324 (set_attr "mode" "<MODE>")])
9326 (define_insn "*ashlsi3_1_zext"
9327 [(set (match_operand:DI 0 "register_operand" "=r,r")
9329 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9330 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9331 (clobber (reg:CC FLAGS_REG))]
9332 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9334 switch (get_attr_type (insn))
9340 gcc_assert (operands[2] == const1_rtx);
9341 return "add{l}\t%k0, %k0";
9344 if (operands[2] == const1_rtx
9345 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9346 return "sal{l}\t%k0";
9348 return "sal{l}\t{%2, %k0|%k0, %2}";
9352 (cond [(eq_attr "alternative" "1")
9353 (const_string "lea")
9354 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9356 (match_operand 2 "const1_operand" ""))
9357 (const_string "alu")
9359 (const_string "ishift")))
9360 (set (attr "length_immediate")
9362 (ior (eq_attr "type" "alu")
9363 (and (eq_attr "type" "ishift")
9364 (and (match_operand 2 "const1_operand" "")
9365 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9368 (const_string "*")))
9369 (set_attr "mode" "SI")])
9371 (define_insn "*ashlhi3_1"
9372 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9373 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9374 (match_operand:QI 2 "nonmemory_operand" "cI")))
9375 (clobber (reg:CC FLAGS_REG))]
9376 "TARGET_PARTIAL_REG_STALL
9377 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9379 switch (get_attr_type (insn))
9382 gcc_assert (operands[2] == const1_rtx);
9383 return "add{w}\t%0, %0";
9386 if (operands[2] == const1_rtx
9387 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9388 return "sal{w}\t%0";
9390 return "sal{w}\t{%2, %0|%0, %2}";
9394 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9396 (match_operand 0 "register_operand" ""))
9397 (match_operand 2 "const1_operand" ""))
9398 (const_string "alu")
9400 (const_string "ishift")))
9401 (set (attr "length_immediate")
9403 (ior (eq_attr "type" "alu")
9404 (and (eq_attr "type" "ishift")
9405 (and (match_operand 2 "const1_operand" "")
9406 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9409 (const_string "*")))
9410 (set_attr "mode" "HI")])
9412 (define_insn "*ashlhi3_1_lea"
9413 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9414 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9415 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9416 (clobber (reg:CC FLAGS_REG))]
9417 "!TARGET_PARTIAL_REG_STALL
9418 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9420 switch (get_attr_type (insn))
9426 gcc_assert (operands[2] == const1_rtx);
9427 return "add{w}\t%0, %0";
9430 if (operands[2] == const1_rtx
9431 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9432 return "sal{w}\t%0";
9434 return "sal{w}\t{%2, %0|%0, %2}";
9438 (cond [(eq_attr "alternative" "1")
9439 (const_string "lea")
9440 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9442 (match_operand 0 "register_operand" ""))
9443 (match_operand 2 "const1_operand" ""))
9444 (const_string "alu")
9446 (const_string "ishift")))
9447 (set (attr "length_immediate")
9449 (ior (eq_attr "type" "alu")
9450 (and (eq_attr "type" "ishift")
9451 (and (match_operand 2 "const1_operand" "")
9452 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9455 (const_string "*")))
9456 (set_attr "mode" "HI,SI")])
9458 (define_insn "*ashlqi3_1"
9459 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9460 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9461 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9462 (clobber (reg:CC FLAGS_REG))]
9463 "TARGET_PARTIAL_REG_STALL
9464 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9466 switch (get_attr_type (insn))
9469 gcc_assert (operands[2] == const1_rtx);
9470 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9471 return "add{l}\t%k0, %k0";
9473 return "add{b}\t%0, %0";
9476 if (operands[2] == const1_rtx
9477 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9479 if (get_attr_mode (insn) == MODE_SI)
9480 return "sal{l}\t%k0";
9482 return "sal{b}\t%0";
9486 if (get_attr_mode (insn) == MODE_SI)
9487 return "sal{l}\t{%2, %k0|%k0, %2}";
9489 return "sal{b}\t{%2, %0|%0, %2}";
9494 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9496 (match_operand 0 "register_operand" ""))
9497 (match_operand 2 "const1_operand" ""))
9498 (const_string "alu")
9500 (const_string "ishift")))
9501 (set (attr "length_immediate")
9503 (ior (eq_attr "type" "alu")
9504 (and (eq_attr "type" "ishift")
9505 (and (match_operand 2 "const1_operand" "")
9506 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9509 (const_string "*")))
9510 (set_attr "mode" "QI,SI")])
9512 ;; %%% Potential partial reg stall on alternative 2. What to do?
9513 (define_insn "*ashlqi3_1_lea"
9514 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9515 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9516 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9517 (clobber (reg:CC FLAGS_REG))]
9518 "!TARGET_PARTIAL_REG_STALL
9519 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9521 switch (get_attr_type (insn))
9527 gcc_assert (operands[2] == const1_rtx);
9528 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9529 return "add{l}\t%k0, %k0";
9531 return "add{b}\t%0, %0";
9534 if (operands[2] == const1_rtx
9535 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9537 if (get_attr_mode (insn) == MODE_SI)
9538 return "sal{l}\t%k0";
9540 return "sal{b}\t%0";
9544 if (get_attr_mode (insn) == MODE_SI)
9545 return "sal{l}\t{%2, %k0|%k0, %2}";
9547 return "sal{b}\t{%2, %0|%0, %2}";
9552 (cond [(eq_attr "alternative" "2")
9553 (const_string "lea")
9554 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9556 (match_operand 0 "register_operand" ""))
9557 (match_operand 2 "const1_operand" ""))
9558 (const_string "alu")
9560 (const_string "ishift")))
9561 (set (attr "length_immediate")
9563 (ior (eq_attr "type" "alu")
9564 (and (eq_attr "type" "ishift")
9565 (and (match_operand 2 "const1_operand" "")
9566 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9569 (const_string "*")))
9570 (set_attr "mode" "QI,SI,SI")])
9572 (define_insn "*ashlqi3_1_slp"
9573 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9574 (ashift:QI (match_dup 0)
9575 (match_operand:QI 1 "nonmemory_operand" "cI")))
9576 (clobber (reg:CC FLAGS_REG))]
9577 "(optimize_function_for_size_p (cfun)
9578 || !TARGET_PARTIAL_FLAG_REG_STALL
9579 || (operands[1] == const1_rtx
9581 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9583 switch (get_attr_type (insn))
9586 gcc_assert (operands[1] == const1_rtx);
9587 return "add{b}\t%0, %0";
9590 if (operands[1] == const1_rtx
9591 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592 return "sal{b}\t%0";
9594 return "sal{b}\t{%1, %0|%0, %1}";
9598 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9600 (match_operand 0 "register_operand" ""))
9601 (match_operand 1 "const1_operand" ""))
9602 (const_string "alu")
9604 (const_string "ishift1")))
9605 (set (attr "length_immediate")
9607 (ior (eq_attr "type" "alu")
9608 (and (eq_attr "type" "ishift1")
9609 (and (match_operand 1 "const1_operand" "")
9610 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9613 (const_string "*")))
9614 (set_attr "mode" "QI")])
9616 ;; Convert lea to the lea pattern to avoid flags dependency.
9618 [(set (match_operand 0 "register_operand" "")
9619 (ashift (match_operand 1 "index_register_operand" "")
9620 (match_operand:QI 2 "const_int_operand" "")))
9621 (clobber (reg:CC FLAGS_REG))]
9623 && true_regnum (operands[0]) != true_regnum (operands[1])"
9627 enum machine_mode mode = GET_MODE (operands[0]);
9630 operands[1] = gen_lowpart (Pmode, operands[1]);
9631 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9633 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9635 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9636 operands[0] = gen_lowpart (SImode, operands[0]);
9638 if (TARGET_64BIT && mode != Pmode)
9639 pat = gen_rtx_SUBREG (SImode, pat, 0);
9641 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9645 ;; Convert lea to the lea pattern to avoid flags dependency.
9647 [(set (match_operand:DI 0 "register_operand" "")
9649 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9650 (match_operand:QI 2 "const_int_operand" ""))))
9651 (clobber (reg:CC FLAGS_REG))]
9652 "TARGET_64BIT && reload_completed
9653 && true_regnum (operands[0]) != true_regnum (operands[1])"
9655 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9657 operands[1] = gen_lowpart (DImode, operands[1]);
9658 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9661 ;; This pattern can't accept a variable shift count, since shifts by
9662 ;; zero don't affect the flags. We assume that shifts by constant
9663 ;; zero are optimized away.
9664 (define_insn "*ashl<mode>3_cmp"
9665 [(set (reg FLAGS_REG)
9667 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9668 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9670 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9671 (ashift:SWI (match_dup 1) (match_dup 2)))]
9672 "(optimize_function_for_size_p (cfun)
9673 || !TARGET_PARTIAL_FLAG_REG_STALL
9674 || (operands[2] == const1_rtx
9676 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9677 && ix86_match_ccmode (insn, CCGOCmode)
9678 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9680 switch (get_attr_type (insn))
9683 gcc_assert (operands[2] == const1_rtx);
9684 return "add{<imodesuffix>}\t%0, %0";
9687 if (operands[2] == const1_rtx
9688 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9689 return "sal{<imodesuffix>}\t%0";
9691 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9695 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9697 (match_operand 0 "register_operand" ""))
9698 (match_operand 2 "const1_operand" ""))
9699 (const_string "alu")
9701 (const_string "ishift")))
9702 (set (attr "length_immediate")
9704 (ior (eq_attr "type" "alu")
9705 (and (eq_attr "type" "ishift")
9706 (and (match_operand 2 "const1_operand" "")
9707 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9710 (const_string "*")))
9711 (set_attr "mode" "<MODE>")])
9713 (define_insn "*ashlsi3_cmp_zext"
9714 [(set (reg FLAGS_REG)
9716 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9717 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9719 (set (match_operand:DI 0 "register_operand" "=r")
9720 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9722 && (optimize_function_for_size_p (cfun)
9723 || !TARGET_PARTIAL_FLAG_REG_STALL
9724 || (operands[2] == const1_rtx
9726 || TARGET_DOUBLE_WITH_ADD)))
9727 && ix86_match_ccmode (insn, CCGOCmode)
9728 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9730 switch (get_attr_type (insn))
9733 gcc_assert (operands[2] == const1_rtx);
9734 return "add{l}\t%k0, %k0";
9737 if (operands[2] == const1_rtx
9738 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9739 return "sal{l}\t%k0";
9741 return "sal{l}\t{%2, %k0|%k0, %2}";
9745 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9747 (match_operand 2 "const1_operand" ""))
9748 (const_string "alu")
9750 (const_string "ishift")))
9751 (set (attr "length_immediate")
9753 (ior (eq_attr "type" "alu")
9754 (and (eq_attr "type" "ishift")
9755 (and (match_operand 2 "const1_operand" "")
9756 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9759 (const_string "*")))
9760 (set_attr "mode" "SI")])
9762 (define_insn "*ashl<mode>3_cconly"
9763 [(set (reg FLAGS_REG)
9765 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9766 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9768 (clobber (match_scratch:SWI 0 "=<r>"))]
9769 "(optimize_function_for_size_p (cfun)
9770 || !TARGET_PARTIAL_FLAG_REG_STALL
9771 || (operands[2] == const1_rtx
9773 || TARGET_DOUBLE_WITH_ADD)))
9774 && ix86_match_ccmode (insn, CCGOCmode)"
9776 switch (get_attr_type (insn))
9779 gcc_assert (operands[2] == const1_rtx);
9780 return "add{<imodesuffix>}\t%0, %0";
9783 if (operands[2] == const1_rtx
9784 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9785 return "sal{<imodesuffix>}\t%0";
9787 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9791 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9793 (match_operand 0 "register_operand" ""))
9794 (match_operand 2 "const1_operand" ""))
9795 (const_string "alu")
9797 (const_string "ishift")))
9798 (set (attr "length_immediate")
9800 (ior (eq_attr "type" "alu")
9801 (and (eq_attr "type" "ishift")
9802 (and (match_operand 2 "const1_operand" "")
9803 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9806 (const_string "*")))
9807 (set_attr "mode" "<MODE>")])
9809 ;; See comment above `ashl<mode>3' about how this works.
9811 (define_expand "<shiftrt_insn><mode>3"
9812 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9813 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9814 (match_operand:QI 2 "nonmemory_operand" "")))]
9816 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9818 ;; Avoid useless masking of count operand.
9819 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9820 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9822 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9825 (match_operand:SI 2 "nonimmediate_operand" "c")
9826 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9827 (clobber (reg:CC FLAGS_REG))]
9828 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9829 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9830 == GET_MODE_BITSIZE (<MODE>mode)-1"
9833 [(parallel [(set (match_dup 0)
9834 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9835 (clobber (reg:CC FLAGS_REG))])]
9837 if (can_create_pseudo_p ())
9838 operands [2] = force_reg (SImode, operands[2]);
9840 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9842 [(set_attr "type" "ishift")
9843 (set_attr "mode" "<MODE>")])
9845 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9846 [(set (match_operand:DWI 0 "register_operand" "=r")
9847 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9848 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9849 (clobber (reg:CC FLAGS_REG))]
9852 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9854 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9855 [(set_attr "type" "multi")])
9857 ;; By default we don't ask for a scratch register, because when DWImode
9858 ;; values are manipulated, registers are already at a premium. But if
9859 ;; we have one handy, we won't turn it away.
9862 [(match_scratch:DWIH 3 "r")
9863 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9865 (match_operand:<DWI> 1 "register_operand" "")
9866 (match_operand:QI 2 "nonmemory_operand" "")))
9867 (clobber (reg:CC FLAGS_REG))])
9871 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9873 (define_insn "x86_64_shrd"
9874 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9875 (ior:DI (ashiftrt:DI (match_dup 0)
9876 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9877 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9878 (minus:QI (const_int 64) (match_dup 2)))))
9879 (clobber (reg:CC FLAGS_REG))]
9881 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9882 [(set_attr "type" "ishift")
9883 (set_attr "prefix_0f" "1")
9884 (set_attr "mode" "DI")
9885 (set_attr "athlon_decode" "vector")
9886 (set_attr "amdfam10_decode" "vector")
9887 (set_attr "bdver1_decode" "vector")])
9889 (define_insn "x86_shrd"
9890 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9891 (ior:SI (ashiftrt:SI (match_dup 0)
9892 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9893 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9894 (minus:QI (const_int 32) (match_dup 2)))))
9895 (clobber (reg:CC FLAGS_REG))]
9897 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9898 [(set_attr "type" "ishift")
9899 (set_attr "prefix_0f" "1")
9900 (set_attr "mode" "SI")
9901 (set_attr "pent_pair" "np")
9902 (set_attr "athlon_decode" "vector")
9903 (set_attr "amdfam10_decode" "vector")
9904 (set_attr "bdver1_decode" "vector")])
9906 (define_insn "ashrdi3_cvt"
9907 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9908 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9909 (match_operand:QI 2 "const_int_operand" "")))
9910 (clobber (reg:CC FLAGS_REG))]
9911 "TARGET_64BIT && INTVAL (operands[2]) == 63
9912 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9913 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9916 sar{q}\t{%2, %0|%0, %2}"
9917 [(set_attr "type" "imovx,ishift")
9918 (set_attr "prefix_0f" "0,*")
9919 (set_attr "length_immediate" "0,*")
9920 (set_attr "modrm" "0,1")
9921 (set_attr "mode" "DI")])
9923 (define_insn "ashrsi3_cvt"
9924 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9925 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9926 (match_operand:QI 2 "const_int_operand" "")))
9927 (clobber (reg:CC FLAGS_REG))]
9928 "INTVAL (operands[2]) == 31
9929 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9930 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9933 sar{l}\t{%2, %0|%0, %2}"
9934 [(set_attr "type" "imovx,ishift")
9935 (set_attr "prefix_0f" "0,*")
9936 (set_attr "length_immediate" "0,*")
9937 (set_attr "modrm" "0,1")
9938 (set_attr "mode" "SI")])
9940 (define_insn "*ashrsi3_cvt_zext"
9941 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9943 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9944 (match_operand:QI 2 "const_int_operand" ""))))
9945 (clobber (reg:CC FLAGS_REG))]
9946 "TARGET_64BIT && INTVAL (operands[2]) == 31
9947 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9948 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9951 sar{l}\t{%2, %k0|%k0, %2}"
9952 [(set_attr "type" "imovx,ishift")
9953 (set_attr "prefix_0f" "0,*")
9954 (set_attr "length_immediate" "0,*")
9955 (set_attr "modrm" "0,1")
9956 (set_attr "mode" "SI")])
9958 (define_expand "x86_shift<mode>_adj_3"
9959 [(use (match_operand:SWI48 0 "register_operand" ""))
9960 (use (match_operand:SWI48 1 "register_operand" ""))
9961 (use (match_operand:QI 2 "register_operand" ""))]
9964 rtx label = gen_label_rtx ();
9967 emit_insn (gen_testqi_ccz_1 (operands[2],
9968 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9970 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9971 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9972 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9973 gen_rtx_LABEL_REF (VOIDmode, label),
9975 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9976 JUMP_LABEL (tmp) = label;
9978 emit_move_insn (operands[0], operands[1]);
9979 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9980 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9982 LABEL_NUSES (label) = 1;
9987 (define_insn "*<shiftrt_insn><mode>3_1"
9988 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9989 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9990 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9991 (clobber (reg:CC FLAGS_REG))]
9992 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9994 if (operands[2] == const1_rtx
9995 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9996 return "<shiftrt>{<imodesuffix>}\t%0";
9998 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10000 [(set_attr "type" "ishift")
10001 (set (attr "length_immediate")
10003 (and (match_operand 2 "const1_operand" "")
10004 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10007 (const_string "*")))
10008 (set_attr "mode" "<MODE>")])
10010 (define_insn "*<shiftrt_insn>si3_1_zext"
10011 [(set (match_operand:DI 0 "register_operand" "=r")
10013 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10014 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10015 (clobber (reg:CC FLAGS_REG))]
10016 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10018 if (operands[2] == const1_rtx
10019 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10020 return "<shiftrt>{l}\t%k0";
10022 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10024 [(set_attr "type" "ishift")
10025 (set (attr "length_immediate")
10027 (and (match_operand 2 "const1_operand" "")
10028 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10031 (const_string "*")))
10032 (set_attr "mode" "SI")])
10034 (define_insn "*<shiftrt_insn>qi3_1_slp"
10035 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10036 (any_shiftrt:QI (match_dup 0)
10037 (match_operand:QI 1 "nonmemory_operand" "cI")))
10038 (clobber (reg:CC FLAGS_REG))]
10039 "(optimize_function_for_size_p (cfun)
10040 || !TARGET_PARTIAL_REG_STALL
10041 || (operands[1] == const1_rtx
10042 && TARGET_SHIFT1))"
10044 if (operands[1] == const1_rtx
10045 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10046 return "<shiftrt>{b}\t%0";
10048 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10050 [(set_attr "type" "ishift1")
10051 (set (attr "length_immediate")
10053 (and (match_operand 1 "const1_operand" "")
10054 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10057 (const_string "*")))
10058 (set_attr "mode" "QI")])
10060 ;; This pattern can't accept a variable shift count, since shifts by
10061 ;; zero don't affect the flags. We assume that shifts by constant
10062 ;; zero are optimized away.
10063 (define_insn "*<shiftrt_insn><mode>3_cmp"
10064 [(set (reg FLAGS_REG)
10067 (match_operand:SWI 1 "nonimmediate_operand" "0")
10068 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10070 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10071 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10072 "(optimize_function_for_size_p (cfun)
10073 || !TARGET_PARTIAL_FLAG_REG_STALL
10074 || (operands[2] == const1_rtx
10076 && ix86_match_ccmode (insn, CCGOCmode)
10077 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10079 if (operands[2] == const1_rtx
10080 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10081 return "<shiftrt>{<imodesuffix>}\t%0";
10083 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10085 [(set_attr "type" "ishift")
10086 (set (attr "length_immediate")
10088 (and (match_operand 2 "const1_operand" "")
10089 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10092 (const_string "*")))
10093 (set_attr "mode" "<MODE>")])
10095 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10096 [(set (reg FLAGS_REG)
10098 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10099 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10101 (set (match_operand:DI 0 "register_operand" "=r")
10102 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10104 && (optimize_function_for_size_p (cfun)
10105 || !TARGET_PARTIAL_FLAG_REG_STALL
10106 || (operands[2] == const1_rtx
10108 && ix86_match_ccmode (insn, CCGOCmode)
10109 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10111 if (operands[2] == const1_rtx
10112 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10113 return "<shiftrt>{l}\t%k0";
10115 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10117 [(set_attr "type" "ishift")
10118 (set (attr "length_immediate")
10120 (and (match_operand 2 "const1_operand" "")
10121 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10124 (const_string "*")))
10125 (set_attr "mode" "SI")])
10127 (define_insn "*<shiftrt_insn><mode>3_cconly"
10128 [(set (reg FLAGS_REG)
10131 (match_operand:SWI 1 "register_operand" "0")
10132 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10134 (clobber (match_scratch:SWI 0 "=<r>"))]
10135 "(optimize_function_for_size_p (cfun)
10136 || !TARGET_PARTIAL_FLAG_REG_STALL
10137 || (operands[2] == const1_rtx
10139 && ix86_match_ccmode (insn, CCGOCmode)"
10141 if (operands[2] == const1_rtx
10142 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10143 return "<shiftrt>{<imodesuffix>}\t%0";
10145 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10147 [(set_attr "type" "ishift")
10148 (set (attr "length_immediate")
10150 (and (match_operand 2 "const1_operand" "")
10151 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10154 (const_string "*")))
10155 (set_attr "mode" "<MODE>")])
10157 ;; Rotate instructions
10159 (define_expand "<rotate_insn>ti3"
10160 [(set (match_operand:TI 0 "register_operand" "")
10161 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10162 (match_operand:QI 2 "nonmemory_operand" "")))]
10165 if (const_1_to_63_operand (operands[2], VOIDmode))
10166 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10167 (operands[0], operands[1], operands[2]));
10174 (define_expand "<rotate_insn>di3"
10175 [(set (match_operand:DI 0 "shiftdi_operand" "")
10176 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10177 (match_operand:QI 2 "nonmemory_operand" "")))]
10181 ix86_expand_binary_operator (<CODE>, DImode, operands);
10182 else if (const_1_to_31_operand (operands[2], VOIDmode))
10183 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10184 (operands[0], operands[1], operands[2]));
10191 (define_expand "<rotate_insn><mode>3"
10192 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10193 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10194 (match_operand:QI 2 "nonmemory_operand" "")))]
10196 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10198 ;; Avoid useless masking of count operand.
10199 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10200 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10202 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10205 (match_operand:SI 2 "nonimmediate_operand" "c")
10206 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10207 (clobber (reg:CC FLAGS_REG))]
10208 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10209 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10210 == GET_MODE_BITSIZE (<MODE>mode)-1"
10213 [(parallel [(set (match_dup 0)
10214 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10215 (clobber (reg:CC FLAGS_REG))])]
10217 if (can_create_pseudo_p ())
10218 operands [2] = force_reg (SImode, operands[2]);
10220 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10222 [(set_attr "type" "rotate")
10223 (set_attr "mode" "<MODE>")])
10225 ;; Implement rotation using two double-precision
10226 ;; shift instructions and a scratch register.
10228 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10229 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10230 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10231 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10232 (clobber (reg:CC FLAGS_REG))
10233 (clobber (match_scratch:DWIH 3 "=&r"))]
10237 [(set (match_dup 3) (match_dup 4))
10239 [(set (match_dup 4)
10240 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10241 (lshiftrt:DWIH (match_dup 5)
10242 (minus:QI (match_dup 6) (match_dup 2)))))
10243 (clobber (reg:CC FLAGS_REG))])
10245 [(set (match_dup 5)
10246 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10247 (lshiftrt:DWIH (match_dup 3)
10248 (minus:QI (match_dup 6) (match_dup 2)))))
10249 (clobber (reg:CC FLAGS_REG))])]
10251 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10253 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10256 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10257 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10258 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10259 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10260 (clobber (reg:CC FLAGS_REG))
10261 (clobber (match_scratch:DWIH 3 "=&r"))]
10265 [(set (match_dup 3) (match_dup 4))
10267 [(set (match_dup 4)
10268 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10269 (ashift:DWIH (match_dup 5)
10270 (minus:QI (match_dup 6) (match_dup 2)))))
10271 (clobber (reg:CC FLAGS_REG))])
10273 [(set (match_dup 5)
10274 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10275 (ashift:DWIH (match_dup 3)
10276 (minus:QI (match_dup 6) (match_dup 2)))))
10277 (clobber (reg:CC FLAGS_REG))])]
10279 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10281 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10284 (define_insn "*<rotate_insn><mode>3_1"
10285 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10286 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10287 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10288 (clobber (reg:CC FLAGS_REG))]
10289 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10291 if (operands[2] == const1_rtx
10292 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10293 return "<rotate>{<imodesuffix>}\t%0";
10295 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10297 [(set_attr "type" "rotate")
10298 (set (attr "length_immediate")
10300 (and (match_operand 2 "const1_operand" "")
10301 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10304 (const_string "*")))
10305 (set_attr "mode" "<MODE>")])
10307 (define_insn "*<rotate_insn>si3_1_zext"
10308 [(set (match_operand:DI 0 "register_operand" "=r")
10310 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10311 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10312 (clobber (reg:CC FLAGS_REG))]
10313 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10315 if (operands[2] == const1_rtx
10316 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10317 return "<rotate>{l}\t%k0";
10319 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10321 [(set_attr "type" "rotate")
10322 (set (attr "length_immediate")
10324 (and (match_operand 2 "const1_operand" "")
10325 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10328 (const_string "*")))
10329 (set_attr "mode" "SI")])
10331 (define_insn "*<rotate_insn>qi3_1_slp"
10332 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10333 (any_rotate:QI (match_dup 0)
10334 (match_operand:QI 1 "nonmemory_operand" "cI")))
10335 (clobber (reg:CC FLAGS_REG))]
10336 "(optimize_function_for_size_p (cfun)
10337 || !TARGET_PARTIAL_REG_STALL
10338 || (operands[1] == const1_rtx
10339 && TARGET_SHIFT1))"
10341 if (operands[1] == const1_rtx
10342 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10343 return "<rotate>{b}\t%0";
10345 return "<rotate>{b}\t{%1, %0|%0, %1}";
10347 [(set_attr "type" "rotate1")
10348 (set (attr "length_immediate")
10350 (and (match_operand 1 "const1_operand" "")
10351 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10354 (const_string "*")))
10355 (set_attr "mode" "QI")])
10358 [(set (match_operand:HI 0 "register_operand" "")
10359 (any_rotate:HI (match_dup 0) (const_int 8)))
10360 (clobber (reg:CC FLAGS_REG))]
10362 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10363 [(parallel [(set (strict_low_part (match_dup 0))
10364 (bswap:HI (match_dup 0)))
10365 (clobber (reg:CC FLAGS_REG))])])
10367 ;; Bit set / bit test instructions
10369 (define_expand "extv"
10370 [(set (match_operand:SI 0 "register_operand" "")
10371 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10372 (match_operand:SI 2 "const8_operand" "")
10373 (match_operand:SI 3 "const8_operand" "")))]
10376 /* Handle extractions from %ah et al. */
10377 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10380 /* From mips.md: extract_bit_field doesn't verify that our source
10381 matches the predicate, so check it again here. */
10382 if (! ext_register_operand (operands[1], VOIDmode))
10386 (define_expand "extzv"
10387 [(set (match_operand:SI 0 "register_operand" "")
10388 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10389 (match_operand:SI 2 "const8_operand" "")
10390 (match_operand:SI 3 "const8_operand" "")))]
10393 /* Handle extractions from %ah et al. */
10394 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10397 /* From mips.md: extract_bit_field doesn't verify that our source
10398 matches the predicate, so check it again here. */
10399 if (! ext_register_operand (operands[1], VOIDmode))
10403 (define_expand "insv"
10404 [(set (zero_extract (match_operand 0 "register_operand" "")
10405 (match_operand 1 "const_int_operand" "")
10406 (match_operand 2 "const_int_operand" ""))
10407 (match_operand 3 "register_operand" ""))]
10410 rtx (*gen_mov_insv_1) (rtx, rtx);
10412 if (ix86_expand_pinsr (operands))
10415 /* Handle insertions to %ah et al. */
10416 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10419 /* From mips.md: insert_bit_field doesn't verify that our source
10420 matches the predicate, so check it again here. */
10421 if (! ext_register_operand (operands[0], VOIDmode))
10424 gen_mov_insv_1 = (TARGET_64BIT
10425 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10427 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10431 ;; %%% bts, btr, btc, bt.
10432 ;; In general these instructions are *slow* when applied to memory,
10433 ;; since they enforce atomic operation. When applied to registers,
10434 ;; it depends on the cpu implementation. They're never faster than
10435 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10436 ;; no point. But in 64-bit, we can't hold the relevant immediates
10437 ;; within the instruction itself, so operating on bits in the high
10438 ;; 32-bits of a register becomes easier.
10440 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10441 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10442 ;; negdf respectively, so they can never be disabled entirely.
10444 (define_insn "*btsq"
10445 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10447 (match_operand:DI 1 "const_0_to_63_operand" ""))
10449 (clobber (reg:CC FLAGS_REG))]
10450 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10451 "bts{q}\t{%1, %0|%0, %1}"
10452 [(set_attr "type" "alu1")
10453 (set_attr "prefix_0f" "1")
10454 (set_attr "mode" "DI")])
10456 (define_insn "*btrq"
10457 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10459 (match_operand:DI 1 "const_0_to_63_operand" ""))
10461 (clobber (reg:CC FLAGS_REG))]
10462 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10463 "btr{q}\t{%1, %0|%0, %1}"
10464 [(set_attr "type" "alu1")
10465 (set_attr "prefix_0f" "1")
10466 (set_attr "mode" "DI")])
10468 (define_insn "*btcq"
10469 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10471 (match_operand:DI 1 "const_0_to_63_operand" ""))
10472 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10473 (clobber (reg:CC FLAGS_REG))]
10474 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10475 "btc{q}\t{%1, %0|%0, %1}"
10476 [(set_attr "type" "alu1")
10477 (set_attr "prefix_0f" "1")
10478 (set_attr "mode" "DI")])
10480 ;; Allow Nocona to avoid these instructions if a register is available.
10483 [(match_scratch:DI 2 "r")
10484 (parallel [(set (zero_extract:DI
10485 (match_operand:DI 0 "register_operand" "")
10487 (match_operand:DI 1 "const_0_to_63_operand" ""))
10489 (clobber (reg:CC FLAGS_REG))])]
10490 "TARGET_64BIT && !TARGET_USE_BT"
10493 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10496 if (HOST_BITS_PER_WIDE_INT >= 64)
10497 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10498 else if (i < HOST_BITS_PER_WIDE_INT)
10499 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10501 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10503 op1 = immed_double_const (lo, hi, DImode);
10506 emit_move_insn (operands[2], op1);
10510 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10515 [(match_scratch:DI 2 "r")
10516 (parallel [(set (zero_extract:DI
10517 (match_operand:DI 0 "register_operand" "")
10519 (match_operand:DI 1 "const_0_to_63_operand" ""))
10521 (clobber (reg:CC FLAGS_REG))])]
10522 "TARGET_64BIT && !TARGET_USE_BT"
10525 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10528 if (HOST_BITS_PER_WIDE_INT >= 64)
10529 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10530 else if (i < HOST_BITS_PER_WIDE_INT)
10531 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10533 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10535 op1 = immed_double_const (~lo, ~hi, DImode);
10538 emit_move_insn (operands[2], op1);
10542 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10547 [(match_scratch:DI 2 "r")
10548 (parallel [(set (zero_extract:DI
10549 (match_operand:DI 0 "register_operand" "")
10551 (match_operand:DI 1 "const_0_to_63_operand" ""))
10552 (not:DI (zero_extract:DI
10553 (match_dup 0) (const_int 1) (match_dup 1))))
10554 (clobber (reg:CC FLAGS_REG))])]
10555 "TARGET_64BIT && !TARGET_USE_BT"
10558 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10561 if (HOST_BITS_PER_WIDE_INT >= 64)
10562 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10563 else if (i < HOST_BITS_PER_WIDE_INT)
10564 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10566 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10568 op1 = immed_double_const (lo, hi, DImode);
10571 emit_move_insn (operands[2], op1);
10575 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10579 (define_insn "*bt<mode>"
10580 [(set (reg:CCC FLAGS_REG)
10582 (zero_extract:SWI48
10583 (match_operand:SWI48 0 "register_operand" "r")
10585 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10587 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10588 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10589 [(set_attr "type" "alu1")
10590 (set_attr "prefix_0f" "1")
10591 (set_attr "mode" "<MODE>")])
10593 ;; Store-flag instructions.
10595 ;; For all sCOND expanders, also expand the compare or test insn that
10596 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10598 (define_insn_and_split "*setcc_di_1"
10599 [(set (match_operand:DI 0 "register_operand" "=q")
10600 (match_operator:DI 1 "ix86_comparison_operator"
10601 [(reg FLAGS_REG) (const_int 0)]))]
10602 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10604 "&& reload_completed"
10605 [(set (match_dup 2) (match_dup 1))
10606 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10608 PUT_MODE (operands[1], QImode);
10609 operands[2] = gen_lowpart (QImode, operands[0]);
10612 (define_insn_and_split "*setcc_si_1_and"
10613 [(set (match_operand:SI 0 "register_operand" "=q")
10614 (match_operator:SI 1 "ix86_comparison_operator"
10615 [(reg FLAGS_REG) (const_int 0)]))
10616 (clobber (reg:CC FLAGS_REG))]
10617 "!TARGET_PARTIAL_REG_STALL
10618 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10620 "&& reload_completed"
10621 [(set (match_dup 2) (match_dup 1))
10622 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10623 (clobber (reg:CC FLAGS_REG))])]
10625 PUT_MODE (operands[1], QImode);
10626 operands[2] = gen_lowpart (QImode, operands[0]);
10629 (define_insn_and_split "*setcc_si_1_movzbl"
10630 [(set (match_operand:SI 0 "register_operand" "=q")
10631 (match_operator:SI 1 "ix86_comparison_operator"
10632 [(reg FLAGS_REG) (const_int 0)]))]
10633 "!TARGET_PARTIAL_REG_STALL
10634 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10636 "&& reload_completed"
10637 [(set (match_dup 2) (match_dup 1))
10638 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10640 PUT_MODE (operands[1], QImode);
10641 operands[2] = gen_lowpart (QImode, operands[0]);
10644 (define_insn "*setcc_qi"
10645 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10646 (match_operator:QI 1 "ix86_comparison_operator"
10647 [(reg FLAGS_REG) (const_int 0)]))]
10650 [(set_attr "type" "setcc")
10651 (set_attr "mode" "QI")])
10653 (define_insn "*setcc_qi_slp"
10654 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10655 (match_operator:QI 1 "ix86_comparison_operator"
10656 [(reg FLAGS_REG) (const_int 0)]))]
10659 [(set_attr "type" "setcc")
10660 (set_attr "mode" "QI")])
10662 ;; In general it is not safe to assume too much about CCmode registers,
10663 ;; so simplify-rtx stops when it sees a second one. Under certain
10664 ;; conditions this is safe on x86, so help combine not create
10671 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10672 (ne:QI (match_operator 1 "ix86_comparison_operator"
10673 [(reg FLAGS_REG) (const_int 0)])
10676 [(set (match_dup 0) (match_dup 1))]
10677 "PUT_MODE (operands[1], QImode);")
10680 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10681 (ne:QI (match_operator 1 "ix86_comparison_operator"
10682 [(reg FLAGS_REG) (const_int 0)])
10685 [(set (match_dup 0) (match_dup 1))]
10686 "PUT_MODE (operands[1], QImode);")
10689 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10690 (eq:QI (match_operator 1 "ix86_comparison_operator"
10691 [(reg FLAGS_REG) (const_int 0)])
10694 [(set (match_dup 0) (match_dup 1))]
10696 rtx new_op1 = copy_rtx (operands[1]);
10697 operands[1] = new_op1;
10698 PUT_MODE (new_op1, QImode);
10699 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10700 GET_MODE (XEXP (new_op1, 0))));
10702 /* Make sure that (a) the CCmode we have for the flags is strong
10703 enough for the reversed compare or (b) we have a valid FP compare. */
10704 if (! ix86_comparison_operator (new_op1, VOIDmode))
10709 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10710 (eq:QI (match_operator 1 "ix86_comparison_operator"
10711 [(reg FLAGS_REG) (const_int 0)])
10714 [(set (match_dup 0) (match_dup 1))]
10716 rtx new_op1 = copy_rtx (operands[1]);
10717 operands[1] = new_op1;
10718 PUT_MODE (new_op1, QImode);
10719 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10720 GET_MODE (XEXP (new_op1, 0))));
10722 /* Make sure that (a) the CCmode we have for the flags is strong
10723 enough for the reversed compare or (b) we have a valid FP compare. */
10724 if (! ix86_comparison_operator (new_op1, VOIDmode))
10728 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10729 ;; subsequent logical operations are used to imitate conditional moves.
10730 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10733 (define_insn "setcc_<mode>_sse"
10734 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10735 (match_operator:MODEF 3 "sse_comparison_operator"
10736 [(match_operand:MODEF 1 "register_operand" "0,x")
10737 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10738 "SSE_FLOAT_MODE_P (<MODE>mode)"
10740 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10741 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10742 [(set_attr "isa" "noavx,avx")
10743 (set_attr "type" "ssecmp")
10744 (set_attr "length_immediate" "1")
10745 (set_attr "prefix" "orig,vex")
10746 (set_attr "mode" "<MODE>")])
10748 ;; Basic conditional jump instructions.
10749 ;; We ignore the overflow flag for signed branch instructions.
10751 (define_insn "*jcc_1"
10753 (if_then_else (match_operator 1 "ix86_comparison_operator"
10754 [(reg FLAGS_REG) (const_int 0)])
10755 (label_ref (match_operand 0 "" ""))
10759 [(set_attr "type" "ibr")
10760 (set_attr "modrm" "0")
10761 (set (attr "length")
10762 (if_then_else (and (ge (minus (match_dup 0) (pc))
10764 (lt (minus (match_dup 0) (pc))
10769 (define_insn "*jcc_2"
10771 (if_then_else (match_operator 1 "ix86_comparison_operator"
10772 [(reg FLAGS_REG) (const_int 0)])
10774 (label_ref (match_operand 0 "" ""))))]
10777 [(set_attr "type" "ibr")
10778 (set_attr "modrm" "0")
10779 (set (attr "length")
10780 (if_then_else (and (ge (minus (match_dup 0) (pc))
10782 (lt (minus (match_dup 0) (pc))
10787 ;; In general it is not safe to assume too much about CCmode registers,
10788 ;; so simplify-rtx stops when it sees a second one. Under certain
10789 ;; conditions this is safe on x86, so help combine not create
10797 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10798 [(reg FLAGS_REG) (const_int 0)])
10800 (label_ref (match_operand 1 "" ""))
10804 (if_then_else (match_dup 0)
10805 (label_ref (match_dup 1))
10807 "PUT_MODE (operands[0], VOIDmode);")
10811 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10812 [(reg FLAGS_REG) (const_int 0)])
10814 (label_ref (match_operand 1 "" ""))
10818 (if_then_else (match_dup 0)
10819 (label_ref (match_dup 1))
10822 rtx new_op0 = copy_rtx (operands[0]);
10823 operands[0] = new_op0;
10824 PUT_MODE (new_op0, VOIDmode);
10825 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10826 GET_MODE (XEXP (new_op0, 0))));
10828 /* Make sure that (a) the CCmode we have for the flags is strong
10829 enough for the reversed compare or (b) we have a valid FP compare. */
10830 if (! ix86_comparison_operator (new_op0, VOIDmode))
10834 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10835 ;; pass generates from shift insn with QImode operand. Actually, the mode
10836 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10837 ;; appropriate modulo of the bit offset value.
10839 (define_insn_and_split "*jcc_bt<mode>"
10841 (if_then_else (match_operator 0 "bt_comparison_operator"
10842 [(zero_extract:SWI48
10843 (match_operand:SWI48 1 "register_operand" "r")
10846 (match_operand:QI 2 "register_operand" "r")))
10848 (label_ref (match_operand 3 "" ""))
10850 (clobber (reg:CC FLAGS_REG))]
10851 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10854 [(set (reg:CCC FLAGS_REG)
10856 (zero_extract:SWI48
10862 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10863 (label_ref (match_dup 3))
10866 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10868 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10871 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10872 ;; also for DImode, this is what combine produces.
10873 (define_insn_and_split "*jcc_bt<mode>_mask"
10875 (if_then_else (match_operator 0 "bt_comparison_operator"
10876 [(zero_extract:SWI48
10877 (match_operand:SWI48 1 "register_operand" "r")
10880 (match_operand:SI 2 "register_operand" "r")
10881 (match_operand:SI 3 "const_int_operand" "n")))])
10882 (label_ref (match_operand 4 "" ""))
10884 (clobber (reg:CC FLAGS_REG))]
10885 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10886 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10887 == GET_MODE_BITSIZE (<MODE>mode)-1"
10890 [(set (reg:CCC FLAGS_REG)
10892 (zero_extract:SWI48
10898 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10899 (label_ref (match_dup 4))
10902 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10904 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10907 (define_insn_and_split "*jcc_btsi_1"
10909 (if_then_else (match_operator 0 "bt_comparison_operator"
10912 (match_operand:SI 1 "register_operand" "r")
10913 (match_operand:QI 2 "register_operand" "r"))
10916 (label_ref (match_operand 3 "" ""))
10918 (clobber (reg:CC FLAGS_REG))]
10919 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10922 [(set (reg:CCC FLAGS_REG)
10930 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10931 (label_ref (match_dup 3))
10934 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10936 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10939 ;; avoid useless masking of bit offset operand
10940 (define_insn_and_split "*jcc_btsi_mask_1"
10943 (match_operator 0 "bt_comparison_operator"
10946 (match_operand:SI 1 "register_operand" "r")
10949 (match_operand:SI 2 "register_operand" "r")
10950 (match_operand:SI 3 "const_int_operand" "n")) 0))
10953 (label_ref (match_operand 4 "" ""))
10955 (clobber (reg:CC FLAGS_REG))]
10956 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10957 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10960 [(set (reg:CCC FLAGS_REG)
10968 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10969 (label_ref (match_dup 4))
10971 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10973 ;; Define combination compare-and-branch fp compare instructions to help
10976 (define_insn "*fp_jcc_1_387"
10978 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10979 [(match_operand 1 "register_operand" "f")
10980 (match_operand 2 "nonimmediate_operand" "fm")])
10981 (label_ref (match_operand 3 "" ""))
10983 (clobber (reg:CCFP FPSR_REG))
10984 (clobber (reg:CCFP FLAGS_REG))
10985 (clobber (match_scratch:HI 4 "=a"))]
10987 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10988 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10989 && SELECT_CC_MODE (GET_CODE (operands[0]),
10990 operands[1], operands[2]) == CCFPmode
10994 (define_insn "*fp_jcc_1r_387"
10996 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10997 [(match_operand 1 "register_operand" "f")
10998 (match_operand 2 "nonimmediate_operand" "fm")])
11000 (label_ref (match_operand 3 "" ""))))
11001 (clobber (reg:CCFP FPSR_REG))
11002 (clobber (reg:CCFP FLAGS_REG))
11003 (clobber (match_scratch:HI 4 "=a"))]
11005 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11006 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11007 && SELECT_CC_MODE (GET_CODE (operands[0]),
11008 operands[1], operands[2]) == CCFPmode
11012 (define_insn "*fp_jcc_2_387"
11014 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11015 [(match_operand 1 "register_operand" "f")
11016 (match_operand 2 "register_operand" "f")])
11017 (label_ref (match_operand 3 "" ""))
11019 (clobber (reg:CCFP FPSR_REG))
11020 (clobber (reg:CCFP FLAGS_REG))
11021 (clobber (match_scratch:HI 4 "=a"))]
11022 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11023 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11027 (define_insn "*fp_jcc_2r_387"
11029 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11030 [(match_operand 1 "register_operand" "f")
11031 (match_operand 2 "register_operand" "f")])
11033 (label_ref (match_operand 3 "" ""))))
11034 (clobber (reg:CCFP FPSR_REG))
11035 (clobber (reg:CCFP FLAGS_REG))
11036 (clobber (match_scratch:HI 4 "=a"))]
11037 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11038 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11042 (define_insn "*fp_jcc_3_387"
11044 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11045 [(match_operand 1 "register_operand" "f")
11046 (match_operand 2 "const0_operand" "")])
11047 (label_ref (match_operand 3 "" ""))
11049 (clobber (reg:CCFP FPSR_REG))
11050 (clobber (reg:CCFP FLAGS_REG))
11051 (clobber (match_scratch:HI 4 "=a"))]
11052 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11053 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11054 && SELECT_CC_MODE (GET_CODE (operands[0]),
11055 operands[1], operands[2]) == CCFPmode
11061 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11062 [(match_operand 1 "register_operand" "")
11063 (match_operand 2 "nonimmediate_operand" "")])
11064 (match_operand 3 "" "")
11065 (match_operand 4 "" "")))
11066 (clobber (reg:CCFP FPSR_REG))
11067 (clobber (reg:CCFP FLAGS_REG))]
11071 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11072 operands[3], operands[4], NULL_RTX, NULL_RTX);
11078 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11079 [(match_operand 1 "register_operand" "")
11080 (match_operand 2 "general_operand" "")])
11081 (match_operand 3 "" "")
11082 (match_operand 4 "" "")))
11083 (clobber (reg:CCFP FPSR_REG))
11084 (clobber (reg:CCFP FLAGS_REG))
11085 (clobber (match_scratch:HI 5 "=a"))]
11089 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11090 operands[3], operands[4], operands[5], NULL_RTX);
11094 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11095 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11096 ;; with a precedence over other operators and is always put in the first
11097 ;; place. Swap condition and operands to match ficom instruction.
11099 (define_insn "*fp_jcc_4_<mode>_387"
11102 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11103 [(match_operator 1 "float_operator"
11104 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11105 (match_operand 3 "register_operand" "f,f")])
11106 (label_ref (match_operand 4 "" ""))
11108 (clobber (reg:CCFP FPSR_REG))
11109 (clobber (reg:CCFP FLAGS_REG))
11110 (clobber (match_scratch:HI 5 "=a,a"))]
11111 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11112 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11113 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11114 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11121 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11122 [(match_operator 1 "float_operator"
11123 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11124 (match_operand 3 "register_operand" "")])
11125 (match_operand 4 "" "")
11126 (match_operand 5 "" "")))
11127 (clobber (reg:CCFP FPSR_REG))
11128 (clobber (reg:CCFP FLAGS_REG))
11129 (clobber (match_scratch:HI 6 "=a"))]
11133 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11135 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11136 operands[3], operands[7],
11137 operands[4], operands[5], operands[6], NULL_RTX);
11141 ;; %%% Kill this when reload knows how to do it.
11145 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11146 [(match_operator 1 "float_operator"
11147 [(match_operand:X87MODEI12 2 "register_operand" "")])
11148 (match_operand 3 "register_operand" "")])
11149 (match_operand 4 "" "")
11150 (match_operand 5 "" "")))
11151 (clobber (reg:CCFP FPSR_REG))
11152 (clobber (reg:CCFP FLAGS_REG))
11153 (clobber (match_scratch:HI 6 "=a"))]
11157 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11158 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11160 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11161 operands[3], operands[7],
11162 operands[4], operands[5], operands[6], operands[2]);
11166 ;; Unconditional and other jump instructions
11168 (define_insn "jump"
11170 (label_ref (match_operand 0 "" "")))]
11173 [(set_attr "type" "ibr")
11174 (set (attr "length")
11175 (if_then_else (and (ge (minus (match_dup 0) (pc))
11177 (lt (minus (match_dup 0) (pc))
11181 (set_attr "modrm" "0")])
11183 (define_expand "indirect_jump"
11184 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11188 (define_insn "*indirect_jump"
11189 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11192 [(set_attr "type" "ibr")
11193 (set_attr "length_immediate" "0")])
11195 (define_expand "tablejump"
11196 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11197 (use (label_ref (match_operand 1 "" "")))])]
11200 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11201 relative. Convert the relative address to an absolute address. */
11205 enum rtx_code code;
11207 /* We can't use @GOTOFF for text labels on VxWorks;
11208 see gotoff_operand. */
11209 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11213 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11215 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11219 op1 = pic_offset_table_rtx;
11224 op0 = pic_offset_table_rtx;
11228 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11233 (define_insn "*tablejump_1"
11234 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11235 (use (label_ref (match_operand 1 "" "")))]
11238 [(set_attr "type" "ibr")
11239 (set_attr "length_immediate" "0")])
11241 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11244 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11245 (set (match_operand:QI 1 "register_operand" "")
11246 (match_operator:QI 2 "ix86_comparison_operator"
11247 [(reg FLAGS_REG) (const_int 0)]))
11248 (set (match_operand 3 "q_regs_operand" "")
11249 (zero_extend (match_dup 1)))]
11250 "(peep2_reg_dead_p (3, operands[1])
11251 || operands_match_p (operands[1], operands[3]))
11252 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11253 [(set (match_dup 4) (match_dup 0))
11254 (set (strict_low_part (match_dup 5))
11257 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11258 operands[5] = gen_lowpart (QImode, operands[3]);
11259 ix86_expand_clear (operands[3]);
11262 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11265 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11266 (set (match_operand:QI 1 "register_operand" "")
11267 (match_operator:QI 2 "ix86_comparison_operator"
11268 [(reg FLAGS_REG) (const_int 0)]))
11269 (parallel [(set (match_operand 3 "q_regs_operand" "")
11270 (zero_extend (match_dup 1)))
11271 (clobber (reg:CC FLAGS_REG))])]
11272 "(peep2_reg_dead_p (3, operands[1])
11273 || operands_match_p (operands[1], operands[3]))
11274 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11275 [(set (match_dup 4) (match_dup 0))
11276 (set (strict_low_part (match_dup 5))
11279 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11280 operands[5] = gen_lowpart (QImode, operands[3]);
11281 ix86_expand_clear (operands[3]);
11284 ;; Call instructions.
11286 ;; The predicates normally associated with named expanders are not properly
11287 ;; checked for calls. This is a bug in the generic code, but it isn't that
11288 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11290 ;; P6 processors will jump to the address after the decrement when %esp
11291 ;; is used as a call operand, so they will execute return address as a code.
11292 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11294 ;; Call subroutine returning no value.
11296 (define_expand "call_pop"
11297 [(parallel [(call (match_operand:QI 0 "" "")
11298 (match_operand:SI 1 "" ""))
11299 (set (reg:SI SP_REG)
11300 (plus:SI (reg:SI SP_REG)
11301 (match_operand:SI 3 "" "")))])]
11304 ix86_expand_call (NULL, operands[0], operands[1],
11305 operands[2], operands[3], 0);
11309 (define_insn_and_split "*call_pop_0_vzeroupper"
11311 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11312 (match_operand:SI 1 "" ""))
11313 (set (reg:SI SP_REG)
11314 (plus:SI (reg:SI SP_REG)
11315 (match_operand:SI 2 "immediate_operand" "")))])
11316 (unspec [(match_operand 3 "const_int_operand" "")]
11317 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11318 "TARGET_VZEROUPPER && !TARGET_64BIT"
11320 "&& reload_completed"
11322 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11323 [(set_attr "type" "call")])
11325 (define_insn "*call_pop_0"
11326 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11327 (match_operand:SI 1 "" ""))
11328 (set (reg:SI SP_REG)
11329 (plus:SI (reg:SI SP_REG)
11330 (match_operand:SI 2 "immediate_operand" "")))]
11333 if (SIBLING_CALL_P (insn))
11336 return "call\t%P0";
11338 [(set_attr "type" "call")])
11340 (define_insn_and_split "*call_pop_1_vzeroupper"
11342 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11343 (match_operand:SI 1 "" ""))
11344 (set (reg:SI SP_REG)
11345 (plus:SI (reg:SI SP_REG)
11346 (match_operand:SI 2 "immediate_operand" "i")))])
11347 (unspec [(match_operand 3 "const_int_operand" "")]
11348 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11349 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11351 "&& reload_completed"
11353 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11354 [(set_attr "type" "call")])
11356 (define_insn "*call_pop_1"
11357 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11358 (match_operand:SI 1 "" ""))
11359 (set (reg:SI SP_REG)
11360 (plus:SI (reg:SI SP_REG)
11361 (match_operand:SI 2 "immediate_operand" "i")))]
11362 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11364 if (constant_call_address_operand (operands[0], Pmode))
11365 return "call\t%P0";
11366 return "call\t%A0";
11368 [(set_attr "type" "call")])
11370 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11372 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11373 (match_operand:SI 1 "" ""))
11374 (set (reg:SI SP_REG)
11375 (plus:SI (reg:SI SP_REG)
11376 (match_operand:SI 2 "immediate_operand" "i,i")))])
11377 (unspec [(match_operand 3 "const_int_operand" "")]
11378 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11379 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11381 "&& reload_completed"
11383 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11384 [(set_attr "type" "call")])
11386 (define_insn "*sibcall_pop_1"
11387 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11388 (match_operand:SI 1 "" ""))
11389 (set (reg:SI SP_REG)
11390 (plus:SI (reg:SI SP_REG)
11391 (match_operand:SI 2 "immediate_operand" "i,i")))]
11392 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11396 [(set_attr "type" "call")])
11398 (define_expand "call"
11399 [(call (match_operand:QI 0 "" "")
11400 (match_operand 1 "" ""))
11401 (use (match_operand 2 "" ""))]
11404 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11408 (define_expand "sibcall"
11409 [(call (match_operand:QI 0 "" "")
11410 (match_operand 1 "" ""))
11411 (use (match_operand 2 "" ""))]
11414 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11418 (define_insn_and_split "*call_0_vzeroupper"
11419 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11420 (match_operand 1 "" ""))
11421 (unspec [(match_operand 2 "const_int_operand" "")]
11422 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11423 "TARGET_VZEROUPPER"
11425 "&& reload_completed"
11427 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11428 [(set_attr "type" "call")])
11430 (define_insn "*call_0"
11431 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11432 (match_operand 1 "" ""))]
11434 { return ix86_output_call_insn (insn, operands[0], 0); }
11435 [(set_attr "type" "call")])
11437 (define_insn_and_split "*call_1_vzeroupper"
11438 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11439 (match_operand 1 "" ""))
11440 (unspec [(match_operand 2 "const_int_operand" "")]
11441 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11442 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11444 "&& reload_completed"
11446 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11447 [(set_attr "type" "call")])
11449 (define_insn "*call_1"
11450 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11451 (match_operand 1 "" ""))]
11452 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11453 { return ix86_output_call_insn (insn, operands[0], 0); }
11454 [(set_attr "type" "call")])
11456 (define_insn_and_split "*sibcall_1_vzeroupper"
11457 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11458 (match_operand 1 "" ""))
11459 (unspec [(match_operand 2 "const_int_operand" "")]
11460 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11461 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11463 "&& reload_completed"
11465 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11466 [(set_attr "type" "call")])
11468 (define_insn "*sibcall_1"
11469 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11470 (match_operand 1 "" ""))]
11471 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11472 { return ix86_output_call_insn (insn, operands[0], 0); }
11473 [(set_attr "type" "call")])
11475 (define_insn_and_split "*call_1_rex64_vzeroupper"
11476 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11477 (match_operand 1 "" ""))
11478 (unspec [(match_operand 2 "const_int_operand" "")]
11479 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11480 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11481 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11483 "&& reload_completed"
11485 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11486 [(set_attr "type" "call")])
11488 (define_insn "*call_1_rex64"
11489 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11490 (match_operand 1 "" ""))]
11491 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11492 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11493 { return ix86_output_call_insn (insn, operands[0], 0); }
11494 [(set_attr "type" "call")])
11496 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11498 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11499 (match_operand 1 "" ""))
11500 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11501 (clobber (reg:TI XMM6_REG))
11502 (clobber (reg:TI XMM7_REG))
11503 (clobber (reg:TI XMM8_REG))
11504 (clobber (reg:TI XMM9_REG))
11505 (clobber (reg:TI XMM10_REG))
11506 (clobber (reg:TI XMM11_REG))
11507 (clobber (reg:TI XMM12_REG))
11508 (clobber (reg:TI XMM13_REG))
11509 (clobber (reg:TI XMM14_REG))
11510 (clobber (reg:TI XMM15_REG))
11511 (clobber (reg:DI SI_REG))
11512 (clobber (reg:DI DI_REG))])
11513 (unspec [(match_operand 2 "const_int_operand" "")]
11514 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11515 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11517 "&& reload_completed"
11519 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11520 [(set_attr "type" "call")])
11522 (define_insn "*call_1_rex64_ms_sysv"
11523 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11524 (match_operand 1 "" ""))
11525 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11526 (clobber (reg:TI XMM6_REG))
11527 (clobber (reg:TI XMM7_REG))
11528 (clobber (reg:TI XMM8_REG))
11529 (clobber (reg:TI XMM9_REG))
11530 (clobber (reg:TI XMM10_REG))
11531 (clobber (reg:TI XMM11_REG))
11532 (clobber (reg:TI XMM12_REG))
11533 (clobber (reg:TI XMM13_REG))
11534 (clobber (reg:TI XMM14_REG))
11535 (clobber (reg:TI XMM15_REG))
11536 (clobber (reg:DI SI_REG))
11537 (clobber (reg:DI DI_REG))]
11538 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11539 { return ix86_output_call_insn (insn, operands[0], 0); }
11540 [(set_attr "type" "call")])
11542 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11543 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11544 (match_operand 1 "" ""))
11545 (unspec [(match_operand 2 "const_int_operand" "")]
11546 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11547 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11549 "&& reload_completed"
11551 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11552 [(set_attr "type" "call")])
11554 (define_insn "*call_1_rex64_large"
11555 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11556 (match_operand 1 "" ""))]
11557 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11558 { return ix86_output_call_insn (insn, operands[0], 0); }
11559 [(set_attr "type" "call")])
11561 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11562 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11563 (match_operand 1 "" ""))
11564 (unspec [(match_operand 2 "const_int_operand" "")]
11565 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11566 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11568 "&& reload_completed"
11570 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11571 [(set_attr "type" "call")])
11573 (define_insn "*sibcall_1_rex64"
11574 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11575 (match_operand 1 "" ""))]
11576 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11577 { return ix86_output_call_insn (insn, operands[0], 0); }
11578 [(set_attr "type" "call")])
11580 ;; Call subroutine, returning value in operand 0
11581 (define_expand "call_value_pop"
11582 [(parallel [(set (match_operand 0 "" "")
11583 (call (match_operand:QI 1 "" "")
11584 (match_operand:SI 2 "" "")))
11585 (set (reg:SI SP_REG)
11586 (plus:SI (reg:SI SP_REG)
11587 (match_operand:SI 4 "" "")))])]
11590 ix86_expand_call (operands[0], operands[1], operands[2],
11591 operands[3], operands[4], 0);
11595 (define_expand "call_value"
11596 [(set (match_operand 0 "" "")
11597 (call (match_operand:QI 1 "" "")
11598 (match_operand:SI 2 "" "")))
11599 (use (match_operand:SI 3 "" ""))]
11600 ;; Operand 3 is not used on the i386.
11603 ix86_expand_call (operands[0], operands[1], operands[2],
11604 operands[3], NULL, 0);
11608 (define_expand "sibcall_value"
11609 [(set (match_operand 0 "" "")
11610 (call (match_operand:QI 1 "" "")
11611 (match_operand:SI 2 "" "")))
11612 (use (match_operand:SI 3 "" ""))]
11613 ;; Operand 3 is not used on the i386.
11616 ix86_expand_call (operands[0], operands[1], operands[2],
11617 operands[3], NULL, 1);
11621 ;; Call subroutine returning any type.
11623 (define_expand "untyped_call"
11624 [(parallel [(call (match_operand 0 "" "")
11626 (match_operand 1 "" "")
11627 (match_operand 2 "" "")])]
11632 /* In order to give reg-stack an easier job in validating two
11633 coprocessor registers as containing a possible return value,
11634 simply pretend the untyped call returns a complex long double
11637 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11638 and should have the default ABI. */
11640 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11641 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11642 operands[0], const0_rtx,
11643 GEN_INT ((TARGET_64BIT
11644 ? (ix86_abi == SYSV_ABI
11645 ? X86_64_SSE_REGPARM_MAX
11646 : X86_64_MS_SSE_REGPARM_MAX)
11647 : X86_32_SSE_REGPARM_MAX)
11651 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11653 rtx set = XVECEXP (operands[2], 0, i);
11654 emit_move_insn (SET_DEST (set), SET_SRC (set));
11657 /* The optimizer does not know that the call sets the function value
11658 registers we stored in the result block. We avoid problems by
11659 claiming that all hard registers are used and clobbered at this
11661 emit_insn (gen_blockage ());
11666 ;; Prologue and epilogue instructions
11668 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11669 ;; all of memory. This blocks insns from being moved across this point.
11671 (define_insn "blockage"
11672 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11675 [(set_attr "length" "0")])
11677 ;; Do not schedule instructions accessing memory across this point.
11679 (define_expand "memory_blockage"
11680 [(set (match_dup 0)
11681 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11684 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11685 MEM_VOLATILE_P (operands[0]) = 1;
11688 (define_insn "*memory_blockage"
11689 [(set (match_operand:BLK 0 "" "")
11690 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11693 [(set_attr "length" "0")])
11695 ;; As USE insns aren't meaningful after reload, this is used instead
11696 ;; to prevent deleting instructions setting registers for PIC code
11697 (define_insn "prologue_use"
11698 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11701 [(set_attr "length" "0")])
11703 ;; Insn emitted into the body of a function to return from a function.
11704 ;; This is only done if the function's epilogue is known to be simple.
11705 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11707 (define_expand "return"
11709 "ix86_can_use_return_insn_p ()"
11711 if (crtl->args.pops_args)
11713 rtx popc = GEN_INT (crtl->args.pops_args);
11714 emit_jump_insn (gen_return_pop_internal (popc));
11719 (define_insn "return_internal"
11723 [(set_attr "length" "1")
11724 (set_attr "atom_unit" "jeu")
11725 (set_attr "length_immediate" "0")
11726 (set_attr "modrm" "0")])
11728 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11729 ;; instruction Athlon and K8 have.
11731 (define_insn "return_internal_long"
11733 (unspec [(const_int 0)] UNSPEC_REP)]
11736 [(set_attr "length" "2")
11737 (set_attr "atom_unit" "jeu")
11738 (set_attr "length_immediate" "0")
11739 (set_attr "prefix_rep" "1")
11740 (set_attr "modrm" "0")])
11742 (define_insn "return_pop_internal"
11744 (use (match_operand:SI 0 "const_int_operand" ""))]
11747 [(set_attr "length" "3")
11748 (set_attr "atom_unit" "jeu")
11749 (set_attr "length_immediate" "2")
11750 (set_attr "modrm" "0")])
11752 (define_insn "return_indirect_internal"
11754 (use (match_operand:SI 0 "register_operand" "r"))]
11757 [(set_attr "type" "ibr")
11758 (set_attr "length_immediate" "0")])
11764 [(set_attr "length" "1")
11765 (set_attr "length_immediate" "0")
11766 (set_attr "modrm" "0")])
11768 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11769 (define_insn "nops"
11770 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11774 int num = INTVAL (operands[0]);
11776 gcc_assert (num >= 1 && num <= 8);
11779 fputs ("\tnop\n", asm_out_file);
11783 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11784 (set_attr "length_immediate" "0")
11785 (set_attr "modrm" "0")])
11787 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11788 ;; branch prediction penalty for the third jump in a 16-byte
11792 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11795 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11796 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11798 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11799 The align insn is used to avoid 3 jump instructions in the row to improve
11800 branch prediction and the benefits hardly outweigh the cost of extra 8
11801 nops on the average inserted by full alignment pseudo operation. */
11805 [(set_attr "length" "16")])
11807 (define_expand "prologue"
11810 "ix86_expand_prologue (); DONE;")
11812 (define_insn "set_got"
11813 [(set (match_operand:SI 0 "register_operand" "=r")
11814 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11815 (clobber (reg:CC FLAGS_REG))]
11817 "* return output_set_got (operands[0], NULL_RTX);"
11818 [(set_attr "type" "multi")
11819 (set_attr "length" "12")])
11821 (define_insn "set_got_labelled"
11822 [(set (match_operand:SI 0 "register_operand" "=r")
11823 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11825 (clobber (reg:CC FLAGS_REG))]
11827 "* return output_set_got (operands[0], operands[1]);"
11828 [(set_attr "type" "multi")
11829 (set_attr "length" "12")])
11831 (define_insn "set_got_rex64"
11832 [(set (match_operand:DI 0 "register_operand" "=r")
11833 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11835 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11836 [(set_attr "type" "lea")
11837 (set_attr "length_address" "4")
11838 (set_attr "mode" "DI")])
11840 (define_insn "set_rip_rex64"
11841 [(set (match_operand:DI 0 "register_operand" "=r")
11842 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11844 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11845 [(set_attr "type" "lea")
11846 (set_attr "length_address" "4")
11847 (set_attr "mode" "DI")])
11849 (define_insn "set_got_offset_rex64"
11850 [(set (match_operand:DI 0 "register_operand" "=r")
11852 [(label_ref (match_operand 1 "" ""))]
11853 UNSPEC_SET_GOT_OFFSET))]
11855 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11856 [(set_attr "type" "imov")
11857 (set_attr "length_immediate" "0")
11858 (set_attr "length_address" "8")
11859 (set_attr "mode" "DI")])
11861 (define_expand "epilogue"
11864 "ix86_expand_epilogue (1); DONE;")
11866 (define_expand "sibcall_epilogue"
11869 "ix86_expand_epilogue (0); DONE;")
11871 (define_expand "eh_return"
11872 [(use (match_operand 0 "register_operand" ""))]
11875 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11877 /* Tricky bit: we write the address of the handler to which we will
11878 be returning into someone else's stack frame, one word below the
11879 stack address we wish to restore. */
11880 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11881 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11882 tmp = gen_rtx_MEM (Pmode, tmp);
11883 emit_move_insn (tmp, ra);
11885 emit_jump_insn (gen_eh_return_internal ());
11890 (define_insn_and_split "eh_return_internal"
11894 "epilogue_completed"
11896 "ix86_expand_epilogue (2); DONE;")
11898 (define_insn "leave"
11899 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11900 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11901 (clobber (mem:BLK (scratch)))]
11904 [(set_attr "type" "leave")])
11906 (define_insn "leave_rex64"
11907 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11908 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11909 (clobber (mem:BLK (scratch)))]
11912 [(set_attr "type" "leave")])
11914 ;; Handle -fsplit-stack.
11916 (define_expand "split_stack_prologue"
11920 ix86_expand_split_stack_prologue ();
11924 ;; In order to support the call/return predictor, we use a return
11925 ;; instruction which the middle-end doesn't see.
11926 (define_insn "split_stack_return"
11927 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11928 UNSPECV_SPLIT_STACK_RETURN)]
11931 if (operands[0] == const0_rtx)
11936 [(set_attr "atom_unit" "jeu")
11937 (set_attr "modrm" "0")
11938 (set (attr "length")
11939 (if_then_else (match_operand:SI 0 "const0_operand" "")
11942 (set (attr "length_immediate")
11943 (if_then_else (match_operand:SI 0 "const0_operand" "")
11947 ;; If there are operand 0 bytes available on the stack, jump to
11950 (define_expand "split_stack_space_check"
11951 [(set (pc) (if_then_else
11952 (ltu (minus (reg SP_REG)
11953 (match_operand 0 "register_operand" ""))
11954 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11955 (label_ref (match_operand 1 "" ""))
11959 rtx reg, size, limit;
11961 reg = gen_reg_rtx (Pmode);
11962 size = force_reg (Pmode, operands[0]);
11963 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11964 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11965 UNSPEC_STACK_CHECK);
11966 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11967 ix86_expand_branch (GEU, reg, limit, operands[1]);
11972 ;; Bit manipulation instructions.
11974 (define_expand "ffs<mode>2"
11975 [(set (match_dup 2) (const_int -1))
11976 (parallel [(set (reg:CCZ FLAGS_REG)
11978 (match_operand:SWI48 1 "nonimmediate_operand" "")
11980 (set (match_operand:SWI48 0 "register_operand" "")
11981 (ctz:SWI48 (match_dup 1)))])
11982 (set (match_dup 0) (if_then_else:SWI48
11983 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11986 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11987 (clobber (reg:CC FLAGS_REG))])]
11990 if (<MODE>mode == SImode && !TARGET_CMOVE)
11992 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11995 operands[2] = gen_reg_rtx (<MODE>mode);
11998 (define_insn_and_split "ffssi2_no_cmove"
11999 [(set (match_operand:SI 0 "register_operand" "=r")
12000 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12001 (clobber (match_scratch:SI 2 "=&q"))
12002 (clobber (reg:CC FLAGS_REG))]
12005 "&& reload_completed"
12006 [(parallel [(set (reg:CCZ FLAGS_REG)
12007 (compare:CCZ (match_dup 1) (const_int 0)))
12008 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12009 (set (strict_low_part (match_dup 3))
12010 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12011 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12012 (clobber (reg:CC FLAGS_REG))])
12013 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12014 (clobber (reg:CC FLAGS_REG))])
12015 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12016 (clobber (reg:CC FLAGS_REG))])]
12018 operands[3] = gen_lowpart (QImode, operands[2]);
12019 ix86_expand_clear (operands[2]);
12022 (define_insn "*ffs<mode>_1"
12023 [(set (reg:CCZ FLAGS_REG)
12024 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12026 (set (match_operand:SWI48 0 "register_operand" "=r")
12027 (ctz:SWI48 (match_dup 1)))]
12029 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12030 [(set_attr "type" "alu1")
12031 (set_attr "prefix_0f" "1")
12032 (set_attr "mode" "<MODE>")])
12034 (define_insn "ctz<mode>2"
12035 [(set (match_operand:SWI248 0 "register_operand" "=r")
12036 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12037 (clobber (reg:CC FLAGS_REG))]
12041 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12043 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12045 [(set_attr "type" "alu1")
12046 (set_attr "prefix_0f" "1")
12047 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12048 (set_attr "mode" "<MODE>")])
12050 (define_expand "clz<mode>2"
12052 [(set (match_operand:SWI248 0 "register_operand" "")
12055 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12056 (clobber (reg:CC FLAGS_REG))])
12058 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12059 (clobber (reg:CC FLAGS_REG))])]
12064 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12067 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12070 (define_insn "clz<mode>2_abm"
12071 [(set (match_operand:SWI248 0 "register_operand" "=r")
12072 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12073 (clobber (reg:CC FLAGS_REG))]
12074 "TARGET_ABM || TARGET_BMI"
12075 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12076 [(set_attr "prefix_rep" "1")
12077 (set_attr "type" "bitmanip")
12078 (set_attr "mode" "<MODE>")])
12080 ;; BMI instructions.
12081 (define_insn "*bmi_andn_<mode>"
12082 [(set (match_operand:SWI48 0 "register_operand" "=r")
12085 (match_operand:SWI48 1 "register_operand" "r"))
12086 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12087 (clobber (reg:CC FLAGS_REG))]
12089 "andn\t{%2, %1, %0|%0, %1, %2}"
12090 [(set_attr "type" "bitmanip")
12091 (set_attr "mode" "<MODE>")])
12093 (define_insn "bmi_bextr_<mode>"
12094 [(set (match_operand:SWI48 0 "register_operand" "=r")
12095 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12096 (match_operand:SWI48 2 "register_operand" "r")]
12098 (clobber (reg:CC FLAGS_REG))]
12100 "bextr\t{%2, %1, %0|%0, %1, %2}"
12101 [(set_attr "type" "bitmanip")
12102 (set_attr "mode" "<MODE>")])
12104 (define_insn "*bmi_blsi_<mode>"
12105 [(set (match_operand:SWI48 0 "register_operand" "=r")
12108 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12110 (clobber (reg:CC FLAGS_REG))]
12112 "blsi\t{%1, %0|%0, %1}"
12113 [(set_attr "type" "bitmanip")
12114 (set_attr "mode" "<MODE>")])
12116 (define_insn "*bmi_blsmsk_<mode>"
12117 [(set (match_operand:SWI48 0 "register_operand" "=r")
12120 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12123 (clobber (reg:CC FLAGS_REG))]
12125 "blsmsk\t{%1, %0|%0, %1}"
12126 [(set_attr "type" "bitmanip")
12127 (set_attr "mode" "<MODE>")])
12129 (define_insn "*bmi_blsr_<mode>"
12130 [(set (match_operand:SWI48 0 "register_operand" "=r")
12133 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12136 (clobber (reg:CC FLAGS_REG))]
12138 "blsr\t{%1, %0|%0, %1}"
12139 [(set_attr "type" "bitmanip")
12140 (set_attr "mode" "<MODE>")])
12142 ;; TBM instructions.
12143 (define_insn "tbm_bextri_<mode>"
12144 [(set (match_operand:SWI48 0 "register_operand" "=r")
12145 (zero_extract:SWI48
12146 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12147 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12148 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12149 (clobber (reg:CC FLAGS_REG))]
12152 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12153 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12155 [(set_attr "type" "bitmanip")
12156 (set_attr "mode" "<MODE>")])
12158 (define_insn "*tbm_blcfill_<mode>"
12159 [(set (match_operand:SWI48 0 "register_operand" "=r")
12162 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12165 (clobber (reg:CC FLAGS_REG))]
12167 "blcfill\t{%1, %0|%0, %1}"
12168 [(set_attr "type" "bitmanip")
12169 (set_attr "mode" "<MODE>")])
12171 (define_insn "*tbm_blci_<mode>"
12172 [(set (match_operand:SWI48 0 "register_operand" "=r")
12176 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12179 (clobber (reg:CC FLAGS_REG))]
12181 "blci\t{%1, %0|%0, %1}"
12182 [(set_attr "type" "bitmanip")
12183 (set_attr "mode" "<MODE>")])
12185 (define_insn "*tbm_blcic_<mode>"
12186 [(set (match_operand:SWI48 0 "register_operand" "=r")
12189 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12193 (clobber (reg:CC FLAGS_REG))]
12195 "blcic\t{%1, %0|%0, %1}"
12196 [(set_attr "type" "bitmanip")
12197 (set_attr "mode" "<MODE>")])
12199 (define_insn "*tbm_blcmsk_<mode>"
12200 [(set (match_operand:SWI48 0 "register_operand" "=r")
12203 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12206 (clobber (reg:CC FLAGS_REG))]
12208 "blcmsk\t{%1, %0|%0, %1}"
12209 [(set_attr "type" "bitmanip")
12210 (set_attr "mode" "<MODE>")])
12212 (define_insn "*tbm_blcs_<mode>"
12213 [(set (match_operand:SWI48 0 "register_operand" "=r")
12216 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12219 (clobber (reg:CC FLAGS_REG))]
12221 "blcs\t{%1, %0|%0, %1}"
12222 [(set_attr "type" "bitmanip")
12223 (set_attr "mode" "<MODE>")])
12225 (define_insn "*tbm_blsfill_<mode>"
12226 [(set (match_operand:SWI48 0 "register_operand" "=r")
12229 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12232 (clobber (reg:CC FLAGS_REG))]
12234 "blsfill\t{%1, %0|%0, %1}"
12235 [(set_attr "type" "bitmanip")
12236 (set_attr "mode" "<MODE>")])
12238 (define_insn "*tbm_blsic_<mode>"
12239 [(set (match_operand:SWI48 0 "register_operand" "=r")
12242 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12246 (clobber (reg:CC FLAGS_REG))]
12248 "blsic\t{%1, %0|%0, %1}"
12249 [(set_attr "type" "bitmanip")
12250 (set_attr "mode" "<MODE>")])
12252 (define_insn "*tbm_t1mskc_<mode>"
12253 [(set (match_operand:SWI48 0 "register_operand" "=r")
12256 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12260 (clobber (reg:CC FLAGS_REG))]
12262 "t1mskc\t{%1, %0|%0, %1}"
12263 [(set_attr "type" "bitmanip")
12264 (set_attr "mode" "<MODE>")])
12266 (define_insn "*tbm_tzmsk_<mode>"
12267 [(set (match_operand:SWI48 0 "register_operand" "=r")
12270 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12274 (clobber (reg:CC FLAGS_REG))]
12276 "tzmsk\t{%1, %0|%0, %1}"
12277 [(set_attr "type" "bitmanip")
12278 (set_attr "mode" "<MODE>")])
12280 (define_insn "bsr_rex64"
12281 [(set (match_operand:DI 0 "register_operand" "=r")
12282 (minus:DI (const_int 63)
12283 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12284 (clobber (reg:CC FLAGS_REG))]
12286 "bsr{q}\t{%1, %0|%0, %1}"
12287 [(set_attr "type" "alu1")
12288 (set_attr "prefix_0f" "1")
12289 (set_attr "mode" "DI")])
12292 [(set (match_operand:SI 0 "register_operand" "=r")
12293 (minus:SI (const_int 31)
12294 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12295 (clobber (reg:CC FLAGS_REG))]
12297 "bsr{l}\t{%1, %0|%0, %1}"
12298 [(set_attr "type" "alu1")
12299 (set_attr "prefix_0f" "1")
12300 (set_attr "mode" "SI")])
12302 (define_insn "*bsrhi"
12303 [(set (match_operand:HI 0 "register_operand" "=r")
12304 (minus:HI (const_int 15)
12305 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12306 (clobber (reg:CC FLAGS_REG))]
12308 "bsr{w}\t{%1, %0|%0, %1}"
12309 [(set_attr "type" "alu1")
12310 (set_attr "prefix_0f" "1")
12311 (set_attr "mode" "HI")])
12313 (define_insn "popcount<mode>2"
12314 [(set (match_operand:SWI248 0 "register_operand" "=r")
12316 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12317 (clobber (reg:CC FLAGS_REG))]
12321 return "popcnt\t{%1, %0|%0, %1}";
12323 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12326 [(set_attr "prefix_rep" "1")
12327 (set_attr "type" "bitmanip")
12328 (set_attr "mode" "<MODE>")])
12330 (define_insn "*popcount<mode>2_cmp"
12331 [(set (reg FLAGS_REG)
12334 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12336 (set (match_operand:SWI248 0 "register_operand" "=r")
12337 (popcount:SWI248 (match_dup 1)))]
12338 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12341 return "popcnt\t{%1, %0|%0, %1}";
12343 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12346 [(set_attr "prefix_rep" "1")
12347 (set_attr "type" "bitmanip")
12348 (set_attr "mode" "<MODE>")])
12350 (define_insn "*popcountsi2_cmp_zext"
12351 [(set (reg FLAGS_REG)
12353 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12355 (set (match_operand:DI 0 "register_operand" "=r")
12356 (zero_extend:DI(popcount:SI (match_dup 1))))]
12357 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12360 return "popcnt\t{%1, %0|%0, %1}";
12362 return "popcnt{l}\t{%1, %0|%0, %1}";
12365 [(set_attr "prefix_rep" "1")
12366 (set_attr "type" "bitmanip")
12367 (set_attr "mode" "SI")])
12369 (define_expand "bswap<mode>2"
12370 [(set (match_operand:SWI48 0 "register_operand" "")
12371 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12374 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12376 rtx x = operands[0];
12378 emit_move_insn (x, operands[1]);
12379 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12380 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12381 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12386 (define_insn "*bswap<mode>2_movbe"
12387 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12388 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12390 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12393 movbe\t{%1, %0|%0, %1}
12394 movbe\t{%1, %0|%0, %1}"
12395 [(set_attr "type" "bitmanip,imov,imov")
12396 (set_attr "modrm" "0,1,1")
12397 (set_attr "prefix_0f" "*,1,1")
12398 (set_attr "prefix_extra" "*,1,1")
12399 (set_attr "mode" "<MODE>")])
12401 (define_insn "*bswap<mode>2_1"
12402 [(set (match_operand:SWI48 0 "register_operand" "=r")
12403 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12406 [(set_attr "type" "bitmanip")
12407 (set_attr "modrm" "0")
12408 (set_attr "mode" "<MODE>")])
12410 (define_insn "*bswaphi_lowpart_1"
12411 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12412 (bswap:HI (match_dup 0)))
12413 (clobber (reg:CC FLAGS_REG))]
12414 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12416 xchg{b}\t{%h0, %b0|%b0, %h0}
12417 rol{w}\t{$8, %0|%0, 8}"
12418 [(set_attr "length" "2,4")
12419 (set_attr "mode" "QI,HI")])
12421 (define_insn "bswaphi_lowpart"
12422 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12423 (bswap:HI (match_dup 0)))
12424 (clobber (reg:CC FLAGS_REG))]
12426 "rol{w}\t{$8, %0|%0, 8}"
12427 [(set_attr "length" "4")
12428 (set_attr "mode" "HI")])
12430 (define_expand "paritydi2"
12431 [(set (match_operand:DI 0 "register_operand" "")
12432 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12435 rtx scratch = gen_reg_rtx (QImode);
12438 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12439 NULL_RTX, operands[1]));
12441 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12442 gen_rtx_REG (CCmode, FLAGS_REG),
12444 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12447 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12450 rtx tmp = gen_reg_rtx (SImode);
12452 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12453 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12458 (define_expand "paritysi2"
12459 [(set (match_operand:SI 0 "register_operand" "")
12460 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12463 rtx scratch = gen_reg_rtx (QImode);
12466 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12468 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12469 gen_rtx_REG (CCmode, FLAGS_REG),
12471 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12473 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12477 (define_insn_and_split "paritydi2_cmp"
12478 [(set (reg:CC FLAGS_REG)
12479 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12481 (clobber (match_scratch:DI 0 "=r"))
12482 (clobber (match_scratch:SI 1 "=&r"))
12483 (clobber (match_scratch:HI 2 "=Q"))]
12486 "&& reload_completed"
12488 [(set (match_dup 1)
12489 (xor:SI (match_dup 1) (match_dup 4)))
12490 (clobber (reg:CC FLAGS_REG))])
12492 [(set (reg:CC FLAGS_REG)
12493 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12494 (clobber (match_dup 1))
12495 (clobber (match_dup 2))])]
12497 operands[4] = gen_lowpart (SImode, operands[3]);
12501 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12502 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12505 operands[1] = gen_highpart (SImode, operands[3]);
12508 (define_insn_and_split "paritysi2_cmp"
12509 [(set (reg:CC FLAGS_REG)
12510 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12512 (clobber (match_scratch:SI 0 "=r"))
12513 (clobber (match_scratch:HI 1 "=&Q"))]
12516 "&& reload_completed"
12518 [(set (match_dup 1)
12519 (xor:HI (match_dup 1) (match_dup 3)))
12520 (clobber (reg:CC FLAGS_REG))])
12522 [(set (reg:CC FLAGS_REG)
12523 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12524 (clobber (match_dup 1))])]
12526 operands[3] = gen_lowpart (HImode, operands[2]);
12528 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12529 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12532 (define_insn "*parityhi2_cmp"
12533 [(set (reg:CC FLAGS_REG)
12534 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12536 (clobber (match_scratch:HI 0 "=Q"))]
12538 "xor{b}\t{%h0, %b0|%b0, %h0}"
12539 [(set_attr "length" "2")
12540 (set_attr "mode" "HI")])
12542 ;; Thread-local storage patterns for ELF.
12544 ;; Note that these code sequences must appear exactly as shown
12545 ;; in order to allow linker relaxation.
12547 (define_insn "*tls_global_dynamic_32_gnu"
12548 [(set (match_operand:SI 0 "register_operand" "=a")
12549 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12550 (match_operand:SI 2 "tls_symbolic_operand" "")
12551 (match_operand:SI 3 "call_insn_operand" "")]
12553 (clobber (match_scratch:SI 4 "=d"))
12554 (clobber (match_scratch:SI 5 "=c"))
12555 (clobber (reg:CC FLAGS_REG))]
12556 "!TARGET_64BIT && TARGET_GNU_TLS"
12557 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12558 [(set_attr "type" "multi")
12559 (set_attr "length" "12")])
12561 (define_expand "tls_global_dynamic_32"
12562 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12565 (match_operand:SI 1 "tls_symbolic_operand" "")
12568 (clobber (match_scratch:SI 4 ""))
12569 (clobber (match_scratch:SI 5 ""))
12570 (clobber (reg:CC FLAGS_REG))])]
12574 operands[2] = pic_offset_table_rtx;
12577 operands[2] = gen_reg_rtx (Pmode);
12578 emit_insn (gen_set_got (operands[2]));
12580 if (TARGET_GNU2_TLS)
12582 emit_insn (gen_tls_dynamic_gnu2_32
12583 (operands[0], operands[1], operands[2]));
12586 operands[3] = ix86_tls_get_addr ();
12589 (define_insn "*tls_global_dynamic_64"
12590 [(set (match_operand:DI 0 "register_operand" "=a")
12591 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12592 (match_operand:DI 3 "" "")))
12593 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12596 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12597 [(set_attr "type" "multi")
12598 (set_attr "length" "16")])
12600 (define_expand "tls_global_dynamic_64"
12601 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12602 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12603 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12607 if (TARGET_GNU2_TLS)
12609 emit_insn (gen_tls_dynamic_gnu2_64
12610 (operands[0], operands[1]));
12613 operands[2] = ix86_tls_get_addr ();
12616 (define_insn "*tls_local_dynamic_base_32_gnu"
12617 [(set (match_operand:SI 0 "register_operand" "=a")
12618 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12619 (match_operand:SI 2 "call_insn_operand" "")]
12620 UNSPEC_TLS_LD_BASE))
12621 (clobber (match_scratch:SI 3 "=d"))
12622 (clobber (match_scratch:SI 4 "=c"))
12623 (clobber (reg:CC FLAGS_REG))]
12624 "!TARGET_64BIT && TARGET_GNU_TLS"
12625 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12626 [(set_attr "type" "multi")
12627 (set_attr "length" "11")])
12629 (define_expand "tls_local_dynamic_base_32"
12630 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12631 (unspec:SI [(match_dup 1) (match_dup 2)]
12632 UNSPEC_TLS_LD_BASE))
12633 (clobber (match_scratch:SI 3 ""))
12634 (clobber (match_scratch:SI 4 ""))
12635 (clobber (reg:CC FLAGS_REG))])]
12639 operands[1] = pic_offset_table_rtx;
12642 operands[1] = gen_reg_rtx (Pmode);
12643 emit_insn (gen_set_got (operands[1]));
12645 if (TARGET_GNU2_TLS)
12647 emit_insn (gen_tls_dynamic_gnu2_32
12648 (operands[0], ix86_tls_module_base (), operands[1]));
12651 operands[2] = ix86_tls_get_addr ();
12654 (define_insn "*tls_local_dynamic_base_64"
12655 [(set (match_operand:DI 0 "register_operand" "=a")
12656 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12657 (match_operand:DI 2 "" "")))
12658 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12660 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12661 [(set_attr "type" "multi")
12662 (set_attr "length" "12")])
12664 (define_expand "tls_local_dynamic_base_64"
12665 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12666 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12667 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12670 if (TARGET_GNU2_TLS)
12672 emit_insn (gen_tls_dynamic_gnu2_64
12673 (operands[0], ix86_tls_module_base ()));
12676 operands[1] = ix86_tls_get_addr ();
12679 ;; Local dynamic of a single variable is a lose. Show combine how
12680 ;; to convert that back to global dynamic.
12682 (define_insn_and_split "*tls_local_dynamic_32_once"
12683 [(set (match_operand:SI 0 "register_operand" "=a")
12684 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12685 (match_operand:SI 2 "call_insn_operand" "")]
12686 UNSPEC_TLS_LD_BASE)
12687 (const:SI (unspec:SI
12688 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12690 (clobber (match_scratch:SI 4 "=d"))
12691 (clobber (match_scratch:SI 5 "=c"))
12692 (clobber (reg:CC FLAGS_REG))]
12696 [(parallel [(set (match_dup 0)
12697 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12699 (clobber (match_dup 4))
12700 (clobber (match_dup 5))
12701 (clobber (reg:CC FLAGS_REG))])])
12703 ;; Segment register for the thread base ptr load
12704 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12706 ;; Load and add the thread base pointer from %gs:0.
12707 (define_insn "*load_tp_<mode>"
12708 [(set (match_operand:P 0 "register_operand" "=r")
12709 (unspec:P [(const_int 0)] UNSPEC_TP))]
12711 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12712 [(set_attr "type" "imov")
12713 (set_attr "modrm" "0")
12714 (set_attr "length" "7")
12715 (set_attr "memory" "load")
12716 (set_attr "imm_disp" "false")])
12718 (define_insn "*add_tp_<mode>"
12719 [(set (match_operand:P 0 "register_operand" "=r")
12720 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12721 (match_operand:P 1 "register_operand" "0")))
12722 (clobber (reg:CC FLAGS_REG))]
12724 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12725 [(set_attr "type" "alu")
12726 (set_attr "modrm" "0")
12727 (set_attr "length" "7")
12728 (set_attr "memory" "load")
12729 (set_attr "imm_disp" "false")])
12731 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12732 ;; %rax as destination of the initial executable code sequence.
12733 (define_insn "tls_initial_exec_64_sun"
12734 [(set (match_operand:DI 0 "register_operand" "=a")
12736 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12737 UNSPEC_TLS_IE_SUN))
12738 (clobber (reg:CC FLAGS_REG))]
12739 "TARGET_64BIT && TARGET_SUN_TLS"
12740 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12741 [(set_attr "type" "multi")])
12743 ;; GNU2 TLS patterns can be split.
12745 (define_expand "tls_dynamic_gnu2_32"
12746 [(set (match_dup 3)
12747 (plus:SI (match_operand:SI 2 "register_operand" "")
12749 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12752 [(set (match_operand:SI 0 "register_operand" "")
12753 (unspec:SI [(match_dup 1) (match_dup 3)
12754 (match_dup 2) (reg:SI SP_REG)]
12756 (clobber (reg:CC FLAGS_REG))])]
12757 "!TARGET_64BIT && TARGET_GNU2_TLS"
12759 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12760 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12763 (define_insn "*tls_dynamic_lea_32"
12764 [(set (match_operand:SI 0 "register_operand" "=r")
12765 (plus:SI (match_operand:SI 1 "register_operand" "b")
12767 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12768 UNSPEC_TLSDESC))))]
12769 "!TARGET_64BIT && TARGET_GNU2_TLS"
12770 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12771 [(set_attr "type" "lea")
12772 (set_attr "mode" "SI")
12773 (set_attr "length" "6")
12774 (set_attr "length_address" "4")])
12776 (define_insn "*tls_dynamic_call_32"
12777 [(set (match_operand:SI 0 "register_operand" "=a")
12778 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12779 (match_operand:SI 2 "register_operand" "0")
12780 ;; we have to make sure %ebx still points to the GOT
12781 (match_operand:SI 3 "register_operand" "b")
12784 (clobber (reg:CC FLAGS_REG))]
12785 "!TARGET_64BIT && TARGET_GNU2_TLS"
12786 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12787 [(set_attr "type" "call")
12788 (set_attr "length" "2")
12789 (set_attr "length_address" "0")])
12791 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12792 [(set (match_operand:SI 0 "register_operand" "=&a")
12794 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12795 (match_operand:SI 4 "" "")
12796 (match_operand:SI 2 "register_operand" "b")
12799 (const:SI (unspec:SI
12800 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12802 (clobber (reg:CC FLAGS_REG))]
12803 "!TARGET_64BIT && TARGET_GNU2_TLS"
12806 [(set (match_dup 0) (match_dup 5))]
12808 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12809 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12812 (define_expand "tls_dynamic_gnu2_64"
12813 [(set (match_dup 2)
12814 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12817 [(set (match_operand:DI 0 "register_operand" "")
12818 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12820 (clobber (reg:CC FLAGS_REG))])]
12821 "TARGET_64BIT && TARGET_GNU2_TLS"
12823 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12824 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12827 (define_insn "*tls_dynamic_lea_64"
12828 [(set (match_operand:DI 0 "register_operand" "=r")
12829 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12831 "TARGET_64BIT && TARGET_GNU2_TLS"
12832 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12833 [(set_attr "type" "lea")
12834 (set_attr "mode" "DI")
12835 (set_attr "length" "7")
12836 (set_attr "length_address" "4")])
12838 (define_insn "*tls_dynamic_call_64"
12839 [(set (match_operand:DI 0 "register_operand" "=a")
12840 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12841 (match_operand:DI 2 "register_operand" "0")
12844 (clobber (reg:CC FLAGS_REG))]
12845 "TARGET_64BIT && TARGET_GNU2_TLS"
12846 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12847 [(set_attr "type" "call")
12848 (set_attr "length" "2")
12849 (set_attr "length_address" "0")])
12851 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12852 [(set (match_operand:DI 0 "register_operand" "=&a")
12854 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12855 (match_operand:DI 3 "" "")
12858 (const:DI (unspec:DI
12859 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12861 (clobber (reg:CC FLAGS_REG))]
12862 "TARGET_64BIT && TARGET_GNU2_TLS"
12865 [(set (match_dup 0) (match_dup 4))]
12867 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12868 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12871 ;; These patterns match the binary 387 instructions for addM3, subM3,
12872 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12873 ;; SFmode. The first is the normal insn, the second the same insn but
12874 ;; with one operand a conversion, and the third the same insn but with
12875 ;; the other operand a conversion. The conversion may be SFmode or
12876 ;; SImode if the target mode DFmode, but only SImode if the target mode
12879 ;; Gcc is slightly more smart about handling normal two address instructions
12880 ;; so use special patterns for add and mull.
12882 (define_insn "*fop_<mode>_comm_mixed"
12883 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12884 (match_operator:MODEF 3 "binary_fp_operator"
12885 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12886 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12887 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12888 && COMMUTATIVE_ARITH_P (operands[3])
12889 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12890 "* return output_387_binary_op (insn, operands);"
12891 [(set (attr "type")
12892 (if_then_else (eq_attr "alternative" "1,2")
12893 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12894 (const_string "ssemul")
12895 (const_string "sseadd"))
12896 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12897 (const_string "fmul")
12898 (const_string "fop"))))
12899 (set_attr "isa" "base,noavx,avx")
12900 (set_attr "prefix" "orig,orig,vex")
12901 (set_attr "mode" "<MODE>")])
12903 (define_insn "*fop_<mode>_comm_sse"
12904 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12905 (match_operator:MODEF 3 "binary_fp_operator"
12906 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12907 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12908 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12909 && COMMUTATIVE_ARITH_P (operands[3])
12910 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12911 "* return output_387_binary_op (insn, operands);"
12912 [(set (attr "type")
12913 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12914 (const_string "ssemul")
12915 (const_string "sseadd")))
12916 (set_attr "isa" "noavx,avx")
12917 (set_attr "prefix" "orig,vex")
12918 (set_attr "mode" "<MODE>")])
12920 (define_insn "*fop_<mode>_comm_i387"
12921 [(set (match_operand:MODEF 0 "register_operand" "=f")
12922 (match_operator:MODEF 3 "binary_fp_operator"
12923 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12924 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12925 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12926 && COMMUTATIVE_ARITH_P (operands[3])
12927 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12928 "* return output_387_binary_op (insn, operands);"
12929 [(set (attr "type")
12930 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12931 (const_string "fmul")
12932 (const_string "fop")))
12933 (set_attr "mode" "<MODE>")])
12935 (define_insn "*fop_<mode>_1_mixed"
12936 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12937 (match_operator:MODEF 3 "binary_fp_operator"
12938 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12939 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12940 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12941 && !COMMUTATIVE_ARITH_P (operands[3])
12942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12943 "* return output_387_binary_op (insn, operands);"
12944 [(set (attr "type")
12945 (cond [(and (eq_attr "alternative" "2,3")
12946 (match_operand:MODEF 3 "mult_operator" ""))
12947 (const_string "ssemul")
12948 (and (eq_attr "alternative" "2,3")
12949 (match_operand:MODEF 3 "div_operator" ""))
12950 (const_string "ssediv")
12951 (eq_attr "alternative" "2,3")
12952 (const_string "sseadd")
12953 (match_operand:MODEF 3 "mult_operator" "")
12954 (const_string "fmul")
12955 (match_operand:MODEF 3 "div_operator" "")
12956 (const_string "fdiv")
12958 (const_string "fop")))
12959 (set_attr "isa" "base,base,noavx,avx")
12960 (set_attr "prefix" "orig,orig,orig,vex")
12961 (set_attr "mode" "<MODE>")])
12963 (define_insn "*rcpsf2_sse"
12964 [(set (match_operand:SF 0 "register_operand" "=x")
12965 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12968 "%vrcpss\t{%1, %d0|%d0, %1}"
12969 [(set_attr "type" "sse")
12970 (set_attr "atom_sse_attr" "rcp")
12971 (set_attr "prefix" "maybe_vex")
12972 (set_attr "mode" "SF")])
12974 (define_insn "*fop_<mode>_1_sse"
12975 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12976 (match_operator:MODEF 3 "binary_fp_operator"
12977 [(match_operand:MODEF 1 "register_operand" "0,x")
12978 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12979 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12980 && !COMMUTATIVE_ARITH_P (operands[3])"
12981 "* return output_387_binary_op (insn, operands);"
12982 [(set (attr "type")
12983 (cond [(match_operand:MODEF 3 "mult_operator" "")
12984 (const_string "ssemul")
12985 (match_operand:MODEF 3 "div_operator" "")
12986 (const_string "ssediv")
12988 (const_string "sseadd")))
12989 (set_attr "isa" "noavx,avx")
12990 (set_attr "prefix" "orig,vex")
12991 (set_attr "mode" "<MODE>")])
12993 ;; This pattern is not fully shadowed by the pattern above.
12994 (define_insn "*fop_<mode>_1_i387"
12995 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12996 (match_operator:MODEF 3 "binary_fp_operator"
12997 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12998 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12999 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13000 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13001 && !COMMUTATIVE_ARITH_P (operands[3])
13002 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13003 "* return output_387_binary_op (insn, operands);"
13004 [(set (attr "type")
13005 (cond [(match_operand:MODEF 3 "mult_operator" "")
13006 (const_string "fmul")
13007 (match_operand:MODEF 3 "div_operator" "")
13008 (const_string "fdiv")
13010 (const_string "fop")))
13011 (set_attr "mode" "<MODE>")])
13013 ;; ??? Add SSE splitters for these!
13014 (define_insn "*fop_<MODEF:mode>_2_i387"
13015 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13016 (match_operator:MODEF 3 "binary_fp_operator"
13018 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13019 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13020 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13021 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13022 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13023 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13024 [(set (attr "type")
13025 (cond [(match_operand:MODEF 3 "mult_operator" "")
13026 (const_string "fmul")
13027 (match_operand:MODEF 3 "div_operator" "")
13028 (const_string "fdiv")
13030 (const_string "fop")))
13031 (set_attr "fp_int_src" "true")
13032 (set_attr "mode" "<X87MODEI12:MODE>")])
13034 (define_insn "*fop_<MODEF:mode>_3_i387"
13035 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13036 (match_operator:MODEF 3 "binary_fp_operator"
13037 [(match_operand:MODEF 1 "register_operand" "0,0")
13039 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13040 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13041 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13042 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13043 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13044 [(set (attr "type")
13045 (cond [(match_operand:MODEF 3 "mult_operator" "")
13046 (const_string "fmul")
13047 (match_operand:MODEF 3 "div_operator" "")
13048 (const_string "fdiv")
13050 (const_string "fop")))
13051 (set_attr "fp_int_src" "true")
13052 (set_attr "mode" "<MODE>")])
13054 (define_insn "*fop_df_4_i387"
13055 [(set (match_operand:DF 0 "register_operand" "=f,f")
13056 (match_operator:DF 3 "binary_fp_operator"
13058 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13059 (match_operand:DF 2 "register_operand" "0,f")]))]
13060 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13061 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13062 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13063 "* return output_387_binary_op (insn, operands);"
13064 [(set (attr "type")
13065 (cond [(match_operand:DF 3 "mult_operator" "")
13066 (const_string "fmul")
13067 (match_operand:DF 3 "div_operator" "")
13068 (const_string "fdiv")
13070 (const_string "fop")))
13071 (set_attr "mode" "SF")])
13073 (define_insn "*fop_df_5_i387"
13074 [(set (match_operand:DF 0 "register_operand" "=f,f")
13075 (match_operator:DF 3 "binary_fp_operator"
13076 [(match_operand:DF 1 "register_operand" "0,f")
13078 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13079 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13080 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13081 "* return output_387_binary_op (insn, operands);"
13082 [(set (attr "type")
13083 (cond [(match_operand:DF 3 "mult_operator" "")
13084 (const_string "fmul")
13085 (match_operand:DF 3 "div_operator" "")
13086 (const_string "fdiv")
13088 (const_string "fop")))
13089 (set_attr "mode" "SF")])
13091 (define_insn "*fop_df_6_i387"
13092 [(set (match_operand:DF 0 "register_operand" "=f,f")
13093 (match_operator:DF 3 "binary_fp_operator"
13095 (match_operand:SF 1 "register_operand" "0,f"))
13097 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13098 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13099 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13100 "* return output_387_binary_op (insn, operands);"
13101 [(set (attr "type")
13102 (cond [(match_operand:DF 3 "mult_operator" "")
13103 (const_string "fmul")
13104 (match_operand:DF 3 "div_operator" "")
13105 (const_string "fdiv")
13107 (const_string "fop")))
13108 (set_attr "mode" "SF")])
13110 (define_insn "*fop_xf_comm_i387"
13111 [(set (match_operand:XF 0 "register_operand" "=f")
13112 (match_operator:XF 3 "binary_fp_operator"
13113 [(match_operand:XF 1 "register_operand" "%0")
13114 (match_operand:XF 2 "register_operand" "f")]))]
13116 && COMMUTATIVE_ARITH_P (operands[3])"
13117 "* return output_387_binary_op (insn, operands);"
13118 [(set (attr "type")
13119 (if_then_else (match_operand:XF 3 "mult_operator" "")
13120 (const_string "fmul")
13121 (const_string "fop")))
13122 (set_attr "mode" "XF")])
13124 (define_insn "*fop_xf_1_i387"
13125 [(set (match_operand:XF 0 "register_operand" "=f,f")
13126 (match_operator:XF 3 "binary_fp_operator"
13127 [(match_operand:XF 1 "register_operand" "0,f")
13128 (match_operand:XF 2 "register_operand" "f,0")]))]
13130 && !COMMUTATIVE_ARITH_P (operands[3])"
13131 "* return output_387_binary_op (insn, operands);"
13132 [(set (attr "type")
13133 (cond [(match_operand:XF 3 "mult_operator" "")
13134 (const_string "fmul")
13135 (match_operand:XF 3 "div_operator" "")
13136 (const_string "fdiv")
13138 (const_string "fop")))
13139 (set_attr "mode" "XF")])
13141 (define_insn "*fop_xf_2_i387"
13142 [(set (match_operand:XF 0 "register_operand" "=f,f")
13143 (match_operator:XF 3 "binary_fp_operator"
13145 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13146 (match_operand:XF 2 "register_operand" "0,0")]))]
13147 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13148 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13149 [(set (attr "type")
13150 (cond [(match_operand:XF 3 "mult_operator" "")
13151 (const_string "fmul")
13152 (match_operand:XF 3 "div_operator" "")
13153 (const_string "fdiv")
13155 (const_string "fop")))
13156 (set_attr "fp_int_src" "true")
13157 (set_attr "mode" "<MODE>")])
13159 (define_insn "*fop_xf_3_i387"
13160 [(set (match_operand:XF 0 "register_operand" "=f,f")
13161 (match_operator:XF 3 "binary_fp_operator"
13162 [(match_operand:XF 1 "register_operand" "0,0")
13164 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13165 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13166 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13167 [(set (attr "type")
13168 (cond [(match_operand:XF 3 "mult_operator" "")
13169 (const_string "fmul")
13170 (match_operand:XF 3 "div_operator" "")
13171 (const_string "fdiv")
13173 (const_string "fop")))
13174 (set_attr "fp_int_src" "true")
13175 (set_attr "mode" "<MODE>")])
13177 (define_insn "*fop_xf_4_i387"
13178 [(set (match_operand:XF 0 "register_operand" "=f,f")
13179 (match_operator:XF 3 "binary_fp_operator"
13181 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13182 (match_operand:XF 2 "register_operand" "0,f")]))]
13184 "* return output_387_binary_op (insn, operands);"
13185 [(set (attr "type")
13186 (cond [(match_operand:XF 3 "mult_operator" "")
13187 (const_string "fmul")
13188 (match_operand:XF 3 "div_operator" "")
13189 (const_string "fdiv")
13191 (const_string "fop")))
13192 (set_attr "mode" "<MODE>")])
13194 (define_insn "*fop_xf_5_i387"
13195 [(set (match_operand:XF 0 "register_operand" "=f,f")
13196 (match_operator:XF 3 "binary_fp_operator"
13197 [(match_operand:XF 1 "register_operand" "0,f")
13199 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13201 "* return output_387_binary_op (insn, operands);"
13202 [(set (attr "type")
13203 (cond [(match_operand:XF 3 "mult_operator" "")
13204 (const_string "fmul")
13205 (match_operand:XF 3 "div_operator" "")
13206 (const_string "fdiv")
13208 (const_string "fop")))
13209 (set_attr "mode" "<MODE>")])
13211 (define_insn "*fop_xf_6_i387"
13212 [(set (match_operand:XF 0 "register_operand" "=f,f")
13213 (match_operator:XF 3 "binary_fp_operator"
13215 (match_operand:MODEF 1 "register_operand" "0,f"))
13217 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13219 "* return output_387_binary_op (insn, operands);"
13220 [(set (attr "type")
13221 (cond [(match_operand:XF 3 "mult_operator" "")
13222 (const_string "fmul")
13223 (match_operand:XF 3 "div_operator" "")
13224 (const_string "fdiv")
13226 (const_string "fop")))
13227 (set_attr "mode" "<MODE>")])
13230 [(set (match_operand 0 "register_operand" "")
13231 (match_operator 3 "binary_fp_operator"
13232 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13233 (match_operand 2 "register_operand" "")]))]
13235 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13236 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13239 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13240 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13241 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13242 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13243 GET_MODE (operands[3]),
13246 ix86_free_from_memory (GET_MODE (operands[1]));
13251 [(set (match_operand 0 "register_operand" "")
13252 (match_operator 3 "binary_fp_operator"
13253 [(match_operand 1 "register_operand" "")
13254 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13256 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13257 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13260 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13261 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13262 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13263 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13264 GET_MODE (operands[3]),
13267 ix86_free_from_memory (GET_MODE (operands[2]));
13271 ;; FPU special functions.
13273 ;; This pattern implements a no-op XFmode truncation for
13274 ;; all fancy i386 XFmode math functions.
13276 (define_insn "truncxf<mode>2_i387_noop_unspec"
13277 [(set (match_operand:MODEF 0 "register_operand" "=f")
13278 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13279 UNSPEC_TRUNC_NOOP))]
13280 "TARGET_USE_FANCY_MATH_387"
13281 "* return output_387_reg_move (insn, operands);"
13282 [(set_attr "type" "fmov")
13283 (set_attr "mode" "<MODE>")])
13285 (define_insn "sqrtxf2"
13286 [(set (match_operand:XF 0 "register_operand" "=f")
13287 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13288 "TARGET_USE_FANCY_MATH_387"
13290 [(set_attr "type" "fpspc")
13291 (set_attr "mode" "XF")
13292 (set_attr "athlon_decode" "direct")
13293 (set_attr "amdfam10_decode" "direct")
13294 (set_attr "bdver1_decode" "direct")])
13296 (define_insn "sqrt_extend<mode>xf2_i387"
13297 [(set (match_operand:XF 0 "register_operand" "=f")
13300 (match_operand:MODEF 1 "register_operand" "0"))))]
13301 "TARGET_USE_FANCY_MATH_387"
13303 [(set_attr "type" "fpspc")
13304 (set_attr "mode" "XF")
13305 (set_attr "athlon_decode" "direct")
13306 (set_attr "amdfam10_decode" "direct")
13307 (set_attr "bdver1_decode" "direct")])
13309 (define_insn "*rsqrtsf2_sse"
13310 [(set (match_operand:SF 0 "register_operand" "=x")
13311 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13314 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13315 [(set_attr "type" "sse")
13316 (set_attr "atom_sse_attr" "rcp")
13317 (set_attr "prefix" "maybe_vex")
13318 (set_attr "mode" "SF")])
13320 (define_expand "rsqrtsf2"
13321 [(set (match_operand:SF 0 "register_operand" "")
13322 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13326 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13330 (define_insn "*sqrt<mode>2_sse"
13331 [(set (match_operand:MODEF 0 "register_operand" "=x")
13333 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13334 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13335 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13336 [(set_attr "type" "sse")
13337 (set_attr "atom_sse_attr" "sqrt")
13338 (set_attr "prefix" "maybe_vex")
13339 (set_attr "mode" "<MODE>")
13340 (set_attr "athlon_decode" "*")
13341 (set_attr "amdfam10_decode" "*")
13342 (set_attr "bdver1_decode" "*")])
13344 (define_expand "sqrt<mode>2"
13345 [(set (match_operand:MODEF 0 "register_operand" "")
13347 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13348 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13349 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13351 if (<MODE>mode == SFmode
13352 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13353 && flag_finite_math_only && !flag_trapping_math
13354 && flag_unsafe_math_optimizations)
13356 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13360 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13362 rtx op0 = gen_reg_rtx (XFmode);
13363 rtx op1 = force_reg (<MODE>mode, operands[1]);
13365 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13366 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13371 (define_insn "fpremxf4_i387"
13372 [(set (match_operand:XF 0 "register_operand" "=f")
13373 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13374 (match_operand:XF 3 "register_operand" "1")]
13376 (set (match_operand:XF 1 "register_operand" "=u")
13377 (unspec:XF [(match_dup 2) (match_dup 3)]
13379 (set (reg:CCFP FPSR_REG)
13380 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13382 "TARGET_USE_FANCY_MATH_387"
13384 [(set_attr "type" "fpspc")
13385 (set_attr "mode" "XF")])
13387 (define_expand "fmodxf3"
13388 [(use (match_operand:XF 0 "register_operand" ""))
13389 (use (match_operand:XF 1 "general_operand" ""))
13390 (use (match_operand:XF 2 "general_operand" ""))]
13391 "TARGET_USE_FANCY_MATH_387"
13393 rtx label = gen_label_rtx ();
13395 rtx op1 = gen_reg_rtx (XFmode);
13396 rtx op2 = gen_reg_rtx (XFmode);
13398 emit_move_insn (op2, operands[2]);
13399 emit_move_insn (op1, operands[1]);
13401 emit_label (label);
13402 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13403 ix86_emit_fp_unordered_jump (label);
13404 LABEL_NUSES (label) = 1;
13406 emit_move_insn (operands[0], op1);
13410 (define_expand "fmod<mode>3"
13411 [(use (match_operand:MODEF 0 "register_operand" ""))
13412 (use (match_operand:MODEF 1 "general_operand" ""))
13413 (use (match_operand:MODEF 2 "general_operand" ""))]
13414 "TARGET_USE_FANCY_MATH_387"
13416 rtx (*gen_truncxf) (rtx, rtx);
13418 rtx label = gen_label_rtx ();
13420 rtx op1 = gen_reg_rtx (XFmode);
13421 rtx op2 = gen_reg_rtx (XFmode);
13423 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13424 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13426 emit_label (label);
13427 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13428 ix86_emit_fp_unordered_jump (label);
13429 LABEL_NUSES (label) = 1;
13431 /* Truncate the result properly for strict SSE math. */
13432 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13433 && !TARGET_MIX_SSE_I387)
13434 gen_truncxf = gen_truncxf<mode>2;
13436 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13438 emit_insn (gen_truncxf (operands[0], op1));
13442 (define_insn "fprem1xf4_i387"
13443 [(set (match_operand:XF 0 "register_operand" "=f")
13444 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13445 (match_operand:XF 3 "register_operand" "1")]
13447 (set (match_operand:XF 1 "register_operand" "=u")
13448 (unspec:XF [(match_dup 2) (match_dup 3)]
13450 (set (reg:CCFP FPSR_REG)
13451 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13453 "TARGET_USE_FANCY_MATH_387"
13455 [(set_attr "type" "fpspc")
13456 (set_attr "mode" "XF")])
13458 (define_expand "remainderxf3"
13459 [(use (match_operand:XF 0 "register_operand" ""))
13460 (use (match_operand:XF 1 "general_operand" ""))
13461 (use (match_operand:XF 2 "general_operand" ""))]
13462 "TARGET_USE_FANCY_MATH_387"
13464 rtx label = gen_label_rtx ();
13466 rtx op1 = gen_reg_rtx (XFmode);
13467 rtx op2 = gen_reg_rtx (XFmode);
13469 emit_move_insn (op2, operands[2]);
13470 emit_move_insn (op1, operands[1]);
13472 emit_label (label);
13473 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13474 ix86_emit_fp_unordered_jump (label);
13475 LABEL_NUSES (label) = 1;
13477 emit_move_insn (operands[0], op1);
13481 (define_expand "remainder<mode>3"
13482 [(use (match_operand:MODEF 0 "register_operand" ""))
13483 (use (match_operand:MODEF 1 "general_operand" ""))
13484 (use (match_operand:MODEF 2 "general_operand" ""))]
13485 "TARGET_USE_FANCY_MATH_387"
13487 rtx (*gen_truncxf) (rtx, rtx);
13489 rtx label = gen_label_rtx ();
13491 rtx op1 = gen_reg_rtx (XFmode);
13492 rtx op2 = gen_reg_rtx (XFmode);
13494 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13495 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13497 emit_label (label);
13499 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13500 ix86_emit_fp_unordered_jump (label);
13501 LABEL_NUSES (label) = 1;
13503 /* Truncate the result properly for strict SSE math. */
13504 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13505 && !TARGET_MIX_SSE_I387)
13506 gen_truncxf = gen_truncxf<mode>2;
13508 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13510 emit_insn (gen_truncxf (operands[0], op1));
13514 (define_insn "*sinxf2_i387"
13515 [(set (match_operand:XF 0 "register_operand" "=f")
13516 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13517 "TARGET_USE_FANCY_MATH_387
13518 && flag_unsafe_math_optimizations"
13520 [(set_attr "type" "fpspc")
13521 (set_attr "mode" "XF")])
13523 (define_insn "*sin_extend<mode>xf2_i387"
13524 [(set (match_operand:XF 0 "register_operand" "=f")
13525 (unspec:XF [(float_extend:XF
13526 (match_operand:MODEF 1 "register_operand" "0"))]
13528 "TARGET_USE_FANCY_MATH_387
13529 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13530 || TARGET_MIX_SSE_I387)
13531 && flag_unsafe_math_optimizations"
13533 [(set_attr "type" "fpspc")
13534 (set_attr "mode" "XF")])
13536 (define_insn "*cosxf2_i387"
13537 [(set (match_operand:XF 0 "register_operand" "=f")
13538 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13539 "TARGET_USE_FANCY_MATH_387
13540 && flag_unsafe_math_optimizations"
13542 [(set_attr "type" "fpspc")
13543 (set_attr "mode" "XF")])
13545 (define_insn "*cos_extend<mode>xf2_i387"
13546 [(set (match_operand:XF 0 "register_operand" "=f")
13547 (unspec:XF [(float_extend:XF
13548 (match_operand:MODEF 1 "register_operand" "0"))]
13550 "TARGET_USE_FANCY_MATH_387
13551 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13552 || TARGET_MIX_SSE_I387)
13553 && flag_unsafe_math_optimizations"
13555 [(set_attr "type" "fpspc")
13556 (set_attr "mode" "XF")])
13558 ;; When sincos pattern is defined, sin and cos builtin functions will be
13559 ;; expanded to sincos pattern with one of its outputs left unused.
13560 ;; CSE pass will figure out if two sincos patterns can be combined,
13561 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13562 ;; depending on the unused output.
13564 (define_insn "sincosxf3"
13565 [(set (match_operand:XF 0 "register_operand" "=f")
13566 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13567 UNSPEC_SINCOS_COS))
13568 (set (match_operand:XF 1 "register_operand" "=u")
13569 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13570 "TARGET_USE_FANCY_MATH_387
13571 && flag_unsafe_math_optimizations"
13573 [(set_attr "type" "fpspc")
13574 (set_attr "mode" "XF")])
13577 [(set (match_operand:XF 0 "register_operand" "")
13578 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13579 UNSPEC_SINCOS_COS))
13580 (set (match_operand:XF 1 "register_operand" "")
13581 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13582 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13583 && !(reload_completed || reload_in_progress)"
13584 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13587 [(set (match_operand:XF 0 "register_operand" "")
13588 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13589 UNSPEC_SINCOS_COS))
13590 (set (match_operand:XF 1 "register_operand" "")
13591 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13592 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13593 && !(reload_completed || reload_in_progress)"
13594 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13596 (define_insn "sincos_extend<mode>xf3_i387"
13597 [(set (match_operand:XF 0 "register_operand" "=f")
13598 (unspec:XF [(float_extend:XF
13599 (match_operand:MODEF 2 "register_operand" "0"))]
13600 UNSPEC_SINCOS_COS))
13601 (set (match_operand:XF 1 "register_operand" "=u")
13602 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13603 "TARGET_USE_FANCY_MATH_387
13604 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13605 || TARGET_MIX_SSE_I387)
13606 && flag_unsafe_math_optimizations"
13608 [(set_attr "type" "fpspc")
13609 (set_attr "mode" "XF")])
13612 [(set (match_operand:XF 0 "register_operand" "")
13613 (unspec:XF [(float_extend:XF
13614 (match_operand:MODEF 2 "register_operand" ""))]
13615 UNSPEC_SINCOS_COS))
13616 (set (match_operand:XF 1 "register_operand" "")
13617 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13618 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13619 && !(reload_completed || reload_in_progress)"
13620 [(set (match_dup 1)
13621 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13624 [(set (match_operand:XF 0 "register_operand" "")
13625 (unspec:XF [(float_extend:XF
13626 (match_operand:MODEF 2 "register_operand" ""))]
13627 UNSPEC_SINCOS_COS))
13628 (set (match_operand:XF 1 "register_operand" "")
13629 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13630 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13631 && !(reload_completed || reload_in_progress)"
13632 [(set (match_dup 0)
13633 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13635 (define_expand "sincos<mode>3"
13636 [(use (match_operand:MODEF 0 "register_operand" ""))
13637 (use (match_operand:MODEF 1 "register_operand" ""))
13638 (use (match_operand:MODEF 2 "register_operand" ""))]
13639 "TARGET_USE_FANCY_MATH_387
13640 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13641 || TARGET_MIX_SSE_I387)
13642 && flag_unsafe_math_optimizations"
13644 rtx op0 = gen_reg_rtx (XFmode);
13645 rtx op1 = gen_reg_rtx (XFmode);
13647 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13648 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13649 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13653 (define_insn "fptanxf4_i387"
13654 [(set (match_operand:XF 0 "register_operand" "=f")
13655 (match_operand:XF 3 "const_double_operand" "F"))
13656 (set (match_operand:XF 1 "register_operand" "=u")
13657 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13659 "TARGET_USE_FANCY_MATH_387
13660 && flag_unsafe_math_optimizations
13661 && standard_80387_constant_p (operands[3]) == 2"
13663 [(set_attr "type" "fpspc")
13664 (set_attr "mode" "XF")])
13666 (define_insn "fptan_extend<mode>xf4_i387"
13667 [(set (match_operand:MODEF 0 "register_operand" "=f")
13668 (match_operand:MODEF 3 "const_double_operand" "F"))
13669 (set (match_operand:XF 1 "register_operand" "=u")
13670 (unspec:XF [(float_extend:XF
13671 (match_operand:MODEF 2 "register_operand" "0"))]
13673 "TARGET_USE_FANCY_MATH_387
13674 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13675 || TARGET_MIX_SSE_I387)
13676 && flag_unsafe_math_optimizations
13677 && standard_80387_constant_p (operands[3]) == 2"
13679 [(set_attr "type" "fpspc")
13680 (set_attr "mode" "XF")])
13682 (define_expand "tanxf2"
13683 [(use (match_operand:XF 0 "register_operand" ""))
13684 (use (match_operand:XF 1 "register_operand" ""))]
13685 "TARGET_USE_FANCY_MATH_387
13686 && flag_unsafe_math_optimizations"
13688 rtx one = gen_reg_rtx (XFmode);
13689 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13691 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13695 (define_expand "tan<mode>2"
13696 [(use (match_operand:MODEF 0 "register_operand" ""))
13697 (use (match_operand:MODEF 1 "register_operand" ""))]
13698 "TARGET_USE_FANCY_MATH_387
13699 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13700 || TARGET_MIX_SSE_I387)
13701 && flag_unsafe_math_optimizations"
13703 rtx op0 = gen_reg_rtx (XFmode);
13705 rtx one = gen_reg_rtx (<MODE>mode);
13706 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13708 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13709 operands[1], op2));
13710 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13714 (define_insn "*fpatanxf3_i387"
13715 [(set (match_operand:XF 0 "register_operand" "=f")
13716 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13717 (match_operand:XF 2 "register_operand" "u")]
13719 (clobber (match_scratch:XF 3 "=2"))]
13720 "TARGET_USE_FANCY_MATH_387
13721 && flag_unsafe_math_optimizations"
13723 [(set_attr "type" "fpspc")
13724 (set_attr "mode" "XF")])
13726 (define_insn "fpatan_extend<mode>xf3_i387"
13727 [(set (match_operand:XF 0 "register_operand" "=f")
13728 (unspec:XF [(float_extend:XF
13729 (match_operand:MODEF 1 "register_operand" "0"))
13731 (match_operand:MODEF 2 "register_operand" "u"))]
13733 (clobber (match_scratch:XF 3 "=2"))]
13734 "TARGET_USE_FANCY_MATH_387
13735 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13736 || TARGET_MIX_SSE_I387)
13737 && flag_unsafe_math_optimizations"
13739 [(set_attr "type" "fpspc")
13740 (set_attr "mode" "XF")])
13742 (define_expand "atan2xf3"
13743 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13744 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13745 (match_operand:XF 1 "register_operand" "")]
13747 (clobber (match_scratch:XF 3 ""))])]
13748 "TARGET_USE_FANCY_MATH_387
13749 && flag_unsafe_math_optimizations")
13751 (define_expand "atan2<mode>3"
13752 [(use (match_operand:MODEF 0 "register_operand" ""))
13753 (use (match_operand:MODEF 1 "register_operand" ""))
13754 (use (match_operand:MODEF 2 "register_operand" ""))]
13755 "TARGET_USE_FANCY_MATH_387
13756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13757 || TARGET_MIX_SSE_I387)
13758 && flag_unsafe_math_optimizations"
13760 rtx op0 = gen_reg_rtx (XFmode);
13762 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13763 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13767 (define_expand "atanxf2"
13768 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13769 (unspec:XF [(match_dup 2)
13770 (match_operand:XF 1 "register_operand" "")]
13772 (clobber (match_scratch:XF 3 ""))])]
13773 "TARGET_USE_FANCY_MATH_387
13774 && flag_unsafe_math_optimizations"
13776 operands[2] = gen_reg_rtx (XFmode);
13777 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13780 (define_expand "atan<mode>2"
13781 [(use (match_operand:MODEF 0 "register_operand" ""))
13782 (use (match_operand:MODEF 1 "register_operand" ""))]
13783 "TARGET_USE_FANCY_MATH_387
13784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13785 || TARGET_MIX_SSE_I387)
13786 && flag_unsafe_math_optimizations"
13788 rtx op0 = gen_reg_rtx (XFmode);
13790 rtx op2 = gen_reg_rtx (<MODE>mode);
13791 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13793 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13794 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13798 (define_expand "asinxf2"
13799 [(set (match_dup 2)
13800 (mult:XF (match_operand:XF 1 "register_operand" "")
13802 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13803 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13804 (parallel [(set (match_operand:XF 0 "register_operand" "")
13805 (unspec:XF [(match_dup 5) (match_dup 1)]
13807 (clobber (match_scratch:XF 6 ""))])]
13808 "TARGET_USE_FANCY_MATH_387
13809 && flag_unsafe_math_optimizations"
13813 if (optimize_insn_for_size_p ())
13816 for (i = 2; i < 6; i++)
13817 operands[i] = gen_reg_rtx (XFmode);
13819 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13822 (define_expand "asin<mode>2"
13823 [(use (match_operand:MODEF 0 "register_operand" ""))
13824 (use (match_operand:MODEF 1 "general_operand" ""))]
13825 "TARGET_USE_FANCY_MATH_387
13826 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13827 || TARGET_MIX_SSE_I387)
13828 && flag_unsafe_math_optimizations"
13830 rtx op0 = gen_reg_rtx (XFmode);
13831 rtx op1 = gen_reg_rtx (XFmode);
13833 if (optimize_insn_for_size_p ())
13836 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13837 emit_insn (gen_asinxf2 (op0, op1));
13838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13842 (define_expand "acosxf2"
13843 [(set (match_dup 2)
13844 (mult:XF (match_operand:XF 1 "register_operand" "")
13846 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13847 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13848 (parallel [(set (match_operand:XF 0 "register_operand" "")
13849 (unspec:XF [(match_dup 1) (match_dup 5)]
13851 (clobber (match_scratch:XF 6 ""))])]
13852 "TARGET_USE_FANCY_MATH_387
13853 && flag_unsafe_math_optimizations"
13857 if (optimize_insn_for_size_p ())
13860 for (i = 2; i < 6; i++)
13861 operands[i] = gen_reg_rtx (XFmode);
13863 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13866 (define_expand "acos<mode>2"
13867 [(use (match_operand:MODEF 0 "register_operand" ""))
13868 (use (match_operand:MODEF 1 "general_operand" ""))]
13869 "TARGET_USE_FANCY_MATH_387
13870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13871 || TARGET_MIX_SSE_I387)
13872 && flag_unsafe_math_optimizations"
13874 rtx op0 = gen_reg_rtx (XFmode);
13875 rtx op1 = gen_reg_rtx (XFmode);
13877 if (optimize_insn_for_size_p ())
13880 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13881 emit_insn (gen_acosxf2 (op0, op1));
13882 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13886 (define_insn "fyl2xxf3_i387"
13887 [(set (match_operand:XF 0 "register_operand" "=f")
13888 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13889 (match_operand:XF 2 "register_operand" "u")]
13891 (clobber (match_scratch:XF 3 "=2"))]
13892 "TARGET_USE_FANCY_MATH_387
13893 && flag_unsafe_math_optimizations"
13895 [(set_attr "type" "fpspc")
13896 (set_attr "mode" "XF")])
13898 (define_insn "fyl2x_extend<mode>xf3_i387"
13899 [(set (match_operand:XF 0 "register_operand" "=f")
13900 (unspec:XF [(float_extend:XF
13901 (match_operand:MODEF 1 "register_operand" "0"))
13902 (match_operand:XF 2 "register_operand" "u")]
13904 (clobber (match_scratch:XF 3 "=2"))]
13905 "TARGET_USE_FANCY_MATH_387
13906 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13907 || TARGET_MIX_SSE_I387)
13908 && flag_unsafe_math_optimizations"
13910 [(set_attr "type" "fpspc")
13911 (set_attr "mode" "XF")])
13913 (define_expand "logxf2"
13914 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13915 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13916 (match_dup 2)] UNSPEC_FYL2X))
13917 (clobber (match_scratch:XF 3 ""))])]
13918 "TARGET_USE_FANCY_MATH_387
13919 && flag_unsafe_math_optimizations"
13921 operands[2] = gen_reg_rtx (XFmode);
13922 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13925 (define_expand "log<mode>2"
13926 [(use (match_operand:MODEF 0 "register_operand" ""))
13927 (use (match_operand:MODEF 1 "register_operand" ""))]
13928 "TARGET_USE_FANCY_MATH_387
13929 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13930 || TARGET_MIX_SSE_I387)
13931 && flag_unsafe_math_optimizations"
13933 rtx op0 = gen_reg_rtx (XFmode);
13935 rtx op2 = gen_reg_rtx (XFmode);
13936 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13938 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13939 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13943 (define_expand "log10xf2"
13944 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13945 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13946 (match_dup 2)] UNSPEC_FYL2X))
13947 (clobber (match_scratch:XF 3 ""))])]
13948 "TARGET_USE_FANCY_MATH_387
13949 && flag_unsafe_math_optimizations"
13951 operands[2] = gen_reg_rtx (XFmode);
13952 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13955 (define_expand "log10<mode>2"
13956 [(use (match_operand:MODEF 0 "register_operand" ""))
13957 (use (match_operand:MODEF 1 "register_operand" ""))]
13958 "TARGET_USE_FANCY_MATH_387
13959 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13960 || TARGET_MIX_SSE_I387)
13961 && flag_unsafe_math_optimizations"
13963 rtx op0 = gen_reg_rtx (XFmode);
13965 rtx op2 = gen_reg_rtx (XFmode);
13966 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13968 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13969 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13973 (define_expand "log2xf2"
13974 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13975 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13976 (match_dup 2)] UNSPEC_FYL2X))
13977 (clobber (match_scratch:XF 3 ""))])]
13978 "TARGET_USE_FANCY_MATH_387
13979 && flag_unsafe_math_optimizations"
13981 operands[2] = gen_reg_rtx (XFmode);
13982 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13985 (define_expand "log2<mode>2"
13986 [(use (match_operand:MODEF 0 "register_operand" ""))
13987 (use (match_operand:MODEF 1 "register_operand" ""))]
13988 "TARGET_USE_FANCY_MATH_387
13989 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13990 || TARGET_MIX_SSE_I387)
13991 && flag_unsafe_math_optimizations"
13993 rtx op0 = gen_reg_rtx (XFmode);
13995 rtx op2 = gen_reg_rtx (XFmode);
13996 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13998 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13999 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14003 (define_insn "fyl2xp1xf3_i387"
14004 [(set (match_operand:XF 0 "register_operand" "=f")
14005 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14006 (match_operand:XF 2 "register_operand" "u")]
14008 (clobber (match_scratch:XF 3 "=2"))]
14009 "TARGET_USE_FANCY_MATH_387
14010 && flag_unsafe_math_optimizations"
14012 [(set_attr "type" "fpspc")
14013 (set_attr "mode" "XF")])
14015 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14016 [(set (match_operand:XF 0 "register_operand" "=f")
14017 (unspec:XF [(float_extend:XF
14018 (match_operand:MODEF 1 "register_operand" "0"))
14019 (match_operand:XF 2 "register_operand" "u")]
14021 (clobber (match_scratch:XF 3 "=2"))]
14022 "TARGET_USE_FANCY_MATH_387
14023 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14024 || TARGET_MIX_SSE_I387)
14025 && flag_unsafe_math_optimizations"
14027 [(set_attr "type" "fpspc")
14028 (set_attr "mode" "XF")])
14030 (define_expand "log1pxf2"
14031 [(use (match_operand:XF 0 "register_operand" ""))
14032 (use (match_operand:XF 1 "register_operand" ""))]
14033 "TARGET_USE_FANCY_MATH_387
14034 && flag_unsafe_math_optimizations"
14036 if (optimize_insn_for_size_p ())
14039 ix86_emit_i387_log1p (operands[0], operands[1]);
14043 (define_expand "log1p<mode>2"
14044 [(use (match_operand:MODEF 0 "register_operand" ""))
14045 (use (match_operand:MODEF 1 "register_operand" ""))]
14046 "TARGET_USE_FANCY_MATH_387
14047 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14048 || TARGET_MIX_SSE_I387)
14049 && flag_unsafe_math_optimizations"
14053 if (optimize_insn_for_size_p ())
14056 op0 = gen_reg_rtx (XFmode);
14058 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14060 ix86_emit_i387_log1p (op0, operands[1]);
14061 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14065 (define_insn "fxtractxf3_i387"
14066 [(set (match_operand:XF 0 "register_operand" "=f")
14067 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14068 UNSPEC_XTRACT_FRACT))
14069 (set (match_operand:XF 1 "register_operand" "=u")
14070 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14071 "TARGET_USE_FANCY_MATH_387
14072 && flag_unsafe_math_optimizations"
14074 [(set_attr "type" "fpspc")
14075 (set_attr "mode" "XF")])
14077 (define_insn "fxtract_extend<mode>xf3_i387"
14078 [(set (match_operand:XF 0 "register_operand" "=f")
14079 (unspec:XF [(float_extend:XF
14080 (match_operand:MODEF 2 "register_operand" "0"))]
14081 UNSPEC_XTRACT_FRACT))
14082 (set (match_operand:XF 1 "register_operand" "=u")
14083 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14084 "TARGET_USE_FANCY_MATH_387
14085 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14086 || TARGET_MIX_SSE_I387)
14087 && flag_unsafe_math_optimizations"
14089 [(set_attr "type" "fpspc")
14090 (set_attr "mode" "XF")])
14092 (define_expand "logbxf2"
14093 [(parallel [(set (match_dup 2)
14094 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14095 UNSPEC_XTRACT_FRACT))
14096 (set (match_operand:XF 0 "register_operand" "")
14097 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14098 "TARGET_USE_FANCY_MATH_387
14099 && flag_unsafe_math_optimizations"
14100 "operands[2] = gen_reg_rtx (XFmode);")
14102 (define_expand "logb<mode>2"
14103 [(use (match_operand:MODEF 0 "register_operand" ""))
14104 (use (match_operand:MODEF 1 "register_operand" ""))]
14105 "TARGET_USE_FANCY_MATH_387
14106 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14107 || TARGET_MIX_SSE_I387)
14108 && flag_unsafe_math_optimizations"
14110 rtx op0 = gen_reg_rtx (XFmode);
14111 rtx op1 = gen_reg_rtx (XFmode);
14113 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14114 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14118 (define_expand "ilogbxf2"
14119 [(use (match_operand:SI 0 "register_operand" ""))
14120 (use (match_operand:XF 1 "register_operand" ""))]
14121 "TARGET_USE_FANCY_MATH_387
14122 && flag_unsafe_math_optimizations"
14126 if (optimize_insn_for_size_p ())
14129 op0 = gen_reg_rtx (XFmode);
14130 op1 = gen_reg_rtx (XFmode);
14132 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14133 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14137 (define_expand "ilogb<mode>2"
14138 [(use (match_operand:SI 0 "register_operand" ""))
14139 (use (match_operand:MODEF 1 "register_operand" ""))]
14140 "TARGET_USE_FANCY_MATH_387
14141 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14142 || TARGET_MIX_SSE_I387)
14143 && flag_unsafe_math_optimizations"
14147 if (optimize_insn_for_size_p ())
14150 op0 = gen_reg_rtx (XFmode);
14151 op1 = gen_reg_rtx (XFmode);
14153 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14154 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14158 (define_insn "*f2xm1xf2_i387"
14159 [(set (match_operand:XF 0 "register_operand" "=f")
14160 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14162 "TARGET_USE_FANCY_MATH_387
14163 && flag_unsafe_math_optimizations"
14165 [(set_attr "type" "fpspc")
14166 (set_attr "mode" "XF")])
14168 (define_insn "*fscalexf4_i387"
14169 [(set (match_operand:XF 0 "register_operand" "=f")
14170 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14171 (match_operand:XF 3 "register_operand" "1")]
14172 UNSPEC_FSCALE_FRACT))
14173 (set (match_operand:XF 1 "register_operand" "=u")
14174 (unspec:XF [(match_dup 2) (match_dup 3)]
14175 UNSPEC_FSCALE_EXP))]
14176 "TARGET_USE_FANCY_MATH_387
14177 && flag_unsafe_math_optimizations"
14179 [(set_attr "type" "fpspc")
14180 (set_attr "mode" "XF")])
14182 (define_expand "expNcorexf3"
14183 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14184 (match_operand:XF 2 "register_operand" "")))
14185 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14186 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14187 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14188 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14189 (parallel [(set (match_operand:XF 0 "register_operand" "")
14190 (unspec:XF [(match_dup 8) (match_dup 4)]
14191 UNSPEC_FSCALE_FRACT))
14193 (unspec:XF [(match_dup 8) (match_dup 4)]
14194 UNSPEC_FSCALE_EXP))])]
14195 "TARGET_USE_FANCY_MATH_387
14196 && flag_unsafe_math_optimizations"
14200 if (optimize_insn_for_size_p ())
14203 for (i = 3; i < 10; i++)
14204 operands[i] = gen_reg_rtx (XFmode);
14206 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14209 (define_expand "expxf2"
14210 [(use (match_operand:XF 0 "register_operand" ""))
14211 (use (match_operand:XF 1 "register_operand" ""))]
14212 "TARGET_USE_FANCY_MATH_387
14213 && flag_unsafe_math_optimizations"
14217 if (optimize_insn_for_size_p ())
14220 op2 = gen_reg_rtx (XFmode);
14221 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14223 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14227 (define_expand "exp<mode>2"
14228 [(use (match_operand:MODEF 0 "register_operand" ""))
14229 (use (match_operand:MODEF 1 "general_operand" ""))]
14230 "TARGET_USE_FANCY_MATH_387
14231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14232 || TARGET_MIX_SSE_I387)
14233 && flag_unsafe_math_optimizations"
14237 if (optimize_insn_for_size_p ())
14240 op0 = gen_reg_rtx (XFmode);
14241 op1 = gen_reg_rtx (XFmode);
14243 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14244 emit_insn (gen_expxf2 (op0, op1));
14245 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14249 (define_expand "exp10xf2"
14250 [(use (match_operand:XF 0 "register_operand" ""))
14251 (use (match_operand:XF 1 "register_operand" ""))]
14252 "TARGET_USE_FANCY_MATH_387
14253 && flag_unsafe_math_optimizations"
14257 if (optimize_insn_for_size_p ())
14260 op2 = gen_reg_rtx (XFmode);
14261 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14263 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14267 (define_expand "exp10<mode>2"
14268 [(use (match_operand:MODEF 0 "register_operand" ""))
14269 (use (match_operand:MODEF 1 "general_operand" ""))]
14270 "TARGET_USE_FANCY_MATH_387
14271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14272 || TARGET_MIX_SSE_I387)
14273 && flag_unsafe_math_optimizations"
14277 if (optimize_insn_for_size_p ())
14280 op0 = gen_reg_rtx (XFmode);
14281 op1 = gen_reg_rtx (XFmode);
14283 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14284 emit_insn (gen_exp10xf2 (op0, op1));
14285 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14289 (define_expand "exp2xf2"
14290 [(use (match_operand:XF 0 "register_operand" ""))
14291 (use (match_operand:XF 1 "register_operand" ""))]
14292 "TARGET_USE_FANCY_MATH_387
14293 && flag_unsafe_math_optimizations"
14297 if (optimize_insn_for_size_p ())
14300 op2 = gen_reg_rtx (XFmode);
14301 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14303 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14307 (define_expand "exp2<mode>2"
14308 [(use (match_operand:MODEF 0 "register_operand" ""))
14309 (use (match_operand:MODEF 1 "general_operand" ""))]
14310 "TARGET_USE_FANCY_MATH_387
14311 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14312 || TARGET_MIX_SSE_I387)
14313 && flag_unsafe_math_optimizations"
14317 if (optimize_insn_for_size_p ())
14320 op0 = gen_reg_rtx (XFmode);
14321 op1 = gen_reg_rtx (XFmode);
14323 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14324 emit_insn (gen_exp2xf2 (op0, op1));
14325 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14329 (define_expand "expm1xf2"
14330 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14332 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14333 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14334 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14335 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14336 (parallel [(set (match_dup 7)
14337 (unspec:XF [(match_dup 6) (match_dup 4)]
14338 UNSPEC_FSCALE_FRACT))
14340 (unspec:XF [(match_dup 6) (match_dup 4)]
14341 UNSPEC_FSCALE_EXP))])
14342 (parallel [(set (match_dup 10)
14343 (unspec:XF [(match_dup 9) (match_dup 8)]
14344 UNSPEC_FSCALE_FRACT))
14345 (set (match_dup 11)
14346 (unspec:XF [(match_dup 9) (match_dup 8)]
14347 UNSPEC_FSCALE_EXP))])
14348 (set (match_dup 12) (minus:XF (match_dup 10)
14349 (float_extend:XF (match_dup 13))))
14350 (set (match_operand:XF 0 "register_operand" "")
14351 (plus:XF (match_dup 12) (match_dup 7)))]
14352 "TARGET_USE_FANCY_MATH_387
14353 && flag_unsafe_math_optimizations"
14357 if (optimize_insn_for_size_p ())
14360 for (i = 2; i < 13; i++)
14361 operands[i] = gen_reg_rtx (XFmode);
14364 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14366 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14369 (define_expand "expm1<mode>2"
14370 [(use (match_operand:MODEF 0 "register_operand" ""))
14371 (use (match_operand:MODEF 1 "general_operand" ""))]
14372 "TARGET_USE_FANCY_MATH_387
14373 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14374 || TARGET_MIX_SSE_I387)
14375 && flag_unsafe_math_optimizations"
14379 if (optimize_insn_for_size_p ())
14382 op0 = gen_reg_rtx (XFmode);
14383 op1 = gen_reg_rtx (XFmode);
14385 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14386 emit_insn (gen_expm1xf2 (op0, op1));
14387 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14391 (define_expand "ldexpxf3"
14392 [(set (match_dup 3)
14393 (float:XF (match_operand:SI 2 "register_operand" "")))
14394 (parallel [(set (match_operand:XF 0 " register_operand" "")
14395 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14397 UNSPEC_FSCALE_FRACT))
14399 (unspec:XF [(match_dup 1) (match_dup 3)]
14400 UNSPEC_FSCALE_EXP))])]
14401 "TARGET_USE_FANCY_MATH_387
14402 && flag_unsafe_math_optimizations"
14404 if (optimize_insn_for_size_p ())
14407 operands[3] = gen_reg_rtx (XFmode);
14408 operands[4] = gen_reg_rtx (XFmode);
14411 (define_expand "ldexp<mode>3"
14412 [(use (match_operand:MODEF 0 "register_operand" ""))
14413 (use (match_operand:MODEF 1 "general_operand" ""))
14414 (use (match_operand:SI 2 "register_operand" ""))]
14415 "TARGET_USE_FANCY_MATH_387
14416 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14417 || TARGET_MIX_SSE_I387)
14418 && flag_unsafe_math_optimizations"
14422 if (optimize_insn_for_size_p ())
14425 op0 = gen_reg_rtx (XFmode);
14426 op1 = gen_reg_rtx (XFmode);
14428 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14429 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14430 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14434 (define_expand "scalbxf3"
14435 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14436 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14437 (match_operand:XF 2 "register_operand" "")]
14438 UNSPEC_FSCALE_FRACT))
14440 (unspec:XF [(match_dup 1) (match_dup 2)]
14441 UNSPEC_FSCALE_EXP))])]
14442 "TARGET_USE_FANCY_MATH_387
14443 && flag_unsafe_math_optimizations"
14445 if (optimize_insn_for_size_p ())
14448 operands[3] = gen_reg_rtx (XFmode);
14451 (define_expand "scalb<mode>3"
14452 [(use (match_operand:MODEF 0 "register_operand" ""))
14453 (use (match_operand:MODEF 1 "general_operand" ""))
14454 (use (match_operand:MODEF 2 "general_operand" ""))]
14455 "TARGET_USE_FANCY_MATH_387
14456 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14457 || TARGET_MIX_SSE_I387)
14458 && flag_unsafe_math_optimizations"
14462 if (optimize_insn_for_size_p ())
14465 op0 = gen_reg_rtx (XFmode);
14466 op1 = gen_reg_rtx (XFmode);
14467 op2 = gen_reg_rtx (XFmode);
14469 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14470 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14471 emit_insn (gen_scalbxf3 (op0, op1, op2));
14472 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14476 (define_expand "significandxf2"
14477 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14478 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14479 UNSPEC_XTRACT_FRACT))
14481 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14482 "TARGET_USE_FANCY_MATH_387
14483 && flag_unsafe_math_optimizations"
14484 "operands[2] = gen_reg_rtx (XFmode);")
14486 (define_expand "significand<mode>2"
14487 [(use (match_operand:MODEF 0 "register_operand" ""))
14488 (use (match_operand:MODEF 1 "register_operand" ""))]
14489 "TARGET_USE_FANCY_MATH_387
14490 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14491 || TARGET_MIX_SSE_I387)
14492 && flag_unsafe_math_optimizations"
14494 rtx op0 = gen_reg_rtx (XFmode);
14495 rtx op1 = gen_reg_rtx (XFmode);
14497 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14498 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14503 (define_insn "sse4_1_round<mode>2"
14504 [(set (match_operand:MODEF 0 "register_operand" "=x")
14505 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14506 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14509 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14510 [(set_attr "type" "ssecvt")
14511 (set_attr "prefix_extra" "1")
14512 (set_attr "prefix" "maybe_vex")
14513 (set_attr "mode" "<MODE>")])
14515 (define_insn "rintxf2"
14516 [(set (match_operand:XF 0 "register_operand" "=f")
14517 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14519 "TARGET_USE_FANCY_MATH_387
14520 && flag_unsafe_math_optimizations"
14522 [(set_attr "type" "fpspc")
14523 (set_attr "mode" "XF")])
14525 (define_expand "rint<mode>2"
14526 [(use (match_operand:MODEF 0 "register_operand" ""))
14527 (use (match_operand:MODEF 1 "register_operand" ""))]
14528 "(TARGET_USE_FANCY_MATH_387
14529 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14530 || TARGET_MIX_SSE_I387)
14531 && flag_unsafe_math_optimizations)
14532 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14533 && !flag_trapping_math)"
14535 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14536 && !flag_trapping_math)
14538 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14541 emit_insn (gen_sse4_1_round<mode>2
14542 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14544 ix86_expand_rint (operand0, operand1);
14548 rtx op0 = gen_reg_rtx (XFmode);
14549 rtx op1 = gen_reg_rtx (XFmode);
14551 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14552 emit_insn (gen_rintxf2 (op0, op1));
14554 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14559 (define_expand "round<mode>2"
14560 [(match_operand:MODEF 0 "register_operand" "")
14561 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14562 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14563 && !flag_trapping_math && !flag_rounding_math"
14565 if (optimize_insn_for_size_p ())
14567 if (TARGET_64BIT || (<MODE>mode != DFmode))
14568 ix86_expand_round (operand0, operand1);
14570 ix86_expand_rounddf_32 (operand0, operand1);
14574 (define_insn_and_split "*fistdi2_1"
14575 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14576 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14578 "TARGET_USE_FANCY_MATH_387
14579 && can_create_pseudo_p ()"
14584 if (memory_operand (operands[0], VOIDmode))
14585 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14588 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14589 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14594 [(set_attr "type" "fpspc")
14595 (set_attr "mode" "DI")])
14597 (define_insn "fistdi2"
14598 [(set (match_operand:DI 0 "memory_operand" "=m")
14599 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14601 (clobber (match_scratch:XF 2 "=&1f"))]
14602 "TARGET_USE_FANCY_MATH_387"
14603 "* return output_fix_trunc (insn, operands, 0);"
14604 [(set_attr "type" "fpspc")
14605 (set_attr "mode" "DI")])
14607 (define_insn "fistdi2_with_temp"
14608 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14609 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14611 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14612 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14613 "TARGET_USE_FANCY_MATH_387"
14615 [(set_attr "type" "fpspc")
14616 (set_attr "mode" "DI")])
14619 [(set (match_operand:DI 0 "register_operand" "")
14620 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14622 (clobber (match_operand:DI 2 "memory_operand" ""))
14623 (clobber (match_scratch 3 ""))]
14625 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14626 (clobber (match_dup 3))])
14627 (set (match_dup 0) (match_dup 2))])
14630 [(set (match_operand:DI 0 "memory_operand" "")
14631 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14633 (clobber (match_operand:DI 2 "memory_operand" ""))
14634 (clobber (match_scratch 3 ""))]
14636 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14637 (clobber (match_dup 3))])])
14639 (define_insn_and_split "*fist<mode>2_1"
14640 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14641 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14643 "TARGET_USE_FANCY_MATH_387
14644 && can_create_pseudo_p ()"
14649 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14650 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14654 [(set_attr "type" "fpspc")
14655 (set_attr "mode" "<MODE>")])
14657 (define_insn "fist<mode>2"
14658 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14659 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14661 "TARGET_USE_FANCY_MATH_387"
14662 "* return output_fix_trunc (insn, operands, 0);"
14663 [(set_attr "type" "fpspc")
14664 (set_attr "mode" "<MODE>")])
14666 (define_insn "fist<mode>2_with_temp"
14667 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14668 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14670 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14671 "TARGET_USE_FANCY_MATH_387"
14673 [(set_attr "type" "fpspc")
14674 (set_attr "mode" "<MODE>")])
14677 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14678 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14680 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14682 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14683 (set (match_dup 0) (match_dup 2))])
14686 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14687 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14689 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14691 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14693 (define_expand "lrintxf<mode>2"
14694 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14695 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14697 "TARGET_USE_FANCY_MATH_387")
14699 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14700 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14701 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14702 UNSPEC_FIX_NOTRUNC))]
14703 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14704 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14706 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14707 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14708 (match_operand:MODEF 1 "register_operand" "")]
14709 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14710 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14711 && !flag_trapping_math && !flag_rounding_math"
14713 if (optimize_insn_for_size_p ())
14715 ix86_expand_lround (operand0, operand1);
14719 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14720 (define_insn_and_split "frndintxf2_floor"
14721 [(set (match_operand:XF 0 "register_operand" "")
14722 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14723 UNSPEC_FRNDINT_FLOOR))
14724 (clobber (reg:CC FLAGS_REG))]
14725 "TARGET_USE_FANCY_MATH_387
14726 && flag_unsafe_math_optimizations
14727 && can_create_pseudo_p ()"
14732 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14734 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14735 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14737 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14738 operands[2], operands[3]));
14741 [(set_attr "type" "frndint")
14742 (set_attr "i387_cw" "floor")
14743 (set_attr "mode" "XF")])
14745 (define_insn "frndintxf2_floor_i387"
14746 [(set (match_operand:XF 0 "register_operand" "=f")
14747 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14748 UNSPEC_FRNDINT_FLOOR))
14749 (use (match_operand:HI 2 "memory_operand" "m"))
14750 (use (match_operand:HI 3 "memory_operand" "m"))]
14751 "TARGET_USE_FANCY_MATH_387
14752 && flag_unsafe_math_optimizations"
14753 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14754 [(set_attr "type" "frndint")
14755 (set_attr "i387_cw" "floor")
14756 (set_attr "mode" "XF")])
14758 (define_expand "floorxf2"
14759 [(use (match_operand:XF 0 "register_operand" ""))
14760 (use (match_operand:XF 1 "register_operand" ""))]
14761 "TARGET_USE_FANCY_MATH_387
14762 && flag_unsafe_math_optimizations"
14764 if (optimize_insn_for_size_p ())
14766 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14770 (define_expand "floor<mode>2"
14771 [(use (match_operand:MODEF 0 "register_operand" ""))
14772 (use (match_operand:MODEF 1 "register_operand" ""))]
14773 "(TARGET_USE_FANCY_MATH_387
14774 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14775 || TARGET_MIX_SSE_I387)
14776 && flag_unsafe_math_optimizations)
14777 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14778 && !flag_trapping_math)"
14780 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14781 && !flag_trapping_math
14782 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14784 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14787 emit_insn (gen_sse4_1_round<mode>2
14788 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14789 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14790 ix86_expand_floorceil (operand0, operand1, true);
14792 ix86_expand_floorceildf_32 (operand0, operand1, true);
14798 if (optimize_insn_for_size_p ())
14801 op0 = gen_reg_rtx (XFmode);
14802 op1 = gen_reg_rtx (XFmode);
14803 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14804 emit_insn (gen_frndintxf2_floor (op0, op1));
14806 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14811 (define_insn_and_split "*fist<mode>2_floor_1"
14812 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14813 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14814 UNSPEC_FIST_FLOOR))
14815 (clobber (reg:CC FLAGS_REG))]
14816 "TARGET_USE_FANCY_MATH_387
14817 && flag_unsafe_math_optimizations
14818 && can_create_pseudo_p ()"
14823 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14825 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14826 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14827 if (memory_operand (operands[0], VOIDmode))
14828 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14829 operands[2], operands[3]));
14832 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14833 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14834 operands[2], operands[3],
14839 [(set_attr "type" "fistp")
14840 (set_attr "i387_cw" "floor")
14841 (set_attr "mode" "<MODE>")])
14843 (define_insn "fistdi2_floor"
14844 [(set (match_operand:DI 0 "memory_operand" "=m")
14845 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14846 UNSPEC_FIST_FLOOR))
14847 (use (match_operand:HI 2 "memory_operand" "m"))
14848 (use (match_operand:HI 3 "memory_operand" "m"))
14849 (clobber (match_scratch:XF 4 "=&1f"))]
14850 "TARGET_USE_FANCY_MATH_387
14851 && flag_unsafe_math_optimizations"
14852 "* return output_fix_trunc (insn, operands, 0);"
14853 [(set_attr "type" "fistp")
14854 (set_attr "i387_cw" "floor")
14855 (set_attr "mode" "DI")])
14857 (define_insn "fistdi2_floor_with_temp"
14858 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14859 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14860 UNSPEC_FIST_FLOOR))
14861 (use (match_operand:HI 2 "memory_operand" "m,m"))
14862 (use (match_operand:HI 3 "memory_operand" "m,m"))
14863 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14864 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14865 "TARGET_USE_FANCY_MATH_387
14866 && flag_unsafe_math_optimizations"
14868 [(set_attr "type" "fistp")
14869 (set_attr "i387_cw" "floor")
14870 (set_attr "mode" "DI")])
14873 [(set (match_operand:DI 0 "register_operand" "")
14874 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14875 UNSPEC_FIST_FLOOR))
14876 (use (match_operand:HI 2 "memory_operand" ""))
14877 (use (match_operand:HI 3 "memory_operand" ""))
14878 (clobber (match_operand:DI 4 "memory_operand" ""))
14879 (clobber (match_scratch 5 ""))]
14881 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14882 (use (match_dup 2))
14883 (use (match_dup 3))
14884 (clobber (match_dup 5))])
14885 (set (match_dup 0) (match_dup 4))])
14888 [(set (match_operand:DI 0 "memory_operand" "")
14889 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14890 UNSPEC_FIST_FLOOR))
14891 (use (match_operand:HI 2 "memory_operand" ""))
14892 (use (match_operand:HI 3 "memory_operand" ""))
14893 (clobber (match_operand:DI 4 "memory_operand" ""))
14894 (clobber (match_scratch 5 ""))]
14896 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14897 (use (match_dup 2))
14898 (use (match_dup 3))
14899 (clobber (match_dup 5))])])
14901 (define_insn "fist<mode>2_floor"
14902 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14903 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14904 UNSPEC_FIST_FLOOR))
14905 (use (match_operand:HI 2 "memory_operand" "m"))
14906 (use (match_operand:HI 3 "memory_operand" "m"))]
14907 "TARGET_USE_FANCY_MATH_387
14908 && flag_unsafe_math_optimizations"
14909 "* return output_fix_trunc (insn, operands, 0);"
14910 [(set_attr "type" "fistp")
14911 (set_attr "i387_cw" "floor")
14912 (set_attr "mode" "<MODE>")])
14914 (define_insn "fist<mode>2_floor_with_temp"
14915 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14916 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14917 UNSPEC_FIST_FLOOR))
14918 (use (match_operand:HI 2 "memory_operand" "m,m"))
14919 (use (match_operand:HI 3 "memory_operand" "m,m"))
14920 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14921 "TARGET_USE_FANCY_MATH_387
14922 && flag_unsafe_math_optimizations"
14924 [(set_attr "type" "fistp")
14925 (set_attr "i387_cw" "floor")
14926 (set_attr "mode" "<MODE>")])
14929 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14930 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14931 UNSPEC_FIST_FLOOR))
14932 (use (match_operand:HI 2 "memory_operand" ""))
14933 (use (match_operand:HI 3 "memory_operand" ""))
14934 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14936 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14937 UNSPEC_FIST_FLOOR))
14938 (use (match_dup 2))
14939 (use (match_dup 3))])
14940 (set (match_dup 0) (match_dup 4))])
14943 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14944 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14945 UNSPEC_FIST_FLOOR))
14946 (use (match_operand:HI 2 "memory_operand" ""))
14947 (use (match_operand:HI 3 "memory_operand" ""))
14948 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14950 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14951 UNSPEC_FIST_FLOOR))
14952 (use (match_dup 2))
14953 (use (match_dup 3))])])
14955 (define_expand "lfloorxf<mode>2"
14956 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14957 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14958 UNSPEC_FIST_FLOOR))
14959 (clobber (reg:CC FLAGS_REG))])]
14960 "TARGET_USE_FANCY_MATH_387
14961 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14962 && flag_unsafe_math_optimizations")
14964 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14965 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14966 (match_operand:MODEF 1 "register_operand" "")]
14967 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14968 && !flag_trapping_math"
14970 if (TARGET_64BIT && optimize_insn_for_size_p ())
14972 ix86_expand_lfloorceil (operand0, operand1, true);
14976 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14977 (define_insn_and_split "frndintxf2_ceil"
14978 [(set (match_operand:XF 0 "register_operand" "")
14979 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14980 UNSPEC_FRNDINT_CEIL))
14981 (clobber (reg:CC FLAGS_REG))]
14982 "TARGET_USE_FANCY_MATH_387
14983 && flag_unsafe_math_optimizations
14984 && can_create_pseudo_p ()"
14989 ix86_optimize_mode_switching[I387_CEIL] = 1;
14991 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14992 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14994 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14995 operands[2], operands[3]));
14998 [(set_attr "type" "frndint")
14999 (set_attr "i387_cw" "ceil")
15000 (set_attr "mode" "XF")])
15002 (define_insn "frndintxf2_ceil_i387"
15003 [(set (match_operand:XF 0 "register_operand" "=f")
15004 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15005 UNSPEC_FRNDINT_CEIL))
15006 (use (match_operand:HI 2 "memory_operand" "m"))
15007 (use (match_operand:HI 3 "memory_operand" "m"))]
15008 "TARGET_USE_FANCY_MATH_387
15009 && flag_unsafe_math_optimizations"
15010 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15011 [(set_attr "type" "frndint")
15012 (set_attr "i387_cw" "ceil")
15013 (set_attr "mode" "XF")])
15015 (define_expand "ceilxf2"
15016 [(use (match_operand:XF 0 "register_operand" ""))
15017 (use (match_operand:XF 1 "register_operand" ""))]
15018 "TARGET_USE_FANCY_MATH_387
15019 && flag_unsafe_math_optimizations"
15021 if (optimize_insn_for_size_p ())
15023 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15027 (define_expand "ceil<mode>2"
15028 [(use (match_operand:MODEF 0 "register_operand" ""))
15029 (use (match_operand:MODEF 1 "register_operand" ""))]
15030 "(TARGET_USE_FANCY_MATH_387
15031 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15032 || TARGET_MIX_SSE_I387)
15033 && flag_unsafe_math_optimizations)
15034 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15035 && !flag_trapping_math)"
15037 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15038 && !flag_trapping_math
15039 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15042 emit_insn (gen_sse4_1_round<mode>2
15043 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15044 else if (optimize_insn_for_size_p ())
15046 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15047 ix86_expand_floorceil (operand0, operand1, false);
15049 ix86_expand_floorceildf_32 (operand0, operand1, false);
15055 if (optimize_insn_for_size_p ())
15058 op0 = gen_reg_rtx (XFmode);
15059 op1 = gen_reg_rtx (XFmode);
15060 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15061 emit_insn (gen_frndintxf2_ceil (op0, op1));
15063 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15068 (define_insn_and_split "*fist<mode>2_ceil_1"
15069 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15070 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15072 (clobber (reg:CC FLAGS_REG))]
15073 "TARGET_USE_FANCY_MATH_387
15074 && flag_unsafe_math_optimizations
15075 && can_create_pseudo_p ()"
15080 ix86_optimize_mode_switching[I387_CEIL] = 1;
15082 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15083 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15084 if (memory_operand (operands[0], VOIDmode))
15085 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15086 operands[2], operands[3]));
15089 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15090 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15091 operands[2], operands[3],
15096 [(set_attr "type" "fistp")
15097 (set_attr "i387_cw" "ceil")
15098 (set_attr "mode" "<MODE>")])
15100 (define_insn "fistdi2_ceil"
15101 [(set (match_operand:DI 0 "memory_operand" "=m")
15102 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15104 (use (match_operand:HI 2 "memory_operand" "m"))
15105 (use (match_operand:HI 3 "memory_operand" "m"))
15106 (clobber (match_scratch:XF 4 "=&1f"))]
15107 "TARGET_USE_FANCY_MATH_387
15108 && flag_unsafe_math_optimizations"
15109 "* return output_fix_trunc (insn, operands, 0);"
15110 [(set_attr "type" "fistp")
15111 (set_attr "i387_cw" "ceil")
15112 (set_attr "mode" "DI")])
15114 (define_insn "fistdi2_ceil_with_temp"
15115 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15116 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15118 (use (match_operand:HI 2 "memory_operand" "m,m"))
15119 (use (match_operand:HI 3 "memory_operand" "m,m"))
15120 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15121 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15122 "TARGET_USE_FANCY_MATH_387
15123 && flag_unsafe_math_optimizations"
15125 [(set_attr "type" "fistp")
15126 (set_attr "i387_cw" "ceil")
15127 (set_attr "mode" "DI")])
15130 [(set (match_operand:DI 0 "register_operand" "")
15131 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15133 (use (match_operand:HI 2 "memory_operand" ""))
15134 (use (match_operand:HI 3 "memory_operand" ""))
15135 (clobber (match_operand:DI 4 "memory_operand" ""))
15136 (clobber (match_scratch 5 ""))]
15138 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15139 (use (match_dup 2))
15140 (use (match_dup 3))
15141 (clobber (match_dup 5))])
15142 (set (match_dup 0) (match_dup 4))])
15145 [(set (match_operand:DI 0 "memory_operand" "")
15146 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15148 (use (match_operand:HI 2 "memory_operand" ""))
15149 (use (match_operand:HI 3 "memory_operand" ""))
15150 (clobber (match_operand:DI 4 "memory_operand" ""))
15151 (clobber (match_scratch 5 ""))]
15153 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15154 (use (match_dup 2))
15155 (use (match_dup 3))
15156 (clobber (match_dup 5))])])
15158 (define_insn "fist<mode>2_ceil"
15159 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15160 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15162 (use (match_operand:HI 2 "memory_operand" "m"))
15163 (use (match_operand:HI 3 "memory_operand" "m"))]
15164 "TARGET_USE_FANCY_MATH_387
15165 && flag_unsafe_math_optimizations"
15166 "* return output_fix_trunc (insn, operands, 0);"
15167 [(set_attr "type" "fistp")
15168 (set_attr "i387_cw" "ceil")
15169 (set_attr "mode" "<MODE>")])
15171 (define_insn "fist<mode>2_ceil_with_temp"
15172 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15173 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15175 (use (match_operand:HI 2 "memory_operand" "m,m"))
15176 (use (match_operand:HI 3 "memory_operand" "m,m"))
15177 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15178 "TARGET_USE_FANCY_MATH_387
15179 && flag_unsafe_math_optimizations"
15181 [(set_attr "type" "fistp")
15182 (set_attr "i387_cw" "ceil")
15183 (set_attr "mode" "<MODE>")])
15186 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15187 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15189 (use (match_operand:HI 2 "memory_operand" ""))
15190 (use (match_operand:HI 3 "memory_operand" ""))
15191 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15193 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15195 (use (match_dup 2))
15196 (use (match_dup 3))])
15197 (set (match_dup 0) (match_dup 4))])
15200 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15201 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15203 (use (match_operand:HI 2 "memory_operand" ""))
15204 (use (match_operand:HI 3 "memory_operand" ""))
15205 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15207 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15209 (use (match_dup 2))
15210 (use (match_dup 3))])])
15212 (define_expand "lceilxf<mode>2"
15213 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15214 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15216 (clobber (reg:CC FLAGS_REG))])]
15217 "TARGET_USE_FANCY_MATH_387
15218 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15219 && flag_unsafe_math_optimizations")
15221 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15222 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15223 (match_operand:MODEF 1 "register_operand" "")]
15224 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15225 && !flag_trapping_math"
15227 ix86_expand_lfloorceil (operand0, operand1, false);
15231 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15232 (define_insn_and_split "frndintxf2_trunc"
15233 [(set (match_operand:XF 0 "register_operand" "")
15234 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15235 UNSPEC_FRNDINT_TRUNC))
15236 (clobber (reg:CC FLAGS_REG))]
15237 "TARGET_USE_FANCY_MATH_387
15238 && flag_unsafe_math_optimizations
15239 && can_create_pseudo_p ()"
15244 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15246 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15247 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15249 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15250 operands[2], operands[3]));
15253 [(set_attr "type" "frndint")
15254 (set_attr "i387_cw" "trunc")
15255 (set_attr "mode" "XF")])
15257 (define_insn "frndintxf2_trunc_i387"
15258 [(set (match_operand:XF 0 "register_operand" "=f")
15259 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15260 UNSPEC_FRNDINT_TRUNC))
15261 (use (match_operand:HI 2 "memory_operand" "m"))
15262 (use (match_operand:HI 3 "memory_operand" "m"))]
15263 "TARGET_USE_FANCY_MATH_387
15264 && flag_unsafe_math_optimizations"
15265 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15266 [(set_attr "type" "frndint")
15267 (set_attr "i387_cw" "trunc")
15268 (set_attr "mode" "XF")])
15270 (define_expand "btruncxf2"
15271 [(use (match_operand:XF 0 "register_operand" ""))
15272 (use (match_operand:XF 1 "register_operand" ""))]
15273 "TARGET_USE_FANCY_MATH_387
15274 && flag_unsafe_math_optimizations"
15276 if (optimize_insn_for_size_p ())
15278 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15282 (define_expand "btrunc<mode>2"
15283 [(use (match_operand:MODEF 0 "register_operand" ""))
15284 (use (match_operand:MODEF 1 "register_operand" ""))]
15285 "(TARGET_USE_FANCY_MATH_387
15286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15287 || TARGET_MIX_SSE_I387)
15288 && flag_unsafe_math_optimizations)
15289 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15290 && !flag_trapping_math)"
15292 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15293 && !flag_trapping_math
15294 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15297 emit_insn (gen_sse4_1_round<mode>2
15298 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15299 else if (optimize_insn_for_size_p ())
15301 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15302 ix86_expand_trunc (operand0, operand1);
15304 ix86_expand_truncdf_32 (operand0, operand1);
15310 if (optimize_insn_for_size_p ())
15313 op0 = gen_reg_rtx (XFmode);
15314 op1 = gen_reg_rtx (XFmode);
15315 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15316 emit_insn (gen_frndintxf2_trunc (op0, op1));
15318 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15323 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15324 (define_insn_and_split "frndintxf2_mask_pm"
15325 [(set (match_operand:XF 0 "register_operand" "")
15326 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15327 UNSPEC_FRNDINT_MASK_PM))
15328 (clobber (reg:CC FLAGS_REG))]
15329 "TARGET_USE_FANCY_MATH_387
15330 && flag_unsafe_math_optimizations
15331 && can_create_pseudo_p ()"
15336 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15338 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15339 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15341 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15342 operands[2], operands[3]));
15345 [(set_attr "type" "frndint")
15346 (set_attr "i387_cw" "mask_pm")
15347 (set_attr "mode" "XF")])
15349 (define_insn "frndintxf2_mask_pm_i387"
15350 [(set (match_operand:XF 0 "register_operand" "=f")
15351 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15352 UNSPEC_FRNDINT_MASK_PM))
15353 (use (match_operand:HI 2 "memory_operand" "m"))
15354 (use (match_operand:HI 3 "memory_operand" "m"))]
15355 "TARGET_USE_FANCY_MATH_387
15356 && flag_unsafe_math_optimizations"
15357 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15358 [(set_attr "type" "frndint")
15359 (set_attr "i387_cw" "mask_pm")
15360 (set_attr "mode" "XF")])
15362 (define_expand "nearbyintxf2"
15363 [(use (match_operand:XF 0 "register_operand" ""))
15364 (use (match_operand:XF 1 "register_operand" ""))]
15365 "TARGET_USE_FANCY_MATH_387
15366 && flag_unsafe_math_optimizations"
15368 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15372 (define_expand "nearbyint<mode>2"
15373 [(use (match_operand:MODEF 0 "register_operand" ""))
15374 (use (match_operand:MODEF 1 "register_operand" ""))]
15375 "TARGET_USE_FANCY_MATH_387
15376 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15377 || TARGET_MIX_SSE_I387)
15378 && flag_unsafe_math_optimizations"
15380 rtx op0 = gen_reg_rtx (XFmode);
15381 rtx op1 = gen_reg_rtx (XFmode);
15383 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15384 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15386 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15390 (define_insn "fxam<mode>2_i387"
15391 [(set (match_operand:HI 0 "register_operand" "=a")
15393 [(match_operand:X87MODEF 1 "register_operand" "f")]
15395 "TARGET_USE_FANCY_MATH_387"
15396 "fxam\n\tfnstsw\t%0"
15397 [(set_attr "type" "multi")
15398 (set_attr "length" "4")
15399 (set_attr "unit" "i387")
15400 (set_attr "mode" "<MODE>")])
15402 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15403 [(set (match_operand:HI 0 "register_operand" "")
15405 [(match_operand:MODEF 1 "memory_operand" "")]
15407 "TARGET_USE_FANCY_MATH_387
15408 && can_create_pseudo_p ()"
15411 [(set (match_dup 2)(match_dup 1))
15413 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15415 operands[2] = gen_reg_rtx (<MODE>mode);
15417 MEM_VOLATILE_P (operands[1]) = 1;
15419 [(set_attr "type" "multi")
15420 (set_attr "unit" "i387")
15421 (set_attr "mode" "<MODE>")])
15423 (define_expand "isinfxf2"
15424 [(use (match_operand:SI 0 "register_operand" ""))
15425 (use (match_operand:XF 1 "register_operand" ""))]
15426 "TARGET_USE_FANCY_MATH_387
15427 && TARGET_C99_FUNCTIONS"
15429 rtx mask = GEN_INT (0x45);
15430 rtx val = GEN_INT (0x05);
15434 rtx scratch = gen_reg_rtx (HImode);
15435 rtx res = gen_reg_rtx (QImode);
15437 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15439 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15440 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15441 cond = gen_rtx_fmt_ee (EQ, QImode,
15442 gen_rtx_REG (CCmode, FLAGS_REG),
15444 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15445 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15449 (define_expand "isinf<mode>2"
15450 [(use (match_operand:SI 0 "register_operand" ""))
15451 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15452 "TARGET_USE_FANCY_MATH_387
15453 && TARGET_C99_FUNCTIONS
15454 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15456 rtx mask = GEN_INT (0x45);
15457 rtx val = GEN_INT (0x05);
15461 rtx scratch = gen_reg_rtx (HImode);
15462 rtx res = gen_reg_rtx (QImode);
15464 /* Remove excess precision by forcing value through memory. */
15465 if (memory_operand (operands[1], VOIDmode))
15466 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15469 enum ix86_stack_slot slot = (virtuals_instantiated
15472 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15474 emit_move_insn (temp, operands[1]);
15475 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15478 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15479 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15480 cond = gen_rtx_fmt_ee (EQ, QImode,
15481 gen_rtx_REG (CCmode, FLAGS_REG),
15483 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15484 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15488 (define_expand "signbitxf2"
15489 [(use (match_operand:SI 0 "register_operand" ""))
15490 (use (match_operand:XF 1 "register_operand" ""))]
15491 "TARGET_USE_FANCY_MATH_387"
15493 rtx scratch = gen_reg_rtx (HImode);
15495 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15496 emit_insn (gen_andsi3 (operands[0],
15497 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15501 (define_insn "movmsk_df"
15502 [(set (match_operand:SI 0 "register_operand" "=r")
15504 [(match_operand:DF 1 "register_operand" "x")]
15506 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15507 "%vmovmskpd\t{%1, %0|%0, %1}"
15508 [(set_attr "type" "ssemov")
15509 (set_attr "prefix" "maybe_vex")
15510 (set_attr "mode" "DF")])
15512 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15513 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15514 (define_expand "signbitdf2"
15515 [(use (match_operand:SI 0 "register_operand" ""))
15516 (use (match_operand:DF 1 "register_operand" ""))]
15517 "TARGET_USE_FANCY_MATH_387
15518 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15520 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15522 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15523 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15527 rtx scratch = gen_reg_rtx (HImode);
15529 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15530 emit_insn (gen_andsi3 (operands[0],
15531 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15536 (define_expand "signbitsf2"
15537 [(use (match_operand:SI 0 "register_operand" ""))
15538 (use (match_operand:SF 1 "register_operand" ""))]
15539 "TARGET_USE_FANCY_MATH_387
15540 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15542 rtx scratch = gen_reg_rtx (HImode);
15544 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15545 emit_insn (gen_andsi3 (operands[0],
15546 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15550 ;; Block operation instructions
15553 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15556 [(set_attr "length" "1")
15557 (set_attr "length_immediate" "0")
15558 (set_attr "modrm" "0")])
15560 (define_expand "movmem<mode>"
15561 [(use (match_operand:BLK 0 "memory_operand" ""))
15562 (use (match_operand:BLK 1 "memory_operand" ""))
15563 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15564 (use (match_operand:SWI48 3 "const_int_operand" ""))
15565 (use (match_operand:SI 4 "const_int_operand" ""))
15566 (use (match_operand:SI 5 "const_int_operand" ""))]
15569 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15570 operands[4], operands[5]))
15576 ;; Most CPUs don't like single string operations
15577 ;; Handle this case here to simplify previous expander.
15579 (define_expand "strmov"
15580 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15581 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15582 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15583 (clobber (reg:CC FLAGS_REG))])
15584 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15585 (clobber (reg:CC FLAGS_REG))])]
15588 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15590 /* If .md ever supports :P for Pmode, these can be directly
15591 in the pattern above. */
15592 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15593 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15595 /* Can't use this if the user has appropriated esi or edi. */
15596 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15597 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15599 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15600 operands[2], operands[3],
15601 operands[5], operands[6]));
15605 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15608 (define_expand "strmov_singleop"
15609 [(parallel [(set (match_operand 1 "memory_operand" "")
15610 (match_operand 3 "memory_operand" ""))
15611 (set (match_operand 0 "register_operand" "")
15612 (match_operand 4 "" ""))
15613 (set (match_operand 2 "register_operand" "")
15614 (match_operand 5 "" ""))])]
15616 "ix86_current_function_needs_cld = 1;")
15618 (define_insn "*strmovdi_rex_1"
15619 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15620 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15621 (set (match_operand:DI 0 "register_operand" "=D")
15622 (plus:DI (match_dup 2)
15624 (set (match_operand:DI 1 "register_operand" "=S")
15625 (plus:DI (match_dup 3)
15629 [(set_attr "type" "str")
15630 (set_attr "memory" "both")
15631 (set_attr "mode" "DI")])
15633 (define_insn "*strmovsi_1"
15634 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15635 (mem:SI (match_operand:P 3 "register_operand" "1")))
15636 (set (match_operand:P 0 "register_operand" "=D")
15637 (plus:P (match_dup 2)
15639 (set (match_operand:P 1 "register_operand" "=S")
15640 (plus:P (match_dup 3)
15644 [(set_attr "type" "str")
15645 (set_attr "memory" "both")
15646 (set_attr "mode" "SI")])
15648 (define_insn "*strmovhi_1"
15649 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15650 (mem:HI (match_operand:P 3 "register_operand" "1")))
15651 (set (match_operand:P 0 "register_operand" "=D")
15652 (plus:P (match_dup 2)
15654 (set (match_operand:P 1 "register_operand" "=S")
15655 (plus:P (match_dup 3)
15659 [(set_attr "type" "str")
15660 (set_attr "memory" "both")
15661 (set_attr "mode" "HI")])
15663 (define_insn "*strmovqi_1"
15664 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15665 (mem:QI (match_operand:P 3 "register_operand" "1")))
15666 (set (match_operand:P 0 "register_operand" "=D")
15667 (plus:P (match_dup 2)
15669 (set (match_operand:P 1 "register_operand" "=S")
15670 (plus:P (match_dup 3)
15674 [(set_attr "type" "str")
15675 (set_attr "memory" "both")
15676 (set (attr "prefix_rex")
15678 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15680 (const_string "*")))
15681 (set_attr "mode" "QI")])
15683 (define_expand "rep_mov"
15684 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15685 (set (match_operand 0 "register_operand" "")
15686 (match_operand 5 "" ""))
15687 (set (match_operand 2 "register_operand" "")
15688 (match_operand 6 "" ""))
15689 (set (match_operand 1 "memory_operand" "")
15690 (match_operand 3 "memory_operand" ""))
15691 (use (match_dup 4))])]
15693 "ix86_current_function_needs_cld = 1;")
15695 (define_insn "*rep_movdi_rex64"
15696 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15697 (set (match_operand:DI 0 "register_operand" "=D")
15698 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15700 (match_operand:DI 3 "register_operand" "0")))
15701 (set (match_operand:DI 1 "register_operand" "=S")
15702 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15703 (match_operand:DI 4 "register_operand" "1")))
15704 (set (mem:BLK (match_dup 3))
15705 (mem:BLK (match_dup 4)))
15706 (use (match_dup 5))]
15709 [(set_attr "type" "str")
15710 (set_attr "prefix_rep" "1")
15711 (set_attr "memory" "both")
15712 (set_attr "mode" "DI")])
15714 (define_insn "*rep_movsi"
15715 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15716 (set (match_operand:P 0 "register_operand" "=D")
15717 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15719 (match_operand:P 3 "register_operand" "0")))
15720 (set (match_operand:P 1 "register_operand" "=S")
15721 (plus:P (ashift:P (match_dup 5) (const_int 2))
15722 (match_operand:P 4 "register_operand" "1")))
15723 (set (mem:BLK (match_dup 3))
15724 (mem:BLK (match_dup 4)))
15725 (use (match_dup 5))]
15727 "rep{%;} movs{l|d}"
15728 [(set_attr "type" "str")
15729 (set_attr "prefix_rep" "1")
15730 (set_attr "memory" "both")
15731 (set_attr "mode" "SI")])
15733 (define_insn "*rep_movqi"
15734 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15735 (set (match_operand:P 0 "register_operand" "=D")
15736 (plus:P (match_operand:P 3 "register_operand" "0")
15737 (match_operand:P 5 "register_operand" "2")))
15738 (set (match_operand:P 1 "register_operand" "=S")
15739 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15740 (set (mem:BLK (match_dup 3))
15741 (mem:BLK (match_dup 4)))
15742 (use (match_dup 5))]
15745 [(set_attr "type" "str")
15746 (set_attr "prefix_rep" "1")
15747 (set_attr "memory" "both")
15748 (set_attr "mode" "QI")])
15750 (define_expand "setmem<mode>"
15751 [(use (match_operand:BLK 0 "memory_operand" ""))
15752 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15753 (use (match_operand:QI 2 "nonmemory_operand" ""))
15754 (use (match_operand 3 "const_int_operand" ""))
15755 (use (match_operand:SI 4 "const_int_operand" ""))
15756 (use (match_operand:SI 5 "const_int_operand" ""))]
15759 if (ix86_expand_setmem (operands[0], operands[1],
15760 operands[2], operands[3],
15761 operands[4], operands[5]))
15767 ;; Most CPUs don't like single string operations
15768 ;; Handle this case here to simplify previous expander.
15770 (define_expand "strset"
15771 [(set (match_operand 1 "memory_operand" "")
15772 (match_operand 2 "register_operand" ""))
15773 (parallel [(set (match_operand 0 "register_operand" "")
15775 (clobber (reg:CC FLAGS_REG))])]
15778 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15779 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15781 /* If .md ever supports :P for Pmode, this can be directly
15782 in the pattern above. */
15783 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15784 GEN_INT (GET_MODE_SIZE (GET_MODE
15786 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15788 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15794 (define_expand "strset_singleop"
15795 [(parallel [(set (match_operand 1 "memory_operand" "")
15796 (match_operand 2 "register_operand" ""))
15797 (set (match_operand 0 "register_operand" "")
15798 (match_operand 3 "" ""))])]
15800 "ix86_current_function_needs_cld = 1;")
15802 (define_insn "*strsetdi_rex_1"
15803 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15804 (match_operand:DI 2 "register_operand" "a"))
15805 (set (match_operand:DI 0 "register_operand" "=D")
15806 (plus:DI (match_dup 1)
15810 [(set_attr "type" "str")
15811 (set_attr "memory" "store")
15812 (set_attr "mode" "DI")])
15814 (define_insn "*strsetsi_1"
15815 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15816 (match_operand:SI 2 "register_operand" "a"))
15817 (set (match_operand:P 0 "register_operand" "=D")
15818 (plus:P (match_dup 1)
15822 [(set_attr "type" "str")
15823 (set_attr "memory" "store")
15824 (set_attr "mode" "SI")])
15826 (define_insn "*strsethi_1"
15827 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15828 (match_operand:HI 2 "register_operand" "a"))
15829 (set (match_operand:P 0 "register_operand" "=D")
15830 (plus:P (match_dup 1)
15834 [(set_attr "type" "str")
15835 (set_attr "memory" "store")
15836 (set_attr "mode" "HI")])
15838 (define_insn "*strsetqi_1"
15839 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15840 (match_operand:QI 2 "register_operand" "a"))
15841 (set (match_operand:P 0 "register_operand" "=D")
15842 (plus:P (match_dup 1)
15846 [(set_attr "type" "str")
15847 (set_attr "memory" "store")
15848 (set (attr "prefix_rex")
15850 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15852 (const_string "*")))
15853 (set_attr "mode" "QI")])
15855 (define_expand "rep_stos"
15856 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15857 (set (match_operand 0 "register_operand" "")
15858 (match_operand 4 "" ""))
15859 (set (match_operand 2 "memory_operand" "") (const_int 0))
15860 (use (match_operand 3 "register_operand" ""))
15861 (use (match_dup 1))])]
15863 "ix86_current_function_needs_cld = 1;")
15865 (define_insn "*rep_stosdi_rex64"
15866 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15867 (set (match_operand:DI 0 "register_operand" "=D")
15868 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15870 (match_operand:DI 3 "register_operand" "0")))
15871 (set (mem:BLK (match_dup 3))
15873 (use (match_operand:DI 2 "register_operand" "a"))
15874 (use (match_dup 4))]
15877 [(set_attr "type" "str")
15878 (set_attr "prefix_rep" "1")
15879 (set_attr "memory" "store")
15880 (set_attr "mode" "DI")])
15882 (define_insn "*rep_stossi"
15883 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15884 (set (match_operand:P 0 "register_operand" "=D")
15885 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15887 (match_operand:P 3 "register_operand" "0")))
15888 (set (mem:BLK (match_dup 3))
15890 (use (match_operand:SI 2 "register_operand" "a"))
15891 (use (match_dup 4))]
15893 "rep{%;} stos{l|d}"
15894 [(set_attr "type" "str")
15895 (set_attr "prefix_rep" "1")
15896 (set_attr "memory" "store")
15897 (set_attr "mode" "SI")])
15899 (define_insn "*rep_stosqi"
15900 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15901 (set (match_operand:P 0 "register_operand" "=D")
15902 (plus:P (match_operand:P 3 "register_operand" "0")
15903 (match_operand:P 4 "register_operand" "1")))
15904 (set (mem:BLK (match_dup 3))
15906 (use (match_operand:QI 2 "register_operand" "a"))
15907 (use (match_dup 4))]
15910 [(set_attr "type" "str")
15911 (set_attr "prefix_rep" "1")
15912 (set_attr "memory" "store")
15913 (set (attr "prefix_rex")
15915 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15917 (const_string "*")))
15918 (set_attr "mode" "QI")])
15920 (define_expand "cmpstrnsi"
15921 [(set (match_operand:SI 0 "register_operand" "")
15922 (compare:SI (match_operand:BLK 1 "general_operand" "")
15923 (match_operand:BLK 2 "general_operand" "")))
15924 (use (match_operand 3 "general_operand" ""))
15925 (use (match_operand 4 "immediate_operand" ""))]
15928 rtx addr1, addr2, out, outlow, count, countreg, align;
15930 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15933 /* Can't use this if the user has appropriated esi or edi. */
15934 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15939 out = gen_reg_rtx (SImode);
15941 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15942 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15943 if (addr1 != XEXP (operands[1], 0))
15944 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15945 if (addr2 != XEXP (operands[2], 0))
15946 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15948 count = operands[3];
15949 countreg = ix86_zero_extend_to_Pmode (count);
15951 /* %%% Iff we are testing strict equality, we can use known alignment
15952 to good advantage. This may be possible with combine, particularly
15953 once cc0 is dead. */
15954 align = operands[4];
15956 if (CONST_INT_P (count))
15958 if (INTVAL (count) == 0)
15960 emit_move_insn (operands[0], const0_rtx);
15963 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15964 operands[1], operands[2]));
15968 rtx (*gen_cmp) (rtx, rtx);
15970 gen_cmp = (TARGET_64BIT
15971 ? gen_cmpdi_1 : gen_cmpsi_1);
15973 emit_insn (gen_cmp (countreg, countreg));
15974 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15975 operands[1], operands[2]));
15978 outlow = gen_lowpart (QImode, out);
15979 emit_insn (gen_cmpintqi (outlow));
15980 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15982 if (operands[0] != out)
15983 emit_move_insn (operands[0], out);
15988 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15990 (define_expand "cmpintqi"
15991 [(set (match_dup 1)
15992 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15994 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15995 (parallel [(set (match_operand:QI 0 "register_operand" "")
15996 (minus:QI (match_dup 1)
15998 (clobber (reg:CC FLAGS_REG))])]
16001 operands[1] = gen_reg_rtx (QImode);
16002 operands[2] = gen_reg_rtx (QImode);
16005 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16006 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16008 (define_expand "cmpstrnqi_nz_1"
16009 [(parallel [(set (reg:CC FLAGS_REG)
16010 (compare:CC (match_operand 4 "memory_operand" "")
16011 (match_operand 5 "memory_operand" "")))
16012 (use (match_operand 2 "register_operand" ""))
16013 (use (match_operand:SI 3 "immediate_operand" ""))
16014 (clobber (match_operand 0 "register_operand" ""))
16015 (clobber (match_operand 1 "register_operand" ""))
16016 (clobber (match_dup 2))])]
16018 "ix86_current_function_needs_cld = 1;")
16020 (define_insn "*cmpstrnqi_nz_1"
16021 [(set (reg:CC FLAGS_REG)
16022 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16023 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16024 (use (match_operand:P 6 "register_operand" "2"))
16025 (use (match_operand:SI 3 "immediate_operand" "i"))
16026 (clobber (match_operand:P 0 "register_operand" "=S"))
16027 (clobber (match_operand:P 1 "register_operand" "=D"))
16028 (clobber (match_operand:P 2 "register_operand" "=c"))]
16031 [(set_attr "type" "str")
16032 (set_attr "mode" "QI")
16033 (set (attr "prefix_rex")
16035 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16037 (const_string "*")))
16038 (set_attr "prefix_rep" "1")])
16040 ;; The same, but the count is not known to not be zero.
16042 (define_expand "cmpstrnqi_1"
16043 [(parallel [(set (reg:CC FLAGS_REG)
16044 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16046 (compare:CC (match_operand 4 "memory_operand" "")
16047 (match_operand 5 "memory_operand" ""))
16049 (use (match_operand:SI 3 "immediate_operand" ""))
16050 (use (reg:CC FLAGS_REG))
16051 (clobber (match_operand 0 "register_operand" ""))
16052 (clobber (match_operand 1 "register_operand" ""))
16053 (clobber (match_dup 2))])]
16055 "ix86_current_function_needs_cld = 1;")
16057 (define_insn "*cmpstrnqi_1"
16058 [(set (reg:CC FLAGS_REG)
16059 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16061 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16062 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16064 (use (match_operand:SI 3 "immediate_operand" "i"))
16065 (use (reg:CC FLAGS_REG))
16066 (clobber (match_operand:P 0 "register_operand" "=S"))
16067 (clobber (match_operand:P 1 "register_operand" "=D"))
16068 (clobber (match_operand:P 2 "register_operand" "=c"))]
16071 [(set_attr "type" "str")
16072 (set_attr "mode" "QI")
16073 (set (attr "prefix_rex")
16075 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16077 (const_string "*")))
16078 (set_attr "prefix_rep" "1")])
16080 (define_expand "strlen<mode>"
16081 [(set (match_operand:SWI48x 0 "register_operand" "")
16082 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16083 (match_operand:QI 2 "immediate_operand" "")
16084 (match_operand 3 "immediate_operand" "")]
16088 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16094 (define_expand "strlenqi_1"
16095 [(parallel [(set (match_operand 0 "register_operand" "")
16096 (match_operand 2 "" ""))
16097 (clobber (match_operand 1 "register_operand" ""))
16098 (clobber (reg:CC FLAGS_REG))])]
16100 "ix86_current_function_needs_cld = 1;")
16102 (define_insn "*strlenqi_1"
16103 [(set (match_operand:P 0 "register_operand" "=&c")
16104 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16105 (match_operand:QI 2 "register_operand" "a")
16106 (match_operand:P 3 "immediate_operand" "i")
16107 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16108 (clobber (match_operand:P 1 "register_operand" "=D"))
16109 (clobber (reg:CC FLAGS_REG))]
16112 [(set_attr "type" "str")
16113 (set_attr "mode" "QI")
16114 (set (attr "prefix_rex")
16116 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16118 (const_string "*")))
16119 (set_attr "prefix_rep" "1")])
16121 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16122 ;; handled in combine, but it is not currently up to the task.
16123 ;; When used for their truth value, the cmpstrn* expanders generate
16132 ;; The intermediate three instructions are unnecessary.
16134 ;; This one handles cmpstrn*_nz_1...
16137 (set (reg:CC FLAGS_REG)
16138 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16139 (mem:BLK (match_operand 5 "register_operand" ""))))
16140 (use (match_operand 6 "register_operand" ""))
16141 (use (match_operand:SI 3 "immediate_operand" ""))
16142 (clobber (match_operand 0 "register_operand" ""))
16143 (clobber (match_operand 1 "register_operand" ""))
16144 (clobber (match_operand 2 "register_operand" ""))])
16145 (set (match_operand:QI 7 "register_operand" "")
16146 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16147 (set (match_operand:QI 8 "register_operand" "")
16148 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16149 (set (reg FLAGS_REG)
16150 (compare (match_dup 7) (match_dup 8)))
16152 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16154 (set (reg:CC FLAGS_REG)
16155 (compare:CC (mem:BLK (match_dup 4))
16156 (mem:BLK (match_dup 5))))
16157 (use (match_dup 6))
16158 (use (match_dup 3))
16159 (clobber (match_dup 0))
16160 (clobber (match_dup 1))
16161 (clobber (match_dup 2))])])
16163 ;; ...and this one handles cmpstrn*_1.
16166 (set (reg:CC FLAGS_REG)
16167 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16169 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16170 (mem:BLK (match_operand 5 "register_operand" "")))
16172 (use (match_operand:SI 3 "immediate_operand" ""))
16173 (use (reg:CC FLAGS_REG))
16174 (clobber (match_operand 0 "register_operand" ""))
16175 (clobber (match_operand 1 "register_operand" ""))
16176 (clobber (match_operand 2 "register_operand" ""))])
16177 (set (match_operand:QI 7 "register_operand" "")
16178 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16179 (set (match_operand:QI 8 "register_operand" "")
16180 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16181 (set (reg FLAGS_REG)
16182 (compare (match_dup 7) (match_dup 8)))
16184 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16186 (set (reg:CC FLAGS_REG)
16187 (if_then_else:CC (ne (match_dup 6)
16189 (compare:CC (mem:BLK (match_dup 4))
16190 (mem:BLK (match_dup 5)))
16192 (use (match_dup 3))
16193 (use (reg:CC FLAGS_REG))
16194 (clobber (match_dup 0))
16195 (clobber (match_dup 1))
16196 (clobber (match_dup 2))])])
16198 ;; Conditional move instructions.
16200 (define_expand "mov<mode>cc"
16201 [(set (match_operand:SWIM 0 "register_operand" "")
16202 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16203 (match_operand:SWIM 2 "general_operand" "")
16204 (match_operand:SWIM 3 "general_operand" "")))]
16206 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16208 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16209 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16210 ;; So just document what we're doing explicitly.
16212 (define_expand "x86_mov<mode>cc_0_m1"
16214 [(set (match_operand:SWI48 0 "register_operand" "")
16215 (if_then_else:SWI48
16216 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16217 [(match_operand 1 "flags_reg_operand" "")
16221 (clobber (reg:CC FLAGS_REG))])])
16223 (define_insn "*x86_mov<mode>cc_0_m1"
16224 [(set (match_operand:SWI48 0 "register_operand" "=r")
16225 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16226 [(reg FLAGS_REG) (const_int 0)])
16229 (clobber (reg:CC FLAGS_REG))]
16231 "sbb{<imodesuffix>}\t%0, %0"
16232 ; Since we don't have the proper number of operands for an alu insn,
16233 ; fill in all the blanks.
16234 [(set_attr "type" "alu")
16235 (set_attr "use_carry" "1")
16236 (set_attr "pent_pair" "pu")
16237 (set_attr "memory" "none")
16238 (set_attr "imm_disp" "false")
16239 (set_attr "mode" "<MODE>")
16240 (set_attr "length_immediate" "0")])
16242 (define_insn "*x86_mov<mode>cc_0_m1_se"
16243 [(set (match_operand:SWI48 0 "register_operand" "=r")
16244 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16245 [(reg FLAGS_REG) (const_int 0)])
16248 (clobber (reg:CC FLAGS_REG))]
16250 "sbb{<imodesuffix>}\t%0, %0"
16251 [(set_attr "type" "alu")
16252 (set_attr "use_carry" "1")
16253 (set_attr "pent_pair" "pu")
16254 (set_attr "memory" "none")
16255 (set_attr "imm_disp" "false")
16256 (set_attr "mode" "<MODE>")
16257 (set_attr "length_immediate" "0")])
16259 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16260 [(set (match_operand:SWI48 0 "register_operand" "=r")
16261 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16262 [(reg FLAGS_REG) (const_int 0)])))]
16264 "sbb{<imodesuffix>}\t%0, %0"
16265 [(set_attr "type" "alu")
16266 (set_attr "use_carry" "1")
16267 (set_attr "pent_pair" "pu")
16268 (set_attr "memory" "none")
16269 (set_attr "imm_disp" "false")
16270 (set_attr "mode" "<MODE>")
16271 (set_attr "length_immediate" "0")])
16273 (define_insn "*mov<mode>cc_noc"
16274 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16275 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16276 [(reg FLAGS_REG) (const_int 0)])
16277 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16278 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16279 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16281 cmov%O2%C1\t{%2, %0|%0, %2}
16282 cmov%O2%c1\t{%3, %0|%0, %3}"
16283 [(set_attr "type" "icmov")
16284 (set_attr "mode" "<MODE>")])
16286 (define_insn_and_split "*movqicc_noc"
16287 [(set (match_operand:QI 0 "register_operand" "=r,r")
16288 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16289 [(match_operand 4 "flags_reg_operand" "")
16291 (match_operand:QI 2 "register_operand" "r,0")
16292 (match_operand:QI 3 "register_operand" "0,r")))]
16293 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16295 "&& reload_completed"
16296 [(set (match_dup 0)
16297 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16300 "operands[0] = gen_lowpart (SImode, operands[0]);
16301 operands[2] = gen_lowpart (SImode, operands[2]);
16302 operands[3] = gen_lowpart (SImode, operands[3]);"
16303 [(set_attr "type" "icmov")
16304 (set_attr "mode" "SI")])
16306 (define_expand "mov<mode>cc"
16307 [(set (match_operand:X87MODEF 0 "register_operand" "")
16308 (if_then_else:X87MODEF
16309 (match_operand 1 "ix86_fp_comparison_operator" "")
16310 (match_operand:X87MODEF 2 "register_operand" "")
16311 (match_operand:X87MODEF 3 "register_operand" "")))]
16312 "(TARGET_80387 && TARGET_CMOVE)
16313 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16314 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16316 (define_insn "*movxfcc_1"
16317 [(set (match_operand:XF 0 "register_operand" "=f,f")
16318 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16319 [(reg FLAGS_REG) (const_int 0)])
16320 (match_operand:XF 2 "register_operand" "f,0")
16321 (match_operand:XF 3 "register_operand" "0,f")))]
16322 "TARGET_80387 && TARGET_CMOVE"
16324 fcmov%F1\t{%2, %0|%0, %2}
16325 fcmov%f1\t{%3, %0|%0, %3}"
16326 [(set_attr "type" "fcmov")
16327 (set_attr "mode" "XF")])
16329 (define_insn "*movdfcc_1_rex64"
16330 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16331 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16332 [(reg FLAGS_REG) (const_int 0)])
16333 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16334 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16335 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16336 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16338 fcmov%F1\t{%2, %0|%0, %2}
16339 fcmov%f1\t{%3, %0|%0, %3}
16340 cmov%O2%C1\t{%2, %0|%0, %2}
16341 cmov%O2%c1\t{%3, %0|%0, %3}"
16342 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16343 (set_attr "mode" "DF,DF,DI,DI")])
16345 (define_insn "*movdfcc_1"
16346 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16347 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16348 [(reg FLAGS_REG) (const_int 0)])
16349 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16350 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16351 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16352 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16354 fcmov%F1\t{%2, %0|%0, %2}
16355 fcmov%f1\t{%3, %0|%0, %3}
16358 [(set_attr "type" "fcmov,fcmov,multi,multi")
16359 (set_attr "mode" "DF,DF,DI,DI")])
16362 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16363 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16364 [(match_operand 4 "flags_reg_operand" "")
16366 (match_operand:DF 2 "nonimmediate_operand" "")
16367 (match_operand:DF 3 "nonimmediate_operand" "")))]
16368 "!TARGET_64BIT && reload_completed"
16369 [(set (match_dup 2)
16370 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16374 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16378 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16379 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16382 (define_insn "*movsfcc_1_387"
16383 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16384 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16385 [(reg FLAGS_REG) (const_int 0)])
16386 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16387 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16388 "TARGET_80387 && TARGET_CMOVE
16389 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16391 fcmov%F1\t{%2, %0|%0, %2}
16392 fcmov%f1\t{%3, %0|%0, %3}
16393 cmov%O2%C1\t{%2, %0|%0, %2}
16394 cmov%O2%c1\t{%3, %0|%0, %3}"
16395 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16396 (set_attr "mode" "SF,SF,SI,SI")])
16398 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16399 ;; the scalar versions to have only XMM registers as operands.
16401 ;; XOP conditional move
16402 (define_insn "*xop_pcmov_<mode>"
16403 [(set (match_operand:MODEF 0 "register_operand" "=x")
16404 (if_then_else:MODEF
16405 (match_operand:MODEF 1 "register_operand" "x")
16406 (match_operand:MODEF 2 "register_operand" "x")
16407 (match_operand:MODEF 3 "register_operand" "x")))]
16409 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16410 [(set_attr "type" "sse4arg")])
16412 ;; These versions of the min/max patterns are intentionally ignorant of
16413 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16414 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16415 ;; are undefined in this condition, we're certain this is correct.
16417 (define_insn "<code><mode>3"
16418 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16420 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16421 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16422 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16424 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16425 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16426 [(set_attr "isa" "noavx,avx")
16427 (set_attr "prefix" "orig,vex")
16428 (set_attr "type" "sseadd")
16429 (set_attr "mode" "<MODE>")])
16431 ;; These versions of the min/max patterns implement exactly the operations
16432 ;; min = (op1 < op2 ? op1 : op2)
16433 ;; max = (!(op1 < op2) ? op1 : op2)
16434 ;; Their operands are not commutative, and thus they may be used in the
16435 ;; presence of -0.0 and NaN.
16437 (define_insn "*ieee_smin<mode>3"
16438 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16440 [(match_operand:MODEF 1 "register_operand" "0,x")
16441 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16443 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16445 min<ssemodesuffix>\t{%2, %0|%0, %2}
16446 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16447 [(set_attr "isa" "noavx,avx")
16448 (set_attr "prefix" "orig,vex")
16449 (set_attr "type" "sseadd")
16450 (set_attr "mode" "<MODE>")])
16452 (define_insn "*ieee_smax<mode>3"
16453 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16455 [(match_operand:MODEF 1 "register_operand" "0,x")
16456 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16458 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16460 max<ssemodesuffix>\t{%2, %0|%0, %2}
16461 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16462 [(set_attr "isa" "noavx,avx")
16463 (set_attr "prefix" "orig,vex")
16464 (set_attr "type" "sseadd")
16465 (set_attr "mode" "<MODE>")])
16467 ;; Make two stack loads independent:
16469 ;; fld %st(0) -> fld bb
16470 ;; fmul bb fmul %st(1), %st
16472 ;; Actually we only match the last two instructions for simplicity.
16474 [(set (match_operand 0 "fp_register_operand" "")
16475 (match_operand 1 "fp_register_operand" ""))
16477 (match_operator 2 "binary_fp_operator"
16479 (match_operand 3 "memory_operand" "")]))]
16480 "REGNO (operands[0]) != REGNO (operands[1])"
16481 [(set (match_dup 0) (match_dup 3))
16482 (set (match_dup 0) (match_dup 4))]
16484 ;; The % modifier is not operational anymore in peephole2's, so we have to
16485 ;; swap the operands manually in the case of addition and multiplication.
16486 "if (COMMUTATIVE_ARITH_P (operands[2]))
16487 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16488 GET_MODE (operands[2]),
16489 operands[0], operands[1]);
16491 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16492 GET_MODE (operands[2]),
16493 operands[1], operands[0]);")
16495 ;; Conditional addition patterns
16496 (define_expand "add<mode>cc"
16497 [(match_operand:SWI 0 "register_operand" "")
16498 (match_operand 1 "ordered_comparison_operator" "")
16499 (match_operand:SWI 2 "register_operand" "")
16500 (match_operand:SWI 3 "const_int_operand" "")]
16502 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16504 ;; Misc patterns (?)
16506 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16507 ;; Otherwise there will be nothing to keep
16509 ;; [(set (reg ebp) (reg esp))]
16510 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16511 ;; (clobber (eflags)]
16512 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16514 ;; in proper program order.
16516 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16517 [(set (match_operand:P 0 "register_operand" "=r,r")
16518 (plus:P (match_operand:P 1 "register_operand" "0,r")
16519 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16520 (clobber (reg:CC FLAGS_REG))
16521 (clobber (mem:BLK (scratch)))]
16524 switch (get_attr_type (insn))
16527 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16530 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16531 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16532 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16534 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16537 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16538 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16541 [(set (attr "type")
16542 (cond [(and (eq_attr "alternative" "0")
16543 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16544 (const_string "alu")
16545 (match_operand:<MODE> 2 "const0_operand" "")
16546 (const_string "imov")
16548 (const_string "lea")))
16549 (set (attr "length_immediate")
16550 (cond [(eq_attr "type" "imov")
16552 (and (eq_attr "type" "alu")
16553 (match_operand 2 "const128_operand" ""))
16556 (const_string "*")))
16557 (set_attr "mode" "<MODE>")])
16559 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16560 [(set (match_operand:P 0 "register_operand" "=r")
16561 (minus:P (match_operand:P 1 "register_operand" "0")
16562 (match_operand:P 2 "register_operand" "r")))
16563 (clobber (reg:CC FLAGS_REG))
16564 (clobber (mem:BLK (scratch)))]
16566 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16567 [(set_attr "type" "alu")
16568 (set_attr "mode" "<MODE>")])
16570 (define_insn "allocate_stack_worker_probe_<mode>"
16571 [(set (match_operand:P 0 "register_operand" "=a")
16572 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16573 UNSPECV_STACK_PROBE))
16574 (clobber (reg:CC FLAGS_REG))]
16575 "ix86_target_stack_probe ()"
16576 "call\t___chkstk_ms"
16577 [(set_attr "type" "multi")
16578 (set_attr "length" "5")])
16580 (define_expand "allocate_stack"
16581 [(match_operand 0 "register_operand" "")
16582 (match_operand 1 "general_operand" "")]
16583 "ix86_target_stack_probe ()"
16587 #ifndef CHECK_STACK_LIMIT
16588 #define CHECK_STACK_LIMIT 0
16591 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16592 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16594 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16595 stack_pointer_rtx, 0, OPTAB_DIRECT);
16596 if (x != stack_pointer_rtx)
16597 emit_move_insn (stack_pointer_rtx, x);
16601 x = copy_to_mode_reg (Pmode, operands[1]);
16603 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16605 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16606 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16607 stack_pointer_rtx, 0, OPTAB_DIRECT);
16608 if (x != stack_pointer_rtx)
16609 emit_move_insn (stack_pointer_rtx, x);
16612 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16616 ;; Use IOR for stack probes, this is shorter.
16617 (define_expand "probe_stack"
16618 [(match_operand 0 "memory_operand" "")]
16621 rtx (*gen_ior3) (rtx, rtx, rtx);
16623 gen_ior3 = (GET_MODE (operands[0]) == DImode
16624 ? gen_iordi3 : gen_iorsi3);
16626 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16630 (define_insn "adjust_stack_and_probe<mode>"
16631 [(set (match_operand:P 0 "register_operand" "=r")
16632 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16633 UNSPECV_PROBE_STACK_RANGE))
16634 (set (reg:P SP_REG)
16635 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16636 (clobber (reg:CC FLAGS_REG))
16637 (clobber (mem:BLK (scratch)))]
16639 "* return output_adjust_stack_and_probe (operands[0]);"
16640 [(set_attr "type" "multi")])
16642 (define_insn "probe_stack_range<mode>"
16643 [(set (match_operand:P 0 "register_operand" "=r")
16644 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16645 (match_operand:P 2 "const_int_operand" "n")]
16646 UNSPECV_PROBE_STACK_RANGE))
16647 (clobber (reg:CC FLAGS_REG))]
16649 "* return output_probe_stack_range (operands[0], operands[2]);"
16650 [(set_attr "type" "multi")])
16652 (define_expand "builtin_setjmp_receiver"
16653 [(label_ref (match_operand 0 "" ""))]
16654 "!TARGET_64BIT && flag_pic"
16660 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16661 rtx label_rtx = gen_label_rtx ();
16662 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16663 xops[0] = xops[1] = picreg;
16664 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16665 ix86_expand_binary_operator (MINUS, SImode, xops);
16669 emit_insn (gen_set_got (pic_offset_table_rtx));
16673 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16676 [(set (match_operand 0 "register_operand" "")
16677 (match_operator 3 "promotable_binary_operator"
16678 [(match_operand 1 "register_operand" "")
16679 (match_operand 2 "aligned_operand" "")]))
16680 (clobber (reg:CC FLAGS_REG))]
16681 "! TARGET_PARTIAL_REG_STALL && reload_completed
16682 && ((GET_MODE (operands[0]) == HImode
16683 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16684 /* ??? next two lines just !satisfies_constraint_K (...) */
16685 || !CONST_INT_P (operands[2])
16686 || satisfies_constraint_K (operands[2])))
16687 || (GET_MODE (operands[0]) == QImode
16688 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16689 [(parallel [(set (match_dup 0)
16690 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16691 (clobber (reg:CC FLAGS_REG))])]
16692 "operands[0] = gen_lowpart (SImode, operands[0]);
16693 operands[1] = gen_lowpart (SImode, operands[1]);
16694 if (GET_CODE (operands[3]) != ASHIFT)
16695 operands[2] = gen_lowpart (SImode, operands[2]);
16696 PUT_MODE (operands[3], SImode);")
16698 ; Promote the QImode tests, as i386 has encoding of the AND
16699 ; instruction with 32-bit sign-extended immediate and thus the
16700 ; instruction size is unchanged, except in the %eax case for
16701 ; which it is increased by one byte, hence the ! optimize_size.
16703 [(set (match_operand 0 "flags_reg_operand" "")
16704 (match_operator 2 "compare_operator"
16705 [(and (match_operand 3 "aligned_operand" "")
16706 (match_operand 4 "const_int_operand" ""))
16708 (set (match_operand 1 "register_operand" "")
16709 (and (match_dup 3) (match_dup 4)))]
16710 "! TARGET_PARTIAL_REG_STALL && reload_completed
16711 && optimize_insn_for_speed_p ()
16712 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16713 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16714 /* Ensure that the operand will remain sign-extended immediate. */
16715 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16716 [(parallel [(set (match_dup 0)
16717 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16720 (and:SI (match_dup 3) (match_dup 4)))])]
16723 = gen_int_mode (INTVAL (operands[4])
16724 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16725 operands[1] = gen_lowpart (SImode, operands[1]);
16726 operands[3] = gen_lowpart (SImode, operands[3]);
16729 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16730 ; the TEST instruction with 32-bit sign-extended immediate and thus
16731 ; the instruction size would at least double, which is not what we
16732 ; want even with ! optimize_size.
16734 [(set (match_operand 0 "flags_reg_operand" "")
16735 (match_operator 1 "compare_operator"
16736 [(and (match_operand:HI 2 "aligned_operand" "")
16737 (match_operand:HI 3 "const_int_operand" ""))
16739 "! TARGET_PARTIAL_REG_STALL && reload_completed
16740 && ! TARGET_FAST_PREFIX
16741 && optimize_insn_for_speed_p ()
16742 /* Ensure that the operand will remain sign-extended immediate. */
16743 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16744 [(set (match_dup 0)
16745 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16749 = gen_int_mode (INTVAL (operands[3])
16750 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16751 operands[2] = gen_lowpart (SImode, operands[2]);
16755 [(set (match_operand 0 "register_operand" "")
16756 (neg (match_operand 1 "register_operand" "")))
16757 (clobber (reg:CC FLAGS_REG))]
16758 "! TARGET_PARTIAL_REG_STALL && reload_completed
16759 && (GET_MODE (operands[0]) == HImode
16760 || (GET_MODE (operands[0]) == QImode
16761 && (TARGET_PROMOTE_QImode
16762 || optimize_insn_for_size_p ())))"
16763 [(parallel [(set (match_dup 0)
16764 (neg:SI (match_dup 1)))
16765 (clobber (reg:CC FLAGS_REG))])]
16766 "operands[0] = gen_lowpart (SImode, operands[0]);
16767 operands[1] = gen_lowpart (SImode, operands[1]);")
16770 [(set (match_operand 0 "register_operand" "")
16771 (not (match_operand 1 "register_operand" "")))]
16772 "! TARGET_PARTIAL_REG_STALL && reload_completed
16773 && (GET_MODE (operands[0]) == HImode
16774 || (GET_MODE (operands[0]) == QImode
16775 && (TARGET_PROMOTE_QImode
16776 || optimize_insn_for_size_p ())))"
16777 [(set (match_dup 0)
16778 (not:SI (match_dup 1)))]
16779 "operands[0] = gen_lowpart (SImode, operands[0]);
16780 operands[1] = gen_lowpart (SImode, operands[1]);")
16783 [(set (match_operand 0 "register_operand" "")
16784 (if_then_else (match_operator 1 "ordered_comparison_operator"
16785 [(reg FLAGS_REG) (const_int 0)])
16786 (match_operand 2 "register_operand" "")
16787 (match_operand 3 "register_operand" "")))]
16788 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16789 && (GET_MODE (operands[0]) == HImode
16790 || (GET_MODE (operands[0]) == QImode
16791 && (TARGET_PROMOTE_QImode
16792 || optimize_insn_for_size_p ())))"
16793 [(set (match_dup 0)
16794 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16795 "operands[0] = gen_lowpart (SImode, operands[0]);
16796 operands[2] = gen_lowpart (SImode, operands[2]);
16797 operands[3] = gen_lowpart (SImode, operands[3]);")
16799 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16800 ;; transform a complex memory operation into two memory to register operations.
16802 ;; Don't push memory operands
16804 [(set (match_operand:SWI 0 "push_operand" "")
16805 (match_operand:SWI 1 "memory_operand" ""))
16806 (match_scratch:SWI 2 "<r>")]
16807 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16808 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16809 [(set (match_dup 2) (match_dup 1))
16810 (set (match_dup 0) (match_dup 2))])
16812 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16815 [(set (match_operand:SF 0 "push_operand" "")
16816 (match_operand:SF 1 "memory_operand" ""))
16817 (match_scratch:SF 2 "r")]
16818 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16819 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16820 [(set (match_dup 2) (match_dup 1))
16821 (set (match_dup 0) (match_dup 2))])
16823 ;; Don't move an immediate directly to memory when the instruction
16826 [(match_scratch:SWI124 1 "<r>")
16827 (set (match_operand:SWI124 0 "memory_operand" "")
16829 "optimize_insn_for_speed_p ()
16830 && !TARGET_USE_MOV0
16831 && TARGET_SPLIT_LONG_MOVES
16832 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16833 && peep2_regno_dead_p (0, FLAGS_REG)"
16834 [(parallel [(set (match_dup 2) (const_int 0))
16835 (clobber (reg:CC FLAGS_REG))])
16836 (set (match_dup 0) (match_dup 1))]
16837 "operands[2] = gen_lowpart (SImode, operands[1]);")
16840 [(match_scratch:SWI124 2 "<r>")
16841 (set (match_operand:SWI124 0 "memory_operand" "")
16842 (match_operand:SWI124 1 "immediate_operand" ""))]
16843 "optimize_insn_for_speed_p ()
16844 && TARGET_SPLIT_LONG_MOVES
16845 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16846 [(set (match_dup 2) (match_dup 1))
16847 (set (match_dup 0) (match_dup 2))])
16849 ;; Don't compare memory with zero, load and use a test instead.
16851 [(set (match_operand 0 "flags_reg_operand" "")
16852 (match_operator 1 "compare_operator"
16853 [(match_operand:SI 2 "memory_operand" "")
16855 (match_scratch:SI 3 "r")]
16856 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16857 [(set (match_dup 3) (match_dup 2))
16858 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16860 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16861 ;; Don't split NOTs with a displacement operand, because resulting XOR
16862 ;; will not be pairable anyway.
16864 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16865 ;; represented using a modRM byte. The XOR replacement is long decoded,
16866 ;; so this split helps here as well.
16868 ;; Note: Can't do this as a regular split because we can't get proper
16869 ;; lifetime information then.
16872 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16873 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16874 "optimize_insn_for_speed_p ()
16875 && ((TARGET_NOT_UNPAIRABLE
16876 && (!MEM_P (operands[0])
16877 || !memory_displacement_operand (operands[0], <MODE>mode)))
16878 || (TARGET_NOT_VECTORMODE
16879 && long_memory_operand (operands[0], <MODE>mode)))
16880 && peep2_regno_dead_p (0, FLAGS_REG)"
16881 [(parallel [(set (match_dup 0)
16882 (xor:SWI124 (match_dup 1) (const_int -1)))
16883 (clobber (reg:CC FLAGS_REG))])])
16885 ;; Non pairable "test imm, reg" instructions can be translated to
16886 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16887 ;; byte opcode instead of two, have a short form for byte operands),
16888 ;; so do it for other CPUs as well. Given that the value was dead,
16889 ;; this should not create any new dependencies. Pass on the sub-word
16890 ;; versions if we're concerned about partial register stalls.
16893 [(set (match_operand 0 "flags_reg_operand" "")
16894 (match_operator 1 "compare_operator"
16895 [(and:SI (match_operand:SI 2 "register_operand" "")
16896 (match_operand:SI 3 "immediate_operand" ""))
16898 "ix86_match_ccmode (insn, CCNOmode)
16899 && (true_regnum (operands[2]) != AX_REG
16900 || satisfies_constraint_K (operands[3]))
16901 && peep2_reg_dead_p (1, operands[2])"
16903 [(set (match_dup 0)
16904 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16907 (and:SI (match_dup 2) (match_dup 3)))])])
16909 ;; We don't need to handle HImode case, because it will be promoted to SImode
16910 ;; on ! TARGET_PARTIAL_REG_STALL
16913 [(set (match_operand 0 "flags_reg_operand" "")
16914 (match_operator 1 "compare_operator"
16915 [(and:QI (match_operand:QI 2 "register_operand" "")
16916 (match_operand:QI 3 "immediate_operand" ""))
16918 "! TARGET_PARTIAL_REG_STALL
16919 && ix86_match_ccmode (insn, CCNOmode)
16920 && true_regnum (operands[2]) != AX_REG
16921 && peep2_reg_dead_p (1, operands[2])"
16923 [(set (match_dup 0)
16924 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16927 (and:QI (match_dup 2) (match_dup 3)))])])
16930 [(set (match_operand 0 "flags_reg_operand" "")
16931 (match_operator 1 "compare_operator"
16934 (match_operand 2 "ext_register_operand" "")
16937 (match_operand 3 "const_int_operand" ""))
16939 "! TARGET_PARTIAL_REG_STALL
16940 && ix86_match_ccmode (insn, CCNOmode)
16941 && true_regnum (operands[2]) != AX_REG
16942 && peep2_reg_dead_p (1, operands[2])"
16943 [(parallel [(set (match_dup 0)
16952 (set (zero_extract:SI (match_dup 2)
16960 (match_dup 3)))])])
16962 ;; Don't do logical operations with memory inputs.
16964 [(match_scratch:SI 2 "r")
16965 (parallel [(set (match_operand:SI 0 "register_operand" "")
16966 (match_operator:SI 3 "arith_or_logical_operator"
16968 (match_operand:SI 1 "memory_operand" "")]))
16969 (clobber (reg:CC FLAGS_REG))])]
16970 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16971 [(set (match_dup 2) (match_dup 1))
16972 (parallel [(set (match_dup 0)
16973 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16974 (clobber (reg:CC FLAGS_REG))])])
16977 [(match_scratch:SI 2 "r")
16978 (parallel [(set (match_operand:SI 0 "register_operand" "")
16979 (match_operator:SI 3 "arith_or_logical_operator"
16980 [(match_operand:SI 1 "memory_operand" "")
16982 (clobber (reg:CC FLAGS_REG))])]
16983 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16984 [(set (match_dup 2) (match_dup 1))
16985 (parallel [(set (match_dup 0)
16986 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16987 (clobber (reg:CC FLAGS_REG))])])
16989 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16990 ;; refers to the destination of the load!
16993 [(set (match_operand:SI 0 "register_operand" "")
16994 (match_operand:SI 1 "register_operand" ""))
16995 (parallel [(set (match_dup 0)
16996 (match_operator:SI 3 "commutative_operator"
16998 (match_operand:SI 2 "memory_operand" "")]))
16999 (clobber (reg:CC FLAGS_REG))])]
17000 "REGNO (operands[0]) != REGNO (operands[1])
17001 && GENERAL_REGNO_P (REGNO (operands[0]))
17002 && GENERAL_REGNO_P (REGNO (operands[1]))"
17003 [(set (match_dup 0) (match_dup 4))
17004 (parallel [(set (match_dup 0)
17005 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17006 (clobber (reg:CC FLAGS_REG))])]
17007 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17010 [(set (match_operand 0 "register_operand" "")
17011 (match_operand 1 "register_operand" ""))
17013 (match_operator 3 "commutative_operator"
17015 (match_operand 2 "memory_operand" "")]))]
17016 "REGNO (operands[0]) != REGNO (operands[1])
17017 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17018 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17019 [(set (match_dup 0) (match_dup 2))
17021 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17023 ; Don't do logical operations with memory outputs
17025 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17026 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17027 ; the same decoder scheduling characteristics as the original.
17030 [(match_scratch:SI 2 "r")
17031 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17032 (match_operator:SI 3 "arith_or_logical_operator"
17034 (match_operand:SI 1 "nonmemory_operand" "")]))
17035 (clobber (reg:CC FLAGS_REG))])]
17036 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17037 /* Do not split stack checking probes. */
17038 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17039 [(set (match_dup 2) (match_dup 0))
17040 (parallel [(set (match_dup 2)
17041 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17042 (clobber (reg:CC FLAGS_REG))])
17043 (set (match_dup 0) (match_dup 2))])
17046 [(match_scratch:SI 2 "r")
17047 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17048 (match_operator:SI 3 "arith_or_logical_operator"
17049 [(match_operand:SI 1 "nonmemory_operand" "")
17051 (clobber (reg:CC FLAGS_REG))])]
17052 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17053 /* Do not split stack checking probes. */
17054 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17055 [(set (match_dup 2) (match_dup 0))
17056 (parallel [(set (match_dup 2)
17057 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17058 (clobber (reg:CC FLAGS_REG))])
17059 (set (match_dup 0) (match_dup 2))])
17061 ;; Attempt to always use XOR for zeroing registers.
17063 [(set (match_operand 0 "register_operand" "")
17064 (match_operand 1 "const0_operand" ""))]
17065 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17066 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17067 && GENERAL_REG_P (operands[0])
17068 && peep2_regno_dead_p (0, FLAGS_REG)"
17069 [(parallel [(set (match_dup 0) (const_int 0))
17070 (clobber (reg:CC FLAGS_REG))])]
17071 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17074 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17076 "(GET_MODE (operands[0]) == QImode
17077 || GET_MODE (operands[0]) == HImode)
17078 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17079 && peep2_regno_dead_p (0, FLAGS_REG)"
17080 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17081 (clobber (reg:CC FLAGS_REG))])])
17083 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17085 [(set (match_operand:SWI248 0 "register_operand" "")
17087 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17088 && peep2_regno_dead_p (0, FLAGS_REG)"
17089 [(parallel [(set (match_dup 0) (const_int -1))
17090 (clobber (reg:CC FLAGS_REG))])]
17092 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17093 operands[0] = gen_lowpart (SImode, operands[0]);
17096 ;; Attempt to convert simple lea to add/shift.
17097 ;; These can be created by move expanders.
17100 [(set (match_operand:SWI48 0 "register_operand" "")
17101 (plus:SWI48 (match_dup 0)
17102 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17103 "peep2_regno_dead_p (0, FLAGS_REG)"
17104 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17105 (clobber (reg:CC FLAGS_REG))])])
17108 [(set (match_operand:SI 0 "register_operand" "")
17109 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17110 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17112 && peep2_regno_dead_p (0, FLAGS_REG)
17113 && REGNO (operands[0]) == REGNO (operands[1])"
17114 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17115 (clobber (reg:CC FLAGS_REG))])]
17116 "operands[2] = gen_lowpart (SImode, operands[2]);")
17119 [(set (match_operand:SWI48 0 "register_operand" "")
17120 (mult:SWI48 (match_dup 0)
17121 (match_operand:SWI48 1 "const_int_operand" "")))]
17122 "exact_log2 (INTVAL (operands[1])) >= 0
17123 && peep2_regno_dead_p (0, FLAGS_REG)"
17124 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17125 (clobber (reg:CC FLAGS_REG))])]
17126 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17129 [(set (match_operand:SI 0 "register_operand" "")
17130 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17131 (match_operand:DI 2 "const_int_operand" "")) 0))]
17133 && exact_log2 (INTVAL (operands[2])) >= 0
17134 && REGNO (operands[0]) == REGNO (operands[1])
17135 && peep2_regno_dead_p (0, FLAGS_REG)"
17136 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17137 (clobber (reg:CC FLAGS_REG))])]
17138 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17140 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17141 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17142 ;; On many CPUs it is also faster, since special hardware to avoid esp
17143 ;; dependencies is present.
17145 ;; While some of these conversions may be done using splitters, we use
17146 ;; peepholes in order to allow combine_stack_adjustments pass to see
17147 ;; nonobfuscated RTL.
17149 ;; Convert prologue esp subtractions to push.
17150 ;; We need register to push. In order to keep verify_flow_info happy we have
17152 ;; - use scratch and clobber it in order to avoid dependencies
17153 ;; - use already live register
17154 ;; We can't use the second way right now, since there is no reliable way how to
17155 ;; verify that given register is live. First choice will also most likely in
17156 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17157 ;; call clobbered registers are dead. We may want to use base pointer as an
17158 ;; alternative when no register is available later.
17161 [(match_scratch:P 1 "r")
17162 (parallel [(set (reg:P SP_REG)
17163 (plus:P (reg:P SP_REG)
17164 (match_operand:P 0 "const_int_operand" "")))
17165 (clobber (reg:CC FLAGS_REG))
17166 (clobber (mem:BLK (scratch)))])]
17167 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17168 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17169 [(clobber (match_dup 1))
17170 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17171 (clobber (mem:BLK (scratch)))])])
17174 [(match_scratch:P 1 "r")
17175 (parallel [(set (reg:P SP_REG)
17176 (plus:P (reg:P SP_REG)
17177 (match_operand:P 0 "const_int_operand" "")))
17178 (clobber (reg:CC FLAGS_REG))
17179 (clobber (mem:BLK (scratch)))])]
17180 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17181 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17182 [(clobber (match_dup 1))
17183 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17184 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17185 (clobber (mem:BLK (scratch)))])])
17187 ;; Convert esp subtractions to push.
17189 [(match_scratch:P 1 "r")
17190 (parallel [(set (reg:P SP_REG)
17191 (plus:P (reg:P SP_REG)
17192 (match_operand:P 0 "const_int_operand" "")))
17193 (clobber (reg:CC FLAGS_REG))])]
17194 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17195 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17196 [(clobber (match_dup 1))
17197 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17200 [(match_scratch:P 1 "r")
17201 (parallel [(set (reg:P SP_REG)
17202 (plus:P (reg:P SP_REG)
17203 (match_operand:P 0 "const_int_operand" "")))
17204 (clobber (reg:CC FLAGS_REG))])]
17205 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17206 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17207 [(clobber (match_dup 1))
17208 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17209 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17211 ;; Convert epilogue deallocator to pop.
17213 [(match_scratch:P 1 "r")
17214 (parallel [(set (reg:P SP_REG)
17215 (plus:P (reg:P SP_REG)
17216 (match_operand:P 0 "const_int_operand" "")))
17217 (clobber (reg:CC FLAGS_REG))
17218 (clobber (mem:BLK (scratch)))])]
17219 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17220 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17221 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17222 (clobber (mem:BLK (scratch)))])])
17224 ;; Two pops case is tricky, since pop causes dependency
17225 ;; on destination register. We use two registers if available.
17227 [(match_scratch:P 1 "r")
17228 (match_scratch:P 2 "r")
17229 (parallel [(set (reg:P SP_REG)
17230 (plus:P (reg:P SP_REG)
17231 (match_operand:P 0 "const_int_operand" "")))
17232 (clobber (reg:CC FLAGS_REG))
17233 (clobber (mem:BLK (scratch)))])]
17234 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17235 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17236 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17237 (clobber (mem:BLK (scratch)))])
17238 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17241 [(match_scratch:P 1 "r")
17242 (parallel [(set (reg:P SP_REG)
17243 (plus:P (reg:P SP_REG)
17244 (match_operand:P 0 "const_int_operand" "")))
17245 (clobber (reg:CC FLAGS_REG))
17246 (clobber (mem:BLK (scratch)))])]
17247 "optimize_insn_for_size_p ()
17248 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17249 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17250 (clobber (mem:BLK (scratch)))])
17251 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17253 ;; Convert esp additions to pop.
17255 [(match_scratch:P 1 "r")
17256 (parallel [(set (reg:P SP_REG)
17257 (plus:P (reg:P SP_REG)
17258 (match_operand:P 0 "const_int_operand" "")))
17259 (clobber (reg:CC FLAGS_REG))])]
17260 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17261 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17263 ;; Two pops case is tricky, since pop causes dependency
17264 ;; on destination register. We use two registers if available.
17266 [(match_scratch:P 1 "r")
17267 (match_scratch:P 2 "r")
17268 (parallel [(set (reg:P SP_REG)
17269 (plus:P (reg:P SP_REG)
17270 (match_operand:P 0 "const_int_operand" "")))
17271 (clobber (reg:CC FLAGS_REG))])]
17272 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17273 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17274 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17277 [(match_scratch:P 1 "r")
17278 (parallel [(set (reg:P SP_REG)
17279 (plus:P (reg:P SP_REG)
17280 (match_operand:P 0 "const_int_operand" "")))
17281 (clobber (reg:CC FLAGS_REG))])]
17282 "optimize_insn_for_size_p ()
17283 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17284 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17285 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17287 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17288 ;; required and register dies. Similarly for 128 to -128.
17290 [(set (match_operand 0 "flags_reg_operand" "")
17291 (match_operator 1 "compare_operator"
17292 [(match_operand 2 "register_operand" "")
17293 (match_operand 3 "const_int_operand" "")]))]
17294 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17295 && incdec_operand (operands[3], GET_MODE (operands[3])))
17296 || (!TARGET_FUSE_CMP_AND_BRANCH
17297 && INTVAL (operands[3]) == 128))
17298 && ix86_match_ccmode (insn, CCGCmode)
17299 && peep2_reg_dead_p (1, operands[2])"
17300 [(parallel [(set (match_dup 0)
17301 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17302 (clobber (match_dup 2))])])
17304 ;; Convert imul by three, five and nine into lea
17307 [(set (match_operand:SWI48 0 "register_operand" "")
17308 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17309 (match_operand:SWI48 2 "const_int_operand" "")))
17310 (clobber (reg:CC FLAGS_REG))])]
17311 "INTVAL (operands[2]) == 3
17312 || INTVAL (operands[2]) == 5
17313 || INTVAL (operands[2]) == 9"
17314 [(set (match_dup 0)
17315 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17317 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17321 [(set (match_operand:SWI48 0 "register_operand" "")
17322 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17323 (match_operand:SWI48 2 "const_int_operand" "")))
17324 (clobber (reg:CC FLAGS_REG))])]
17325 "optimize_insn_for_speed_p ()
17326 && (INTVAL (operands[2]) == 3
17327 || INTVAL (operands[2]) == 5
17328 || INTVAL (operands[2]) == 9)"
17329 [(set (match_dup 0) (match_dup 1))
17331 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17333 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17335 ;; imul $32bit_imm, mem, reg is vector decoded, while
17336 ;; imul $32bit_imm, reg, reg is direct decoded.
17338 [(match_scratch:SWI48 3 "r")
17339 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17340 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17341 (match_operand:SWI48 2 "immediate_operand" "")))
17342 (clobber (reg:CC FLAGS_REG))])]
17343 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17344 && !satisfies_constraint_K (operands[2])"
17345 [(set (match_dup 3) (match_dup 1))
17346 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17347 (clobber (reg:CC FLAGS_REG))])])
17350 [(match_scratch:SI 3 "r")
17351 (parallel [(set (match_operand:DI 0 "register_operand" "")
17353 (mult:SI (match_operand:SI 1 "memory_operand" "")
17354 (match_operand:SI 2 "immediate_operand" ""))))
17355 (clobber (reg:CC FLAGS_REG))])]
17357 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17358 && !satisfies_constraint_K (operands[2])"
17359 [(set (match_dup 3) (match_dup 1))
17360 (parallel [(set (match_dup 0)
17361 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17362 (clobber (reg:CC FLAGS_REG))])])
17364 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17365 ;; Convert it into imul reg, reg
17366 ;; It would be better to force assembler to encode instruction using long
17367 ;; immediate, but there is apparently no way to do so.
17369 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17371 (match_operand:SWI248 1 "nonimmediate_operand" "")
17372 (match_operand:SWI248 2 "const_int_operand" "")))
17373 (clobber (reg:CC FLAGS_REG))])
17374 (match_scratch:SWI248 3 "r")]
17375 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17376 && satisfies_constraint_K (operands[2])"
17377 [(set (match_dup 3) (match_dup 2))
17378 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17379 (clobber (reg:CC FLAGS_REG))])]
17381 if (!rtx_equal_p (operands[0], operands[1]))
17382 emit_move_insn (operands[0], operands[1]);
17385 ;; After splitting up read-modify operations, array accesses with memory
17386 ;; operands might end up in form:
17388 ;; movl 4(%esp), %edx
17390 ;; instead of pre-splitting:
17392 ;; addl 4(%esp), %eax
17394 ;; movl 4(%esp), %edx
17395 ;; leal (%edx,%eax,4), %eax
17398 [(match_scratch:P 5 "r")
17399 (parallel [(set (match_operand 0 "register_operand" "")
17400 (ashift (match_operand 1 "register_operand" "")
17401 (match_operand 2 "const_int_operand" "")))
17402 (clobber (reg:CC FLAGS_REG))])
17403 (parallel [(set (match_operand 3 "register_operand" "")
17404 (plus (match_dup 0)
17405 (match_operand 4 "x86_64_general_operand" "")))
17406 (clobber (reg:CC FLAGS_REG))])]
17407 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17408 /* Validate MODE for lea. */
17409 && ((!TARGET_PARTIAL_REG_STALL
17410 && (GET_MODE (operands[0]) == QImode
17411 || GET_MODE (operands[0]) == HImode))
17412 || GET_MODE (operands[0]) == SImode
17413 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17414 && (rtx_equal_p (operands[0], operands[3])
17415 || peep2_reg_dead_p (2, operands[0]))
17416 /* We reorder load and the shift. */
17417 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17418 [(set (match_dup 5) (match_dup 4))
17419 (set (match_dup 0) (match_dup 1))]
17421 enum machine_mode op1mode = GET_MODE (operands[1]);
17422 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17423 int scale = 1 << INTVAL (operands[2]);
17424 rtx index = gen_lowpart (Pmode, operands[1]);
17425 rtx base = gen_lowpart (Pmode, operands[5]);
17426 rtx dest = gen_lowpart (mode, operands[3]);
17428 operands[1] = gen_rtx_PLUS (Pmode, base,
17429 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17430 operands[5] = base;
17432 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17433 if (op1mode != Pmode)
17434 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17435 operands[0] = dest;
17438 ;; Call-value patterns last so that the wildcard operand does not
17439 ;; disrupt insn-recog's switch tables.
17441 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17443 [(set (match_operand 0 "" "")
17444 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17445 (match_operand:SI 2 "" "")))
17446 (set (reg:SI SP_REG)
17447 (plus:SI (reg:SI SP_REG)
17448 (match_operand:SI 3 "immediate_operand" "")))])
17449 (unspec [(match_operand 4 "const_int_operand" "")]
17450 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17451 "TARGET_VZEROUPPER && !TARGET_64BIT"
17453 "&& reload_completed"
17455 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17456 [(set_attr "type" "callv")])
17458 (define_insn "*call_value_pop_0"
17459 [(set (match_operand 0 "" "")
17460 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17461 (match_operand:SI 2 "" "")))
17462 (set (reg:SI SP_REG)
17463 (plus:SI (reg:SI SP_REG)
17464 (match_operand:SI 3 "immediate_operand" "")))]
17466 { return ix86_output_call_insn (insn, operands[1], 1); }
17467 [(set_attr "type" "callv")])
17469 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17471 [(set (match_operand 0 "" "")
17472 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17473 (match_operand:SI 2 "" "")))
17474 (set (reg:SI SP_REG)
17475 (plus:SI (reg:SI SP_REG)
17476 (match_operand:SI 3 "immediate_operand" "i")))])
17477 (unspec [(match_operand 4 "const_int_operand" "")]
17478 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17479 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17481 "&& reload_completed"
17483 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17484 [(set_attr "type" "callv")])
17486 (define_insn "*call_value_pop_1"
17487 [(set (match_operand 0 "" "")
17488 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17489 (match_operand:SI 2 "" "")))
17490 (set (reg:SI SP_REG)
17491 (plus:SI (reg:SI SP_REG)
17492 (match_operand:SI 3 "immediate_operand" "i")))]
17493 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17494 { return ix86_output_call_insn (insn, operands[1], 1); }
17495 [(set_attr "type" "callv")])
17497 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17499 [(set (match_operand 0 "" "")
17500 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17501 (match_operand:SI 2 "" "")))
17502 (set (reg:SI SP_REG)
17503 (plus:SI (reg:SI SP_REG)
17504 (match_operand:SI 3 "immediate_operand" "i,i")))])
17505 (unspec [(match_operand 4 "const_int_operand" "")]
17506 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17507 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17509 "&& reload_completed"
17511 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17512 [(set_attr "type" "callv")])
17514 (define_insn "*sibcall_value_pop_1"
17515 [(set (match_operand 0 "" "")
17516 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17517 (match_operand:SI 2 "" "")))
17518 (set (reg:SI SP_REG)
17519 (plus:SI (reg:SI SP_REG)
17520 (match_operand:SI 3 "immediate_operand" "i,i")))]
17521 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17522 { return ix86_output_call_insn (insn, operands[1], 1); }
17523 [(set_attr "type" "callv")])
17525 (define_insn_and_split "*call_value_0_vzeroupper"
17526 [(set (match_operand 0 "" "")
17527 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17528 (match_operand:SI 2 "" "")))
17529 (unspec [(match_operand 3 "const_int_operand" "")]
17530 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17531 "TARGET_VZEROUPPER && !TARGET_64BIT"
17533 "&& reload_completed"
17535 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17536 [(set_attr "type" "callv")])
17538 (define_insn "*call_value_0"
17539 [(set (match_operand 0 "" "")
17540 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17541 (match_operand:SI 2 "" "")))]
17543 { return ix86_output_call_insn (insn, operands[1], 1); }
17544 [(set_attr "type" "callv")])
17546 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17547 [(set (match_operand 0 "" "")
17548 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17549 (match_operand:DI 2 "const_int_operand" "")))
17550 (unspec [(match_operand 3 "const_int_operand" "")]
17551 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17552 "TARGET_VZEROUPPER && TARGET_64BIT"
17554 "&& reload_completed"
17556 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17557 [(set_attr "type" "callv")])
17559 (define_insn "*call_value_0_rex64"
17560 [(set (match_operand 0 "" "")
17561 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17562 (match_operand:DI 2 "const_int_operand" "")))]
17564 { return ix86_output_call_insn (insn, operands[1], 1); }
17565 [(set_attr "type" "callv")])
17567 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17569 [(set (match_operand 0 "" "")
17570 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17571 (match_operand:DI 2 "const_int_operand" "")))
17572 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17573 (clobber (reg:TI XMM6_REG))
17574 (clobber (reg:TI XMM7_REG))
17575 (clobber (reg:TI XMM8_REG))
17576 (clobber (reg:TI XMM9_REG))
17577 (clobber (reg:TI XMM10_REG))
17578 (clobber (reg:TI XMM11_REG))
17579 (clobber (reg:TI XMM12_REG))
17580 (clobber (reg:TI XMM13_REG))
17581 (clobber (reg:TI XMM14_REG))
17582 (clobber (reg:TI XMM15_REG))
17583 (clobber (reg:DI SI_REG))
17584 (clobber (reg:DI DI_REG))])
17585 (unspec [(match_operand 3 "const_int_operand" "")]
17586 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17587 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17589 "&& reload_completed"
17591 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17592 [(set_attr "type" "callv")])
17594 (define_insn "*call_value_0_rex64_ms_sysv"
17595 [(set (match_operand 0 "" "")
17596 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17597 (match_operand:DI 2 "const_int_operand" "")))
17598 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17599 (clobber (reg:TI XMM6_REG))
17600 (clobber (reg:TI XMM7_REG))
17601 (clobber (reg:TI XMM8_REG))
17602 (clobber (reg:TI XMM9_REG))
17603 (clobber (reg:TI XMM10_REG))
17604 (clobber (reg:TI XMM11_REG))
17605 (clobber (reg:TI XMM12_REG))
17606 (clobber (reg:TI XMM13_REG))
17607 (clobber (reg:TI XMM14_REG))
17608 (clobber (reg:TI XMM15_REG))
17609 (clobber (reg:DI SI_REG))
17610 (clobber (reg:DI DI_REG))]
17611 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17612 { return ix86_output_call_insn (insn, operands[1], 1); }
17613 [(set_attr "type" "callv")])
17615 (define_insn_and_split "*call_value_1_vzeroupper"
17616 [(set (match_operand 0 "" "")
17617 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17618 (match_operand:SI 2 "" "")))
17619 (unspec [(match_operand 3 "const_int_operand" "")]
17620 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17621 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17623 "&& reload_completed"
17625 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17626 [(set_attr "type" "callv")])
17628 (define_insn "*call_value_1"
17629 [(set (match_operand 0 "" "")
17630 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17631 (match_operand:SI 2 "" "")))]
17632 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17633 { return ix86_output_call_insn (insn, operands[1], 1); }
17634 [(set_attr "type" "callv")])
17636 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17637 [(set (match_operand 0 "" "")
17638 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17639 (match_operand:SI 2 "" "")))
17640 (unspec [(match_operand 3 "const_int_operand" "")]
17641 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17642 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17644 "&& reload_completed"
17646 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17647 [(set_attr "type" "callv")])
17649 (define_insn "*sibcall_value_1"
17650 [(set (match_operand 0 "" "")
17651 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17652 (match_operand:SI 2 "" "")))]
17653 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17654 { return ix86_output_call_insn (insn, operands[1], 1); }
17655 [(set_attr "type" "callv")])
17657 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17658 [(set (match_operand 0 "" "")
17659 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17660 (match_operand:DI 2 "" "")))
17661 (unspec [(match_operand 3 "const_int_operand" "")]
17662 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17663 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17664 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17666 "&& reload_completed"
17668 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17669 [(set_attr "type" "callv")])
17671 (define_insn "*call_value_1_rex64"
17672 [(set (match_operand 0 "" "")
17673 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17674 (match_operand:DI 2 "" "")))]
17675 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17676 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17677 { return ix86_output_call_insn (insn, operands[1], 1); }
17678 [(set_attr "type" "callv")])
17680 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17682 [(set (match_operand 0 "" "")
17683 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17684 (match_operand:DI 2 "" "")))
17685 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17686 (clobber (reg:TI XMM6_REG))
17687 (clobber (reg:TI XMM7_REG))
17688 (clobber (reg:TI XMM8_REG))
17689 (clobber (reg:TI XMM9_REG))
17690 (clobber (reg:TI XMM10_REG))
17691 (clobber (reg:TI XMM11_REG))
17692 (clobber (reg:TI XMM12_REG))
17693 (clobber (reg:TI XMM13_REG))
17694 (clobber (reg:TI XMM14_REG))
17695 (clobber (reg:TI XMM15_REG))
17696 (clobber (reg:DI SI_REG))
17697 (clobber (reg:DI DI_REG))])
17698 (unspec [(match_operand 3 "const_int_operand" "")]
17699 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17700 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17702 "&& reload_completed"
17704 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17705 [(set_attr "type" "callv")])
17707 (define_insn "*call_value_1_rex64_ms_sysv"
17708 [(set (match_operand 0 "" "")
17709 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17710 (match_operand:DI 2 "" "")))
17711 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17712 (clobber (reg:TI XMM6_REG))
17713 (clobber (reg:TI XMM7_REG))
17714 (clobber (reg:TI XMM8_REG))
17715 (clobber (reg:TI XMM9_REG))
17716 (clobber (reg:TI XMM10_REG))
17717 (clobber (reg:TI XMM11_REG))
17718 (clobber (reg:TI XMM12_REG))
17719 (clobber (reg:TI XMM13_REG))
17720 (clobber (reg:TI XMM14_REG))
17721 (clobber (reg:TI XMM15_REG))
17722 (clobber (reg:DI SI_REG))
17723 (clobber (reg:DI DI_REG))]
17724 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17725 { return ix86_output_call_insn (insn, operands[1], 1); }
17726 [(set_attr "type" "callv")])
17728 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17729 [(set (match_operand 0 "" "")
17730 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17731 (match_operand:DI 2 "" "")))
17732 (unspec [(match_operand 3 "const_int_operand" "")]
17733 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17734 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17736 "&& reload_completed"
17738 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17739 [(set_attr "type" "callv")])
17741 (define_insn "*call_value_1_rex64_large"
17742 [(set (match_operand 0 "" "")
17743 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17744 (match_operand:DI 2 "" "")))]
17745 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17746 { return ix86_output_call_insn (insn, operands[1], 1); }
17747 [(set_attr "type" "callv")])
17749 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17750 [(set (match_operand 0 "" "")
17751 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17752 (match_operand:DI 2 "" "")))
17753 (unspec [(match_operand 3 "const_int_operand" "")]
17754 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17755 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17757 "&& reload_completed"
17759 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17760 [(set_attr "type" "callv")])
17762 (define_insn "*sibcall_value_1_rex64"
17763 [(set (match_operand 0 "" "")
17764 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17765 (match_operand:DI 2 "" "")))]
17766 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17767 { return ix86_output_call_insn (insn, operands[1], 1); }
17768 [(set_attr "type" "callv")])
17770 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17771 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17772 ;; caught for use by garbage collectors and the like. Using an insn that
17773 ;; maps to SIGILL makes it more likely the program will rightfully die.
17774 ;; Keeping with tradition, "6" is in honor of #UD.
17775 (define_insn "trap"
17776 [(trap_if (const_int 1) (const_int 6))]
17778 { return ASM_SHORT "0x0b0f"; }
17779 [(set_attr "length" "2")])
17781 (define_expand "prefetch"
17782 [(prefetch (match_operand 0 "address_operand" "")
17783 (match_operand:SI 1 "const_int_operand" "")
17784 (match_operand:SI 2 "const_int_operand" ""))]
17785 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17787 int rw = INTVAL (operands[1]);
17788 int locality = INTVAL (operands[2]);
17790 gcc_assert (rw == 0 || rw == 1);
17791 gcc_assert (locality >= 0 && locality <= 3);
17792 gcc_assert (GET_MODE (operands[0]) == Pmode
17793 || GET_MODE (operands[0]) == VOIDmode);
17795 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17796 supported by SSE counterpart or the SSE prefetch is not available
17797 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17799 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17800 operands[2] = GEN_INT (3);
17802 operands[1] = const0_rtx;
17805 (define_insn "*prefetch_sse_<mode>"
17806 [(prefetch (match_operand:P 0 "address_operand" "p")
17808 (match_operand:SI 1 "const_int_operand" ""))]
17809 "TARGET_PREFETCH_SSE"
17811 static const char * const patterns[4] = {
17812 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17815 int locality = INTVAL (operands[1]);
17816 gcc_assert (locality >= 0 && locality <= 3);
17818 return patterns[locality];
17820 [(set_attr "type" "sse")
17821 (set_attr "atom_sse_attr" "prefetch")
17822 (set (attr "length_address")
17823 (symbol_ref "memory_address_length (operands[0])"))
17824 (set_attr "memory" "none")])
17826 (define_insn "*prefetch_3dnow_<mode>"
17827 [(prefetch (match_operand:P 0 "address_operand" "p")
17828 (match_operand:SI 1 "const_int_operand" "n")
17832 if (INTVAL (operands[1]) == 0)
17833 return "prefetch\t%a0";
17835 return "prefetchw\t%a0";
17837 [(set_attr "type" "mmx")
17838 (set (attr "length_address")
17839 (symbol_ref "memory_address_length (operands[0])"))
17840 (set_attr "memory" "none")])
17842 (define_expand "stack_protect_set"
17843 [(match_operand 0 "memory_operand" "")
17844 (match_operand 1 "memory_operand" "")]
17847 rtx (*insn)(rtx, rtx);
17849 #ifdef TARGET_THREAD_SSP_OFFSET
17850 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17851 insn = (TARGET_64BIT
17852 ? gen_stack_tls_protect_set_di
17853 : gen_stack_tls_protect_set_si);
17855 insn = (TARGET_64BIT
17856 ? gen_stack_protect_set_di
17857 : gen_stack_protect_set_si);
17860 emit_insn (insn (operands[0], operands[1]));
17864 (define_insn "stack_protect_set_<mode>"
17865 [(set (match_operand:P 0 "memory_operand" "=m")
17866 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17867 (set (match_scratch:P 2 "=&r") (const_int 0))
17868 (clobber (reg:CC FLAGS_REG))]
17870 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17871 [(set_attr "type" "multi")])
17873 (define_insn "stack_tls_protect_set_<mode>"
17874 [(set (match_operand:P 0 "memory_operand" "=m")
17875 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17876 UNSPEC_SP_TLS_SET))
17877 (set (match_scratch:P 2 "=&r") (const_int 0))
17878 (clobber (reg:CC FLAGS_REG))]
17880 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17881 [(set_attr "type" "multi")])
17883 (define_expand "stack_protect_test"
17884 [(match_operand 0 "memory_operand" "")
17885 (match_operand 1 "memory_operand" "")
17886 (match_operand 2 "" "")]
17889 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17891 rtx (*insn)(rtx, rtx, rtx);
17893 #ifdef TARGET_THREAD_SSP_OFFSET
17894 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17895 insn = (TARGET_64BIT
17896 ? gen_stack_tls_protect_test_di
17897 : gen_stack_tls_protect_test_si);
17899 insn = (TARGET_64BIT
17900 ? gen_stack_protect_test_di
17901 : gen_stack_protect_test_si);
17904 emit_insn (insn (flags, operands[0], operands[1]));
17906 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17907 flags, const0_rtx, operands[2]));
17911 (define_insn "stack_protect_test_<mode>"
17912 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17913 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17914 (match_operand:P 2 "memory_operand" "m")]
17916 (clobber (match_scratch:P 3 "=&r"))]
17918 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17919 [(set_attr "type" "multi")])
17921 (define_insn "stack_tls_protect_test_<mode>"
17922 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17923 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17924 (match_operand:P 2 "const_int_operand" "i")]
17925 UNSPEC_SP_TLS_TEST))
17926 (clobber (match_scratch:P 3 "=r"))]
17928 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17929 [(set_attr "type" "multi")])
17931 (define_insn "sse4_2_crc32<mode>"
17932 [(set (match_operand:SI 0 "register_operand" "=r")
17934 [(match_operand:SI 1 "register_operand" "0")
17935 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17937 "TARGET_SSE4_2 || TARGET_CRC32"
17938 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17939 [(set_attr "type" "sselog1")
17940 (set_attr "prefix_rep" "1")
17941 (set_attr "prefix_extra" "1")
17942 (set (attr "prefix_data16")
17943 (if_then_else (match_operand:HI 2 "" "")
17945 (const_string "*")))
17946 (set (attr "prefix_rex")
17947 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17949 (const_string "*")))
17950 (set_attr "mode" "SI")])
17952 (define_insn "sse4_2_crc32di"
17953 [(set (match_operand:DI 0 "register_operand" "=r")
17955 [(match_operand:DI 1 "register_operand" "0")
17956 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17958 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17959 "crc32{q}\t{%2, %0|%0, %2}"
17960 [(set_attr "type" "sselog1")
17961 (set_attr "prefix_rep" "1")
17962 (set_attr "prefix_extra" "1")
17963 (set_attr "mode" "DI")])
17965 (define_expand "rdpmc"
17966 [(match_operand:DI 0 "register_operand" "")
17967 (match_operand:SI 1 "register_operand" "")]
17970 rtx reg = gen_reg_rtx (DImode);
17973 /* Force operand 1 into ECX. */
17974 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17975 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17976 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17981 rtvec vec = rtvec_alloc (2);
17982 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17983 rtx upper = gen_reg_rtx (DImode);
17984 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17985 gen_rtvec (1, const0_rtx),
17987 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17988 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17990 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17991 NULL, 1, OPTAB_DIRECT);
17992 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17996 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17997 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18001 (define_insn "*rdpmc"
18002 [(set (match_operand:DI 0 "register_operand" "=A")
18003 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18007 [(set_attr "type" "other")
18008 (set_attr "length" "2")])
18010 (define_insn "*rdpmc_rex64"
18011 [(set (match_operand:DI 0 "register_operand" "=a")
18012 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18014 (set (match_operand:DI 1 "register_operand" "=d")
18015 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18018 [(set_attr "type" "other")
18019 (set_attr "length" "2")])
18021 (define_expand "rdtsc"
18022 [(set (match_operand:DI 0 "register_operand" "")
18023 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18028 rtvec vec = rtvec_alloc (2);
18029 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18030 rtx upper = gen_reg_rtx (DImode);
18031 rtx lower = gen_reg_rtx (DImode);
18032 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18033 gen_rtvec (1, const0_rtx),
18035 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18036 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18038 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18039 NULL, 1, OPTAB_DIRECT);
18040 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18042 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18047 (define_insn "*rdtsc"
18048 [(set (match_operand:DI 0 "register_operand" "=A")
18049 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18052 [(set_attr "type" "other")
18053 (set_attr "length" "2")])
18055 (define_insn "*rdtsc_rex64"
18056 [(set (match_operand:DI 0 "register_operand" "=a")
18057 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18058 (set (match_operand:DI 1 "register_operand" "=d")
18059 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18062 [(set_attr "type" "other")
18063 (set_attr "length" "2")])
18065 (define_expand "rdtscp"
18066 [(match_operand:DI 0 "register_operand" "")
18067 (match_operand:SI 1 "memory_operand" "")]
18070 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18071 gen_rtvec (1, const0_rtx),
18073 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18074 gen_rtvec (1, const0_rtx),
18076 rtx reg = gen_reg_rtx (DImode);
18077 rtx tmp = gen_reg_rtx (SImode);
18081 rtvec vec = rtvec_alloc (3);
18082 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18083 rtx upper = gen_reg_rtx (DImode);
18084 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18085 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18086 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18088 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18089 NULL, 1, OPTAB_DIRECT);
18090 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18095 rtvec vec = rtvec_alloc (2);
18096 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18097 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18098 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18101 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18102 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18106 (define_insn "*rdtscp"
18107 [(set (match_operand:DI 0 "register_operand" "=A")
18108 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18109 (set (match_operand:SI 1 "register_operand" "=c")
18110 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18113 [(set_attr "type" "other")
18114 (set_attr "length" "3")])
18116 (define_insn "*rdtscp_rex64"
18117 [(set (match_operand:DI 0 "register_operand" "=a")
18118 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18119 (set (match_operand:DI 1 "register_operand" "=d")
18120 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18121 (set (match_operand:SI 2 "register_operand" "=c")
18122 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18125 [(set_attr "type" "other")
18126 (set_attr "length" "3")])
18128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18130 ;; LWP instructions
18132 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18134 (define_expand "lwp_llwpcb"
18135 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18136 UNSPECV_LLWP_INTRINSIC)]
18139 (define_insn "*lwp_llwpcb<mode>1"
18140 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18141 UNSPECV_LLWP_INTRINSIC)]
18144 [(set_attr "type" "lwp")
18145 (set_attr "mode" "<MODE>")
18146 (set_attr "length" "5")])
18148 (define_expand "lwp_slwpcb"
18149 [(set (match_operand 0 "register_operand" "=r")
18150 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18155 insn = (TARGET_64BIT
18157 : gen_lwp_slwpcbsi);
18159 emit_insn (insn (operands[0]));
18163 (define_insn "lwp_slwpcb<mode>"
18164 [(set (match_operand:P 0 "register_operand" "=r")
18165 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18168 [(set_attr "type" "lwp")
18169 (set_attr "mode" "<MODE>")
18170 (set_attr "length" "5")])
18172 (define_expand "lwp_lwpval<mode>3"
18173 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18174 (match_operand:SI 2 "nonimmediate_operand" "rm")
18175 (match_operand:SI 3 "const_int_operand" "i")]
18176 UNSPECV_LWPVAL_INTRINSIC)]
18178 "/* Avoid unused variable warning. */
18181 (define_insn "*lwp_lwpval<mode>3_1"
18182 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18183 (match_operand:SI 1 "nonimmediate_operand" "rm")
18184 (match_operand:SI 2 "const_int_operand" "i")]
18185 UNSPECV_LWPVAL_INTRINSIC)]
18187 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18188 [(set_attr "type" "lwp")
18189 (set_attr "mode" "<MODE>")
18190 (set (attr "length")
18191 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18193 (define_expand "lwp_lwpins<mode>3"
18194 [(set (reg:CCC FLAGS_REG)
18195 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18196 (match_operand:SI 2 "nonimmediate_operand" "rm")
18197 (match_operand:SI 3 "const_int_operand" "i")]
18198 UNSPECV_LWPINS_INTRINSIC))
18199 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18200 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18203 (define_insn "*lwp_lwpins<mode>3_1"
18204 [(set (reg:CCC FLAGS_REG)
18205 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18206 (match_operand:SI 1 "nonimmediate_operand" "rm")
18207 (match_operand:SI 2 "const_int_operand" "i")]
18208 UNSPECV_LWPINS_INTRINSIC))]
18210 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18211 [(set_attr "type" "lwp")
18212 (set_attr "mode" "<MODE>")
18213 (set (attr "length")
18214 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18216 (define_insn "rdfsbase<mode>"
18217 [(set (match_operand:SWI48 0 "register_operand" "=r")
18218 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18219 "TARGET_64BIT && TARGET_FSGSBASE"
18221 [(set_attr "type" "other")
18222 (set_attr "prefix_extra" "2")])
18224 (define_insn "rdgsbase<mode>"
18225 [(set (match_operand:SWI48 0 "register_operand" "=r")
18226 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18227 "TARGET_64BIT && TARGET_FSGSBASE"
18229 [(set_attr "type" "other")
18230 (set_attr "prefix_extra" "2")])
18232 (define_insn "wrfsbase<mode>"
18233 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18235 "TARGET_64BIT && TARGET_FSGSBASE"
18237 [(set_attr "type" "other")
18238 (set_attr "prefix_extra" "2")])
18240 (define_insn "wrgsbase<mode>"
18241 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18243 "TARGET_64BIT && TARGET_FSGSBASE"
18245 [(set_attr "type" "other")
18246 (set_attr "prefix_extra" "2")])
18248 (define_insn "rdrand<mode>_1"
18249 [(set (match_operand:SWI248 0 "register_operand" "=r")
18250 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18251 (set (reg:CCC FLAGS_REG)
18252 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18255 [(set_attr "type" "other")
18256 (set_attr "prefix_extra" "1")])
18260 (include "sync.md")