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 asm suffix for floating point modes
938 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
940 ;; SSE vector mode corresponding to a scalar mode
941 (define_mode_attr ssevecmode
942 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
944 ;; Instruction suffix for REX 64bit operators.
945 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
947 ;; This mode iterator allows :P to be used for patterns that operate on
948 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
949 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
951 ;; Scheduling descriptions
953 (include "pentium.md")
956 (include "athlon.md")
957 (include "bdver1.md")
963 ;; Operand and operator predicates and constraints
965 (include "predicates.md")
966 (include "constraints.md")
969 ;; Compare and branch/compare and store instructions.
971 (define_expand "cbranch<mode>4"
972 [(set (reg:CC FLAGS_REG)
973 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
974 (match_operand:SDWIM 2 "<general_operand>" "")))
975 (set (pc) (if_then_else
976 (match_operator 0 "ordered_comparison_operator"
977 [(reg:CC FLAGS_REG) (const_int 0)])
978 (label_ref (match_operand 3 "" ""))
982 if (MEM_P (operands[1]) && MEM_P (operands[2]))
983 operands[1] = force_reg (<MODE>mode, operands[1]);
984 ix86_expand_branch (GET_CODE (operands[0]),
985 operands[1], operands[2], operands[3]);
989 (define_expand "cstore<mode>4"
990 [(set (reg:CC FLAGS_REG)
991 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
992 (match_operand:SWIM 3 "<general_operand>" "")))
993 (set (match_operand:QI 0 "register_operand" "")
994 (match_operator 1 "ordered_comparison_operator"
995 [(reg:CC FLAGS_REG) (const_int 0)]))]
998 if (MEM_P (operands[2]) && MEM_P (operands[3]))
999 operands[2] = force_reg (<MODE>mode, operands[2]);
1000 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1001 operands[2], operands[3]);
1005 (define_expand "cmp<mode>_1"
1006 [(set (reg:CC FLAGS_REG)
1007 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1008 (match_operand:SWI48 1 "<general_operand>" "")))])
1010 (define_insn "*cmp<mode>_ccno_1"
1011 [(set (reg FLAGS_REG)
1012 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1013 (match_operand:SWI 1 "const0_operand" "")))]
1014 "ix86_match_ccmode (insn, CCNOmode)"
1016 test{<imodesuffix>}\t%0, %0
1017 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1018 [(set_attr "type" "test,icmp")
1019 (set_attr "length_immediate" "0,1")
1020 (set_attr "mode" "<MODE>")])
1022 (define_insn "*cmp<mode>_1"
1023 [(set (reg FLAGS_REG)
1024 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1025 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1026 "ix86_match_ccmode (insn, CCmode)"
1027 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1028 [(set_attr "type" "icmp")
1029 (set_attr "mode" "<MODE>")])
1031 (define_insn "*cmp<mode>_minus_1"
1032 [(set (reg FLAGS_REG)
1034 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1035 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1037 "ix86_match_ccmode (insn, CCGOCmode)"
1038 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1039 [(set_attr "type" "icmp")
1040 (set_attr "mode" "<MODE>")])
1042 (define_insn "*cmpqi_ext_1"
1043 [(set (reg FLAGS_REG)
1045 (match_operand:QI 0 "general_operand" "Qm")
1048 (match_operand 1 "ext_register_operand" "Q")
1050 (const_int 8)) 0)))]
1051 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1052 "cmp{b}\t{%h1, %0|%0, %h1}"
1053 [(set_attr "type" "icmp")
1054 (set_attr "mode" "QI")])
1056 (define_insn "*cmpqi_ext_1_rex64"
1057 [(set (reg FLAGS_REG)
1059 (match_operand:QI 0 "register_operand" "Q")
1062 (match_operand 1 "ext_register_operand" "Q")
1064 (const_int 8)) 0)))]
1065 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1066 "cmp{b}\t{%h1, %0|%0, %h1}"
1067 [(set_attr "type" "icmp")
1068 (set_attr "mode" "QI")])
1070 (define_insn "*cmpqi_ext_2"
1071 [(set (reg FLAGS_REG)
1075 (match_operand 0 "ext_register_operand" "Q")
1078 (match_operand:QI 1 "const0_operand" "")))]
1079 "ix86_match_ccmode (insn, CCNOmode)"
1081 [(set_attr "type" "test")
1082 (set_attr "length_immediate" "0")
1083 (set_attr "mode" "QI")])
1085 (define_expand "cmpqi_ext_3"
1086 [(set (reg:CC FLAGS_REG)
1090 (match_operand 0 "ext_register_operand" "")
1093 (match_operand:QI 1 "immediate_operand" "")))])
1095 (define_insn "*cmpqi_ext_3_insn"
1096 [(set (reg FLAGS_REG)
1100 (match_operand 0 "ext_register_operand" "Q")
1103 (match_operand:QI 1 "general_operand" "Qmn")))]
1104 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1105 "cmp{b}\t{%1, %h0|%h0, %1}"
1106 [(set_attr "type" "icmp")
1107 (set_attr "modrm" "1")
1108 (set_attr "mode" "QI")])
1110 (define_insn "*cmpqi_ext_3_insn_rex64"
1111 [(set (reg FLAGS_REG)
1115 (match_operand 0 "ext_register_operand" "Q")
1118 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1119 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1120 "cmp{b}\t{%1, %h0|%h0, %1}"
1121 [(set_attr "type" "icmp")
1122 (set_attr "modrm" "1")
1123 (set_attr "mode" "QI")])
1125 (define_insn "*cmpqi_ext_4"
1126 [(set (reg FLAGS_REG)
1130 (match_operand 0 "ext_register_operand" "Q")
1135 (match_operand 1 "ext_register_operand" "Q")
1137 (const_int 8)) 0)))]
1138 "ix86_match_ccmode (insn, CCmode)"
1139 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1140 [(set_attr "type" "icmp")
1141 (set_attr "mode" "QI")])
1143 ;; These implement float point compares.
1144 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1145 ;; which would allow mix and match FP modes on the compares. Which is what
1146 ;; the old patterns did, but with many more of them.
1148 (define_expand "cbranchxf4"
1149 [(set (reg:CC FLAGS_REG)
1150 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1151 (match_operand:XF 2 "nonmemory_operand" "")))
1152 (set (pc) (if_then_else
1153 (match_operator 0 "ix86_fp_comparison_operator"
1156 (label_ref (match_operand 3 "" ""))
1160 ix86_expand_branch (GET_CODE (operands[0]),
1161 operands[1], operands[2], operands[3]);
1165 (define_expand "cstorexf4"
1166 [(set (reg:CC FLAGS_REG)
1167 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1168 (match_operand:XF 3 "nonmemory_operand" "")))
1169 (set (match_operand:QI 0 "register_operand" "")
1170 (match_operator 1 "ix86_fp_comparison_operator"
1175 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1176 operands[2], operands[3]);
1180 (define_expand "cbranch<mode>4"
1181 [(set (reg:CC FLAGS_REG)
1182 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1183 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1184 (set (pc) (if_then_else
1185 (match_operator 0 "ix86_fp_comparison_operator"
1188 (label_ref (match_operand 3 "" ""))
1190 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1192 ix86_expand_branch (GET_CODE (operands[0]),
1193 operands[1], operands[2], operands[3]);
1197 (define_expand "cstore<mode>4"
1198 [(set (reg:CC FLAGS_REG)
1199 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1200 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1201 (set (match_operand:QI 0 "register_operand" "")
1202 (match_operator 1 "ix86_fp_comparison_operator"
1205 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1207 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1208 operands[2], operands[3]);
1212 (define_expand "cbranchcc4"
1213 [(set (pc) (if_then_else
1214 (match_operator 0 "comparison_operator"
1215 [(match_operand 1 "flags_reg_operand" "")
1216 (match_operand 2 "const0_operand" "")])
1217 (label_ref (match_operand 3 "" ""))
1221 ix86_expand_branch (GET_CODE (operands[0]),
1222 operands[1], operands[2], operands[3]);
1226 (define_expand "cstorecc4"
1227 [(set (match_operand:QI 0 "register_operand" "")
1228 (match_operator 1 "comparison_operator"
1229 [(match_operand 2 "flags_reg_operand" "")
1230 (match_operand 3 "const0_operand" "")]))]
1233 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1234 operands[2], operands[3]);
1239 ;; FP compares, step 1:
1240 ;; Set the FP condition codes.
1242 ;; CCFPmode compare with exceptions
1243 ;; CCFPUmode compare with no exceptions
1245 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1246 ;; used to manage the reg stack popping would not be preserved.
1248 (define_insn "*cmpfp_0"
1249 [(set (match_operand:HI 0 "register_operand" "=a")
1252 (match_operand 1 "register_operand" "f")
1253 (match_operand 2 "const0_operand" ""))]
1255 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1256 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1257 "* return output_fp_compare (insn, operands, 0, 0);"
1258 [(set_attr "type" "multi")
1259 (set_attr "unit" "i387")
1261 (cond [(match_operand:SF 1 "" "")
1263 (match_operand:DF 1 "" "")
1266 (const_string "XF")))])
1268 (define_insn_and_split "*cmpfp_0_cc"
1269 [(set (reg:CCFP FLAGS_REG)
1271 (match_operand 1 "register_operand" "f")
1272 (match_operand 2 "const0_operand" "")))
1273 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1274 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1275 && TARGET_SAHF && !TARGET_CMOVE
1276 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1278 "&& reload_completed"
1281 [(compare:CCFP (match_dup 1)(match_dup 2))]
1283 (set (reg:CC FLAGS_REG)
1284 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1286 [(set_attr "type" "multi")
1287 (set_attr "unit" "i387")
1289 (cond [(match_operand:SF 1 "" "")
1291 (match_operand:DF 1 "" "")
1294 (const_string "XF")))])
1296 (define_insn "*cmpfp_xf"
1297 [(set (match_operand:HI 0 "register_operand" "=a")
1300 (match_operand:XF 1 "register_operand" "f")
1301 (match_operand:XF 2 "register_operand" "f"))]
1304 "* return output_fp_compare (insn, operands, 0, 0);"
1305 [(set_attr "type" "multi")
1306 (set_attr "unit" "i387")
1307 (set_attr "mode" "XF")])
1309 (define_insn_and_split "*cmpfp_xf_cc"
1310 [(set (reg:CCFP FLAGS_REG)
1312 (match_operand:XF 1 "register_operand" "f")
1313 (match_operand:XF 2 "register_operand" "f")))
1314 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1316 && TARGET_SAHF && !TARGET_CMOVE"
1318 "&& reload_completed"
1321 [(compare:CCFP (match_dup 1)(match_dup 2))]
1323 (set (reg:CC FLAGS_REG)
1324 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1326 [(set_attr "type" "multi")
1327 (set_attr "unit" "i387")
1328 (set_attr "mode" "XF")])
1330 (define_insn "*cmpfp_<mode>"
1331 [(set (match_operand:HI 0 "register_operand" "=a")
1334 (match_operand:MODEF 1 "register_operand" "f")
1335 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1338 "* return output_fp_compare (insn, operands, 0, 0);"
1339 [(set_attr "type" "multi")
1340 (set_attr "unit" "i387")
1341 (set_attr "mode" "<MODE>")])
1343 (define_insn_and_split "*cmpfp_<mode>_cc"
1344 [(set (reg:CCFP FLAGS_REG)
1346 (match_operand:MODEF 1 "register_operand" "f")
1347 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1348 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1350 && TARGET_SAHF && !TARGET_CMOVE"
1352 "&& reload_completed"
1355 [(compare:CCFP (match_dup 1)(match_dup 2))]
1357 (set (reg:CC FLAGS_REG)
1358 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1360 [(set_attr "type" "multi")
1361 (set_attr "unit" "i387")
1362 (set_attr "mode" "<MODE>")])
1364 (define_insn "*cmpfp_u"
1365 [(set (match_operand:HI 0 "register_operand" "=a")
1368 (match_operand 1 "register_operand" "f")
1369 (match_operand 2 "register_operand" "f"))]
1371 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1372 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1373 "* return output_fp_compare (insn, operands, 0, 1);"
1374 [(set_attr "type" "multi")
1375 (set_attr "unit" "i387")
1377 (cond [(match_operand:SF 1 "" "")
1379 (match_operand:DF 1 "" "")
1382 (const_string "XF")))])
1384 (define_insn_and_split "*cmpfp_u_cc"
1385 [(set (reg:CCFPU FLAGS_REG)
1387 (match_operand 1 "register_operand" "f")
1388 (match_operand 2 "register_operand" "f")))
1389 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1390 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1391 && TARGET_SAHF && !TARGET_CMOVE
1392 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1394 "&& reload_completed"
1397 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1399 (set (reg:CC FLAGS_REG)
1400 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1402 [(set_attr "type" "multi")
1403 (set_attr "unit" "i387")
1405 (cond [(match_operand:SF 1 "" "")
1407 (match_operand:DF 1 "" "")
1410 (const_string "XF")))])
1412 (define_insn "*cmpfp_<mode>"
1413 [(set (match_operand:HI 0 "register_operand" "=a")
1416 (match_operand 1 "register_operand" "f")
1417 (match_operator 3 "float_operator"
1418 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1420 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1421 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1422 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1423 "* return output_fp_compare (insn, operands, 0, 0);"
1424 [(set_attr "type" "multi")
1425 (set_attr "unit" "i387")
1426 (set_attr "fp_int_src" "true")
1427 (set_attr "mode" "<MODE>")])
1429 (define_insn_and_split "*cmpfp_<mode>_cc"
1430 [(set (reg:CCFP FLAGS_REG)
1432 (match_operand 1 "register_operand" "f")
1433 (match_operator 3 "float_operator"
1434 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1435 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1436 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1437 && TARGET_SAHF && !TARGET_CMOVE
1438 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1439 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1441 "&& reload_completed"
1446 (match_op_dup 3 [(match_dup 2)]))]
1448 (set (reg:CC FLAGS_REG)
1449 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1451 [(set_attr "type" "multi")
1452 (set_attr "unit" "i387")
1453 (set_attr "fp_int_src" "true")
1454 (set_attr "mode" "<MODE>")])
1456 ;; FP compares, step 2
1457 ;; Move the fpsw to ax.
1459 (define_insn "x86_fnstsw_1"
1460 [(set (match_operand:HI 0 "register_operand" "=a")
1461 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1464 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1465 (set_attr "mode" "SI")
1466 (set_attr "unit" "i387")])
1468 ;; FP compares, step 3
1469 ;; Get ax into flags, general case.
1471 (define_insn "x86_sahf_1"
1472 [(set (reg:CC FLAGS_REG)
1473 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1477 #ifndef HAVE_AS_IX86_SAHF
1479 return ASM_BYTE "0x9e";
1484 [(set_attr "length" "1")
1485 (set_attr "athlon_decode" "vector")
1486 (set_attr "amdfam10_decode" "direct")
1487 (set_attr "bdver1_decode" "direct")
1488 (set_attr "mode" "SI")])
1490 ;; Pentium Pro can do steps 1 through 3 in one go.
1491 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1492 (define_insn "*cmpfp_i_mixed"
1493 [(set (reg:CCFP FLAGS_REG)
1494 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1495 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1496 "TARGET_MIX_SSE_I387
1497 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1498 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1499 "* return output_fp_compare (insn, operands, 1, 0);"
1500 [(set_attr "type" "fcmp,ssecomi")
1501 (set_attr "prefix" "orig,maybe_vex")
1503 (if_then_else (match_operand:SF 1 "" "")
1505 (const_string "DF")))
1506 (set (attr "prefix_rep")
1507 (if_then_else (eq_attr "type" "ssecomi")
1509 (const_string "*")))
1510 (set (attr "prefix_data16")
1511 (cond [(eq_attr "type" "fcmp")
1513 (eq_attr "mode" "DF")
1516 (const_string "0")))
1517 (set_attr "athlon_decode" "vector")
1518 (set_attr "amdfam10_decode" "direct")
1519 (set_attr "bdver1_decode" "double")])
1521 (define_insn "*cmpfp_i_sse"
1522 [(set (reg:CCFP FLAGS_REG)
1523 (compare:CCFP (match_operand 0 "register_operand" "x")
1524 (match_operand 1 "nonimmediate_operand" "xm")))]
1526 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1527 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1528 "* return output_fp_compare (insn, operands, 1, 0);"
1529 [(set_attr "type" "ssecomi")
1530 (set_attr "prefix" "maybe_vex")
1532 (if_then_else (match_operand:SF 1 "" "")
1534 (const_string "DF")))
1535 (set_attr "prefix_rep" "0")
1536 (set (attr "prefix_data16")
1537 (if_then_else (eq_attr "mode" "DF")
1539 (const_string "0")))
1540 (set_attr "athlon_decode" "vector")
1541 (set_attr "amdfam10_decode" "direct")
1542 (set_attr "bdver1_decode" "double")])
1544 (define_insn "*cmpfp_i_i387"
1545 [(set (reg:CCFP FLAGS_REG)
1546 (compare:CCFP (match_operand 0 "register_operand" "f")
1547 (match_operand 1 "register_operand" "f")))]
1548 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1550 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1551 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1552 "* return output_fp_compare (insn, operands, 1, 0);"
1553 [(set_attr "type" "fcmp")
1555 (cond [(match_operand:SF 1 "" "")
1557 (match_operand:DF 1 "" "")
1560 (const_string "XF")))
1561 (set_attr "athlon_decode" "vector")
1562 (set_attr "amdfam10_decode" "direct")
1563 (set_attr "bdver1_decode" "double")])
1565 (define_insn "*cmpfp_iu_mixed"
1566 [(set (reg:CCFPU FLAGS_REG)
1567 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1568 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1569 "TARGET_MIX_SSE_I387
1570 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1571 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1572 "* return output_fp_compare (insn, operands, 1, 1);"
1573 [(set_attr "type" "fcmp,ssecomi")
1574 (set_attr "prefix" "orig,maybe_vex")
1576 (if_then_else (match_operand:SF 1 "" "")
1578 (const_string "DF")))
1579 (set (attr "prefix_rep")
1580 (if_then_else (eq_attr "type" "ssecomi")
1582 (const_string "*")))
1583 (set (attr "prefix_data16")
1584 (cond [(eq_attr "type" "fcmp")
1586 (eq_attr "mode" "DF")
1589 (const_string "0")))
1590 (set_attr "athlon_decode" "vector")
1591 (set_attr "amdfam10_decode" "direct")
1592 (set_attr "bdver1_decode" "double")])
1594 (define_insn "*cmpfp_iu_sse"
1595 [(set (reg:CCFPU FLAGS_REG)
1596 (compare:CCFPU (match_operand 0 "register_operand" "x")
1597 (match_operand 1 "nonimmediate_operand" "xm")))]
1599 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1600 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1601 "* return output_fp_compare (insn, operands, 1, 1);"
1602 [(set_attr "type" "ssecomi")
1603 (set_attr "prefix" "maybe_vex")
1605 (if_then_else (match_operand:SF 1 "" "")
1607 (const_string "DF")))
1608 (set_attr "prefix_rep" "0")
1609 (set (attr "prefix_data16")
1610 (if_then_else (eq_attr "mode" "DF")
1612 (const_string "0")))
1613 (set_attr "athlon_decode" "vector")
1614 (set_attr "amdfam10_decode" "direct")
1615 (set_attr "bdver1_decode" "double")])
1617 (define_insn "*cmpfp_iu_387"
1618 [(set (reg:CCFPU FLAGS_REG)
1619 (compare:CCFPU (match_operand 0 "register_operand" "f")
1620 (match_operand 1 "register_operand" "f")))]
1621 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1623 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1624 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1625 "* return output_fp_compare (insn, operands, 1, 1);"
1626 [(set_attr "type" "fcmp")
1628 (cond [(match_operand:SF 1 "" "")
1630 (match_operand:DF 1 "" "")
1633 (const_string "XF")))
1634 (set_attr "athlon_decode" "vector")
1635 (set_attr "amdfam10_decode" "direct")
1636 (set_attr "bdver1_decode" "direct")])
1638 ;; Push/pop instructions.
1640 (define_insn "*push<mode>2"
1641 [(set (match_operand:DWI 0 "push_operand" "=<")
1642 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1647 [(set (match_operand:TI 0 "push_operand" "")
1648 (match_operand:TI 1 "general_operand" ""))]
1649 "TARGET_64BIT && reload_completed
1650 && !SSE_REG_P (operands[1])"
1652 "ix86_split_long_move (operands); DONE;")
1654 (define_insn "*pushdi2_rex64"
1655 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1656 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1661 [(set_attr "type" "push,multi")
1662 (set_attr "mode" "DI")])
1664 ;; Convert impossible pushes of immediate to existing instructions.
1665 ;; First try to get scratch register and go through it. In case this
1666 ;; fails, push sign extended lower part first and then overwrite
1667 ;; upper part by 32bit move.
1669 [(match_scratch:DI 2 "r")
1670 (set (match_operand:DI 0 "push_operand" "")
1671 (match_operand:DI 1 "immediate_operand" ""))]
1672 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1673 && !x86_64_immediate_operand (operands[1], DImode)"
1674 [(set (match_dup 2) (match_dup 1))
1675 (set (match_dup 0) (match_dup 2))])
1677 ;; We need to define this as both peepholer and splitter for case
1678 ;; peephole2 pass is not run.
1679 ;; "&& 1" is needed to keep it from matching the previous pattern.
1681 [(set (match_operand:DI 0 "push_operand" "")
1682 (match_operand:DI 1 "immediate_operand" ""))]
1683 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1684 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1685 [(set (match_dup 0) (match_dup 1))
1686 (set (match_dup 2) (match_dup 3))]
1688 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1690 operands[1] = gen_lowpart (DImode, operands[2]);
1691 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1696 [(set (match_operand:DI 0 "push_operand" "")
1697 (match_operand:DI 1 "immediate_operand" ""))]
1698 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1699 ? epilogue_completed : reload_completed)
1700 && !symbolic_operand (operands[1], DImode)
1701 && !x86_64_immediate_operand (operands[1], DImode)"
1702 [(set (match_dup 0) (match_dup 1))
1703 (set (match_dup 2) (match_dup 3))]
1705 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1707 operands[1] = gen_lowpart (DImode, operands[2]);
1708 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1713 [(set (match_operand:DI 0 "push_operand" "")
1714 (match_operand:DI 1 "general_operand" ""))]
1715 "!TARGET_64BIT && reload_completed
1716 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1718 "ix86_split_long_move (operands); DONE;")
1720 (define_insn "*pushsi2"
1721 [(set (match_operand:SI 0 "push_operand" "=<")
1722 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1725 [(set_attr "type" "push")
1726 (set_attr "mode" "SI")])
1728 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1729 ;; "push a byte/word". But actually we use pushl, which has the effect
1730 ;; of rounding the amount pushed up to a word.
1732 ;; For TARGET_64BIT we always round up to 8 bytes.
1733 (define_insn "*push<mode>2_rex64"
1734 [(set (match_operand:SWI124 0 "push_operand" "=X")
1735 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1738 [(set_attr "type" "push")
1739 (set_attr "mode" "DI")])
1741 (define_insn "*push<mode>2"
1742 [(set (match_operand:SWI12 0 "push_operand" "=X")
1743 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1746 [(set_attr "type" "push")
1747 (set_attr "mode" "SI")])
1749 (define_insn "*push<mode>2_prologue"
1750 [(set (match_operand:P 0 "push_operand" "=<")
1751 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1752 (clobber (mem:BLK (scratch)))]
1754 "push{<imodesuffix>}\t%1"
1755 [(set_attr "type" "push")
1756 (set_attr "mode" "<MODE>")])
1758 (define_insn "*pop<mode>1"
1759 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1760 (match_operand:P 1 "pop_operand" ">"))]
1762 "pop{<imodesuffix>}\t%0"
1763 [(set_attr "type" "pop")
1764 (set_attr "mode" "<MODE>")])
1766 (define_insn "*pop<mode>1_epilogue"
1767 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1768 (match_operand:P 1 "pop_operand" ">"))
1769 (clobber (mem:BLK (scratch)))]
1771 "pop{<imodesuffix>}\t%0"
1772 [(set_attr "type" "pop")
1773 (set_attr "mode" "<MODE>")])
1775 ;; Move instructions.
1777 (define_expand "movoi"
1778 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1779 (match_operand:OI 1 "general_operand" ""))]
1781 "ix86_expand_move (OImode, operands); DONE;")
1783 (define_expand "movti"
1784 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1785 (match_operand:TI 1 "nonimmediate_operand" ""))]
1786 "TARGET_64BIT || TARGET_SSE"
1789 ix86_expand_move (TImode, operands);
1790 else if (push_operand (operands[0], TImode))
1791 ix86_expand_push (TImode, operands[1]);
1793 ix86_expand_vector_move (TImode, operands);
1797 ;; This expands to what emit_move_complex would generate if we didn't
1798 ;; have a movti pattern. Having this avoids problems with reload on
1799 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1800 ;; to have around all the time.
1801 (define_expand "movcdi"
1802 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1803 (match_operand:CDI 1 "general_operand" ""))]
1806 if (push_operand (operands[0], CDImode))
1807 emit_move_complex_push (CDImode, operands[0], operands[1]);
1809 emit_move_complex_parts (operands[0], operands[1]);
1813 (define_expand "mov<mode>"
1814 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1815 (match_operand:SWI1248x 1 "general_operand" ""))]
1817 "ix86_expand_move (<MODE>mode, operands); DONE;")
1819 (define_insn "*mov<mode>_xor"
1820 [(set (match_operand:SWI48 0 "register_operand" "=r")
1821 (match_operand:SWI48 1 "const0_operand" ""))
1822 (clobber (reg:CC FLAGS_REG))]
1825 [(set_attr "type" "alu1")
1826 (set_attr "mode" "SI")
1827 (set_attr "length_immediate" "0")])
1829 (define_insn "*mov<mode>_or"
1830 [(set (match_operand:SWI48 0 "register_operand" "=r")
1831 (match_operand:SWI48 1 "const_int_operand" ""))
1832 (clobber (reg:CC FLAGS_REG))]
1834 && operands[1] == constm1_rtx"
1835 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1836 [(set_attr "type" "alu1")
1837 (set_attr "mode" "<MODE>")
1838 (set_attr "length_immediate" "1")])
1840 (define_insn "*movoi_internal_avx"
1841 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1842 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1843 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1845 switch (which_alternative)
1848 return "vxorps\t%0, %0, %0";
1851 if (misaligned_operand (operands[0], OImode)
1852 || misaligned_operand (operands[1], OImode))
1853 return "vmovdqu\t{%1, %0|%0, %1}";
1855 return "vmovdqa\t{%1, %0|%0, %1}";
1860 [(set_attr "type" "sselog1,ssemov,ssemov")
1861 (set_attr "prefix" "vex")
1862 (set_attr "mode" "OI")])
1864 (define_insn "*movti_internal_rex64"
1865 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1866 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1867 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1869 switch (which_alternative)
1875 if (get_attr_mode (insn) == MODE_V4SF)
1876 return "%vxorps\t%0, %d0";
1878 return "%vpxor\t%0, %d0";
1881 /* TDmode values are passed as TImode on the stack. Moving them
1882 to stack may result in unaligned memory access. */
1883 if (misaligned_operand (operands[0], TImode)
1884 || misaligned_operand (operands[1], TImode))
1886 if (get_attr_mode (insn) == MODE_V4SF)
1887 return "%vmovups\t{%1, %0|%0, %1}";
1889 return "%vmovdqu\t{%1, %0|%0, %1}";
1893 if (get_attr_mode (insn) == MODE_V4SF)
1894 return "%vmovaps\t{%1, %0|%0, %1}";
1896 return "%vmovdqa\t{%1, %0|%0, %1}";
1902 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1903 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1905 (cond [(eq_attr "alternative" "2,3")
1907 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1909 (const_string "V4SF")
1910 (const_string "TI"))
1911 (eq_attr "alternative" "4")
1913 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1915 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1917 (const_string "V4SF")
1918 (const_string "TI"))]
1919 (const_string "DI")))])
1922 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1923 (match_operand:TI 1 "general_operand" ""))]
1925 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1927 "ix86_split_long_move (operands); DONE;")
1929 (define_insn "*movti_internal_sse"
1930 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1931 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1932 "TARGET_SSE && !TARGET_64BIT
1933 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935 switch (which_alternative)
1938 if (get_attr_mode (insn) == MODE_V4SF)
1939 return "%vxorps\t%0, %d0";
1941 return "%vpxor\t%0, %d0";
1944 /* TDmode values are passed as TImode on the stack. Moving them
1945 to stack may result in unaligned memory access. */
1946 if (misaligned_operand (operands[0], TImode)
1947 || misaligned_operand (operands[1], TImode))
1949 if (get_attr_mode (insn) == MODE_V4SF)
1950 return "%vmovups\t{%1, %0|%0, %1}";
1952 return "%vmovdqu\t{%1, %0|%0, %1}";
1956 if (get_attr_mode (insn) == MODE_V4SF)
1957 return "%vmovaps\t{%1, %0|%0, %1}";
1959 return "%vmovdqa\t{%1, %0|%0, %1}";
1965 [(set_attr "type" "sselog1,ssemov,ssemov")
1966 (set_attr "prefix" "maybe_vex")
1968 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1969 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1971 (const_string "V4SF")
1972 (and (eq_attr "alternative" "2")
1973 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1975 (const_string "V4SF")]
1976 (const_string "TI")))])
1978 (define_insn "*movdi_internal_rex64"
1979 [(set (match_operand:DI 0 "nonimmediate_operand"
1980 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1981 (match_operand:DI 1 "general_operand"
1982 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1983 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1985 switch (get_attr_type (insn))
1988 if (SSE_REG_P (operands[0]))
1989 return "movq2dq\t{%1, %0|%0, %1}";
1991 return "movdq2q\t{%1, %0|%0, %1}";
1996 if (get_attr_mode (insn) == MODE_TI)
1997 return "vmovdqa\t{%1, %0|%0, %1}";
1999 return "vmovq\t{%1, %0|%0, %1}";
2002 if (get_attr_mode (insn) == MODE_TI)
2003 return "movdqa\t{%1, %0|%0, %1}";
2007 /* Moves from and into integer register is done using movd
2008 opcode with REX prefix. */
2009 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2010 return "movd\t{%1, %0|%0, %1}";
2011 return "movq\t{%1, %0|%0, %1}";
2014 return "%vpxor\t%0, %d0";
2017 return "pxor\t%0, %0";
2023 return "lea{q}\t{%a1, %0|%0, %a1}";
2026 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2027 if (get_attr_mode (insn) == MODE_SI)
2028 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2029 else if (which_alternative == 2)
2030 return "movabs{q}\t{%1, %0|%0, %1}";
2032 return "mov{q}\t{%1, %0|%0, %1}";
2036 (cond [(eq_attr "alternative" "5")
2037 (const_string "mmx")
2038 (eq_attr "alternative" "6,7,8,9,10")
2039 (const_string "mmxmov")
2040 (eq_attr "alternative" "11")
2041 (const_string "sselog1")
2042 (eq_attr "alternative" "12,13,14,15,16")
2043 (const_string "ssemov")
2044 (eq_attr "alternative" "17,18")
2045 (const_string "ssecvt")
2046 (eq_attr "alternative" "4")
2047 (const_string "multi")
2048 (match_operand:DI 1 "pic_32bit_operand" "")
2049 (const_string "lea")
2051 (const_string "imov")))
2054 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2056 (const_string "*")))
2057 (set (attr "length_immediate")
2059 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2061 (const_string "*")))
2062 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2063 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2064 (set (attr "prefix")
2065 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2066 (const_string "maybe_vex")
2067 (const_string "orig")))
2068 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it. In case this
2072 ;; fails, move by 32bit parts.
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))])
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2086 [(set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090 [(set (match_dup 2) (match_dup 3))
2091 (set (match_dup 4) (match_dup 5))]
2092 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2095 [(set (match_operand:DI 0 "memory_operand" "")
2096 (match_operand:DI 1 "immediate_operand" ""))]
2097 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098 ? epilogue_completed : reload_completed)
2099 && !symbolic_operand (operands[1], DImode)
2100 && !x86_64_immediate_operand (operands[1], DImode)"
2101 [(set (match_dup 2) (match_dup 3))
2102 (set (match_dup 4) (match_dup 5))]
2103 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2105 (define_insn "*movdi_internal"
2106 [(set (match_operand:DI 0 "nonimmediate_operand"
2107 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2108 (match_operand:DI 1 "general_operand"
2109 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2110 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2115 movq\t{%1, %0|%0, %1}
2116 movq\t{%1, %0|%0, %1}
2118 %vmovq\t{%1, %0|%0, %1}
2119 %vmovdqa\t{%1, %0|%0, %1}
2120 %vmovq\t{%1, %0|%0, %1}
2122 movlps\t{%1, %0|%0, %1}
2123 movaps\t{%1, %0|%0, %1}
2124 movlps\t{%1, %0|%0, %1}"
2125 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2126 (set (attr "prefix")
2127 (if_then_else (eq_attr "alternative" "5,6,7,8")
2128 (const_string "vex")
2129 (const_string "orig")))
2130 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2133 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2134 (match_operand:DI 1 "general_operand" ""))]
2135 "!TARGET_64BIT && reload_completed
2136 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2137 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2139 "ix86_split_long_move (operands); DONE;")
2141 (define_insn "*movsi_internal"
2142 [(set (match_operand:SI 0 "nonimmediate_operand"
2143 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2144 (match_operand:SI 1 "general_operand"
2145 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2146 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2148 switch (get_attr_type (insn))
2151 if (get_attr_mode (insn) == MODE_TI)
2152 return "%vpxor\t%0, %d0";
2153 return "%vxorps\t%0, %d0";
2156 switch (get_attr_mode (insn))
2159 return "%vmovdqa\t{%1, %0|%0, %1}";
2161 return "%vmovaps\t{%1, %0|%0, %1}";
2163 return "%vmovd\t{%1, %0|%0, %1}";
2165 return "%vmovss\t{%1, %0|%0, %1}";
2171 return "pxor\t%0, %0";
2174 if (get_attr_mode (insn) == MODE_DI)
2175 return "movq\t{%1, %0|%0, %1}";
2176 return "movd\t{%1, %0|%0, %1}";
2179 return "lea{l}\t{%a1, %0|%0, %a1}";
2182 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2183 return "mov{l}\t{%1, %0|%0, %1}";
2187 (cond [(eq_attr "alternative" "2")
2188 (const_string "mmx")
2189 (eq_attr "alternative" "3,4,5")
2190 (const_string "mmxmov")
2191 (eq_attr "alternative" "6")
2192 (const_string "sselog1")
2193 (eq_attr "alternative" "7,8,9,10,11")
2194 (const_string "ssemov")
2195 (match_operand:DI 1 "pic_32bit_operand" "")
2196 (const_string "lea")
2198 (const_string "imov")))
2199 (set (attr "prefix")
2200 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2201 (const_string "orig")
2202 (const_string "maybe_vex")))
2203 (set (attr "prefix_data16")
2204 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2206 (const_string "*")))
2208 (cond [(eq_attr "alternative" "2,3")
2210 (eq_attr "alternative" "6,7")
2212 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2213 (const_string "V4SF")
2214 (const_string "TI"))
2215 (and (eq_attr "alternative" "8,9,10,11")
2216 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2219 (const_string "SI")))])
2221 (define_insn "*movhi_internal"
2222 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2223 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2224 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2226 switch (get_attr_type (insn))
2229 /* movzwl is faster than movw on p2 due to partial word stalls,
2230 though not as fast as an aligned movl. */
2231 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2233 if (get_attr_mode (insn) == MODE_SI)
2234 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2236 return "mov{w}\t{%1, %0|%0, %1}";
2240 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2242 (const_string "imov")
2243 (and (eq_attr "alternative" "0")
2244 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2246 (eq (symbol_ref "TARGET_HIMODE_MATH")
2248 (const_string "imov")
2249 (and (eq_attr "alternative" "1,2")
2250 (match_operand:HI 1 "aligned_operand" ""))
2251 (const_string "imov")
2252 (and (ne (symbol_ref "TARGET_MOVX")
2254 (eq_attr "alternative" "0,2"))
2255 (const_string "imovx")
2257 (const_string "imov")))
2259 (cond [(eq_attr "type" "imovx")
2261 (and (eq_attr "alternative" "1,2")
2262 (match_operand:HI 1 "aligned_operand" ""))
2264 (and (eq_attr "alternative" "0")
2265 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2267 (eq (symbol_ref "TARGET_HIMODE_MATH")
2271 (const_string "HI")))])
2273 ;; Situation is quite tricky about when to choose full sized (SImode) move
2274 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2275 ;; partial register dependency machines (such as AMD Athlon), where QImode
2276 ;; moves issue extra dependency and for partial register stalls machines
2277 ;; that don't use QImode patterns (and QImode move cause stall on the next
2280 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2281 ;; register stall machines with, where we use QImode instructions, since
2282 ;; partial register stall can be caused there. Then we use movzx.
2283 (define_insn "*movqi_internal"
2284 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2285 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2286 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2288 switch (get_attr_type (insn))
2291 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2292 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2294 if (get_attr_mode (insn) == MODE_SI)
2295 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2297 return "mov{b}\t{%1, %0|%0, %1}";
2301 (cond [(and (eq_attr "alternative" "5")
2302 (not (match_operand:QI 1 "aligned_operand" "")))
2303 (const_string "imovx")
2304 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2306 (const_string "imov")
2307 (and (eq_attr "alternative" "3")
2308 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2310 (eq (symbol_ref "TARGET_QIMODE_MATH")
2312 (const_string "imov")
2313 (eq_attr "alternative" "3,5")
2314 (const_string "imovx")
2315 (and (ne (symbol_ref "TARGET_MOVX")
2317 (eq_attr "alternative" "2"))
2318 (const_string "imovx")
2320 (const_string "imov")))
2322 (cond [(eq_attr "alternative" "3,4,5")
2324 (eq_attr "alternative" "6")
2326 (eq_attr "type" "imovx")
2328 (and (eq_attr "type" "imov")
2329 (and (eq_attr "alternative" "0,1")
2330 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2332 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2334 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2337 ;; Avoid partial register stalls when not using QImode arithmetic
2338 (and (eq_attr "type" "imov")
2339 (and (eq_attr "alternative" "0,1")
2340 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2342 (eq (symbol_ref "TARGET_QIMODE_MATH")
2346 (const_string "QI")))])
2348 ;; Stores and loads of ax to arbitrary constant address.
2349 ;; We fake an second form of instruction to force reload to load address
2350 ;; into register when rax is not available
2351 (define_insn "*movabs<mode>_1"
2352 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2353 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2354 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2356 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2357 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2358 [(set_attr "type" "imov")
2359 (set_attr "modrm" "0,*")
2360 (set_attr "length_address" "8,0")
2361 (set_attr "length_immediate" "0,*")
2362 (set_attr "memory" "store")
2363 (set_attr "mode" "<MODE>")])
2365 (define_insn "*movabs<mode>_2"
2366 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2367 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2368 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2370 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2371 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2372 [(set_attr "type" "imov")
2373 (set_attr "modrm" "0,*")
2374 (set_attr "length_address" "8,0")
2375 (set_attr "length_immediate" "0")
2376 (set_attr "memory" "load")
2377 (set_attr "mode" "<MODE>")])
2379 (define_insn "*swap<mode>"
2380 [(set (match_operand:SWI48 0 "register_operand" "+r")
2381 (match_operand:SWI48 1 "register_operand" "+r"))
2385 "xchg{<imodesuffix>}\t%1, %0"
2386 [(set_attr "type" "imov")
2387 (set_attr "mode" "<MODE>")
2388 (set_attr "pent_pair" "np")
2389 (set_attr "athlon_decode" "vector")
2390 (set_attr "amdfam10_decode" "double")
2391 (set_attr "bdver1_decode" "double")])
2393 (define_insn "*swap<mode>_1"
2394 [(set (match_operand:SWI12 0 "register_operand" "+r")
2395 (match_operand:SWI12 1 "register_operand" "+r"))
2398 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2400 [(set_attr "type" "imov")
2401 (set_attr "mode" "SI")
2402 (set_attr "pent_pair" "np")
2403 (set_attr "athlon_decode" "vector")
2404 (set_attr "amdfam10_decode" "double")
2405 (set_attr "bdver1_decode" "double")])
2407 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2408 ;; is disabled for AMDFAM10
2409 (define_insn "*swap<mode>_2"
2410 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2411 (match_operand:SWI12 1 "register_operand" "+<r>"))
2414 "TARGET_PARTIAL_REG_STALL"
2415 "xchg{<imodesuffix>}\t%1, %0"
2416 [(set_attr "type" "imov")
2417 (set_attr "mode" "<MODE>")
2418 (set_attr "pent_pair" "np")
2419 (set_attr "athlon_decode" "vector")])
2421 (define_expand "movstrict<mode>"
2422 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2423 (match_operand:SWI12 1 "general_operand" ""))]
2426 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2428 if (GET_CODE (operands[0]) == SUBREG
2429 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2431 /* Don't generate memory->memory moves, go through a register */
2432 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2433 operands[1] = force_reg (<MODE>mode, operands[1]);
2436 (define_insn "*movstrict<mode>_1"
2437 [(set (strict_low_part
2438 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2439 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2440 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2441 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2442 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2443 [(set_attr "type" "imov")
2444 (set_attr "mode" "<MODE>")])
2446 (define_insn "*movstrict<mode>_xor"
2447 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2448 (match_operand:SWI12 1 "const0_operand" ""))
2449 (clobber (reg:CC FLAGS_REG))]
2451 "xor{<imodesuffix>}\t%0, %0"
2452 [(set_attr "type" "alu1")
2453 (set_attr "mode" "<MODE>")
2454 (set_attr "length_immediate" "0")])
2456 (define_insn "*mov<mode>_extv_1"
2457 [(set (match_operand:SWI24 0 "register_operand" "=R")
2458 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2462 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2463 [(set_attr "type" "imovx")
2464 (set_attr "mode" "SI")])
2466 (define_insn "*movqi_extv_1_rex64"
2467 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2468 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2473 switch (get_attr_type (insn))
2476 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2478 return "mov{b}\t{%h1, %0|%0, %h1}";
2482 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2483 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2484 (ne (symbol_ref "TARGET_MOVX")
2486 (const_string "imovx")
2487 (const_string "imov")))
2489 (if_then_else (eq_attr "type" "imovx")
2491 (const_string "QI")))])
2493 (define_insn "*movqi_extv_1"
2494 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2495 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2500 switch (get_attr_type (insn))
2503 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2505 return "mov{b}\t{%h1, %0|%0, %h1}";
2509 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2510 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2511 (ne (symbol_ref "TARGET_MOVX")
2513 (const_string "imovx")
2514 (const_string "imov")))
2516 (if_then_else (eq_attr "type" "imovx")
2518 (const_string "QI")))])
2520 (define_insn "*mov<mode>_extzv_1"
2521 [(set (match_operand:SWI48 0 "register_operand" "=R")
2522 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2526 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2527 [(set_attr "type" "imovx")
2528 (set_attr "mode" "SI")])
2530 (define_insn "*movqi_extzv_2_rex64"
2531 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2533 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2538 switch (get_attr_type (insn))
2541 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2543 return "mov{b}\t{%h1, %0|%0, %h1}";
2547 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2548 (ne (symbol_ref "TARGET_MOVX")
2550 (const_string "imovx")
2551 (const_string "imov")))
2553 (if_then_else (eq_attr "type" "imovx")
2555 (const_string "QI")))])
2557 (define_insn "*movqi_extzv_2"
2558 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2560 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2565 switch (get_attr_type (insn))
2568 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2570 return "mov{b}\t{%h1, %0|%0, %h1}";
2574 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2575 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2576 (ne (symbol_ref "TARGET_MOVX")
2578 (const_string "imovx")
2579 (const_string "imov")))
2581 (if_then_else (eq_attr "type" "imovx")
2583 (const_string "QI")))])
2585 (define_expand "mov<mode>_insv_1"
2586 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2589 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2591 (define_insn "*mov<mode>_insv_1_rex64"
2592 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2595 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2597 "mov{b}\t{%b1, %h0|%h0, %b1}"
2598 [(set_attr "type" "imov")
2599 (set_attr "mode" "QI")])
2601 (define_insn "*movsi_insv_1"
2602 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2605 (match_operand:SI 1 "general_operand" "Qmn"))]
2607 "mov{b}\t{%b1, %h0|%h0, %b1}"
2608 [(set_attr "type" "imov")
2609 (set_attr "mode" "QI")])
2611 (define_insn "*movqi_insv_2"
2612 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2615 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2618 "mov{b}\t{%h1, %h0|%h0, %h1}"
2619 [(set_attr "type" "imov")
2620 (set_attr "mode" "QI")])
2622 ;; Floating point push instructions.
2624 (define_insn "*pushtf"
2625 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2626 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2629 /* This insn should be already split before reg-stack. */
2632 [(set_attr "type" "multi")
2633 (set_attr "unit" "sse,*,*")
2634 (set_attr "mode" "TF,SI,SI")])
2637 [(set (match_operand:TF 0 "push_operand" "")
2638 (match_operand:TF 1 "sse_reg_operand" ""))]
2639 "TARGET_SSE2 && reload_completed"
2640 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2641 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2644 [(set (match_operand:TF 0 "push_operand" "")
2645 (match_operand:TF 1 "general_operand" ""))]
2646 "TARGET_SSE2 && reload_completed
2647 && !SSE_REG_P (operands[1])"
2649 "ix86_split_long_move (operands); DONE;")
2651 (define_insn "*pushxf"
2652 [(set (match_operand:XF 0 "push_operand" "=<,<")
2653 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2654 "optimize_function_for_speed_p (cfun)"
2656 /* This insn should be already split before reg-stack. */
2659 [(set_attr "type" "multi")
2660 (set_attr "unit" "i387,*")
2661 (set_attr "mode" "XF,SI")])
2663 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2664 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2665 ;; Pushing using integer instructions is longer except for constants
2666 ;; and direct memory references (assuming that any given constant is pushed
2667 ;; only once, but this ought to be handled elsewhere).
2669 (define_insn "*pushxf_nointeger"
2670 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2671 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2672 "optimize_function_for_size_p (cfun)"
2674 /* This insn should be already split before reg-stack. */
2677 [(set_attr "type" "multi")
2678 (set_attr "unit" "i387,*,*")
2679 (set_attr "mode" "XF,SI,SI")])
2682 [(set (match_operand:XF 0 "push_operand" "")
2683 (match_operand:XF 1 "fp_register_operand" ""))]
2685 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2686 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2687 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2690 [(set (match_operand:XF 0 "push_operand" "")
2691 (match_operand:XF 1 "general_operand" ""))]
2693 && !FP_REG_P (operands[1])"
2695 "ix86_split_long_move (operands); DONE;")
2697 (define_insn "*pushdf"
2698 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2699 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2700 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2702 /* This insn should be already split before reg-stack. */
2705 [(set_attr "type" "multi")
2706 (set_attr "unit" "i387,*,*")
2707 (set_attr "mode" "DF,SI,DF")])
2709 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2710 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2711 ;; On the average, pushdf using integers can be still shorter. Allow this
2712 ;; pattern for optimize_size too.
2714 (define_insn "*pushdf_nointeger"
2715 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2716 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2717 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2719 /* This insn should be already split before reg-stack. */
2722 [(set_attr "type" "multi")
2723 (set_attr "unit" "i387,*,*,*")
2724 (set_attr "mode" "DF,SI,SI,DF")])
2726 ;; %%% Kill this when call knows how to work this out.
2728 [(set (match_operand:DF 0 "push_operand" "")
2729 (match_operand:DF 1 "any_fp_register_operand" ""))]
2731 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2732 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2735 [(set (match_operand:DF 0 "push_operand" "")
2736 (match_operand:DF 1 "general_operand" ""))]
2738 && !ANY_FP_REG_P (operands[1])"
2740 "ix86_split_long_move (operands); DONE;")
2742 (define_insn "*pushsf_rex64"
2743 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2744 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2747 /* Anything else should be already split before reg-stack. */
2748 gcc_assert (which_alternative == 1);
2749 return "push{q}\t%q1";
2751 [(set_attr "type" "multi,push,multi")
2752 (set_attr "unit" "i387,*,*")
2753 (set_attr "mode" "SF,DI,SF")])
2755 (define_insn "*pushsf"
2756 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2757 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2760 /* Anything else should be already split before reg-stack. */
2761 gcc_assert (which_alternative == 1);
2762 return "push{l}\t%1";
2764 [(set_attr "type" "multi,push,multi")
2765 (set_attr "unit" "i387,*,*")
2766 (set_attr "mode" "SF,SI,SF")])
2769 [(set (match_operand:SF 0 "push_operand" "")
2770 (match_operand:SF 1 "memory_operand" ""))]
2772 && MEM_P (operands[1])
2773 && (operands[2] = find_constant_src (insn))"
2777 ;; %%% Kill this when call knows how to work this out.
2779 [(set (match_operand:SF 0 "push_operand" "")
2780 (match_operand:SF 1 "any_fp_register_operand" ""))]
2782 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2783 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2784 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2786 ;; Floating point move instructions.
2788 (define_expand "movtf"
2789 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2790 (match_operand:TF 1 "nonimmediate_operand" ""))]
2793 ix86_expand_move (TFmode, operands);
2797 (define_expand "mov<mode>"
2798 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2799 (match_operand:X87MODEF 1 "general_operand" ""))]
2801 "ix86_expand_move (<MODE>mode, operands); DONE;")
2803 (define_insn "*movtf_internal"
2804 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2805 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2809 switch (which_alternative)
2813 if (get_attr_mode (insn) == MODE_V4SF)
2814 return "%vmovaps\t{%1, %0|%0, %1}";
2816 return "%vmovdqa\t{%1, %0|%0, %1}";
2818 if (get_attr_mode (insn) == MODE_V4SF)
2819 return "%vxorps\t%0, %d0";
2821 return "%vpxor\t%0, %d0";
2829 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2830 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2832 (cond [(eq_attr "alternative" "0,2")
2834 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2836 (const_string "V4SF")
2837 (const_string "TI"))
2838 (eq_attr "alternative" "1")
2840 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2842 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2844 (const_string "V4SF")
2845 (const_string "TI"))]
2846 (const_string "DI")))])
2849 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2850 (match_operand:TF 1 "general_operand" ""))]
2852 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2854 "ix86_split_long_move (operands); DONE;")
2856 (define_insn "*movxf_internal"
2857 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2858 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2859 "optimize_function_for_speed_p (cfun)
2860 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2861 && (reload_in_progress || reload_completed
2862 || GET_CODE (operands[1]) != CONST_DOUBLE
2863 || memory_operand (operands[0], XFmode))"
2865 switch (which_alternative)
2869 return output_387_reg_move (insn, operands);
2872 return standard_80387_constant_opcode (operands[1]);
2881 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2882 (set_attr "mode" "XF,XF,XF,SI,SI")])
2884 ;; Do not use integer registers when optimizing for size
2885 (define_insn "*movxf_internal_nointeger"
2886 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2887 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2888 "optimize_function_for_size_p (cfun)
2889 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2890 && (reload_in_progress || reload_completed
2891 || standard_80387_constant_p (operands[1])
2892 || GET_CODE (operands[1]) != CONST_DOUBLE
2893 || memory_operand (operands[0], XFmode))"
2895 switch (which_alternative)
2899 return output_387_reg_move (insn, operands);
2902 return standard_80387_constant_opcode (operands[1]);
2910 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2911 (set_attr "mode" "XF,XF,XF,SI,SI")])
2914 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2915 (match_operand:XF 1 "general_operand" ""))]
2917 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2918 && ! (FP_REG_P (operands[0]) ||
2919 (GET_CODE (operands[0]) == SUBREG
2920 && FP_REG_P (SUBREG_REG (operands[0]))))
2921 && ! (FP_REG_P (operands[1]) ||
2922 (GET_CODE (operands[1]) == SUBREG
2923 && FP_REG_P (SUBREG_REG (operands[1]))))"
2925 "ix86_split_long_move (operands); DONE;")
2927 (define_insn "*movdf_internal_rex64"
2928 [(set (match_operand:DF 0 "nonimmediate_operand"
2929 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2930 (match_operand:DF 1 "general_operand"
2931 "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2932 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2933 && (reload_in_progress || reload_completed
2934 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2935 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2936 && optimize_function_for_size_p (cfun)
2937 && standard_80387_constant_p (operands[1]))
2938 || GET_CODE (operands[1]) != CONST_DOUBLE
2939 || memory_operand (operands[0], DFmode))"
2941 switch (which_alternative)
2945 return output_387_reg_move (insn, operands);
2948 return standard_80387_constant_opcode (operands[1]);
2952 return "mov{q}\t{%1, %0|%0, %1}";
2955 return "movabs{q}\t{%1, %0|%0, %1}";
2961 switch (get_attr_mode (insn))
2964 return "%vxorps\t%0, %d0";
2966 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2967 return "%vxorps\t%0, %d0";
2969 return "%vxorpd\t%0, %d0";
2971 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2972 return "%vxorps\t%0, %d0";
2974 return "%vpxor\t%0, %d0";
2981 switch (get_attr_mode (insn))
2984 return "%vmovaps\t{%1, %0|%0, %1}";
2986 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2987 return "%vmovaps\t{%1, %0|%0, %1}";
2989 return "%vmovapd\t{%1, %0|%0, %1}";
2991 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2992 return "%vmovaps\t{%1, %0|%0, %1}";
2994 return "%vmovdqa\t{%1, %0|%0, %1}";
2996 return "%vmovq\t{%1, %0|%0, %1}";
3000 if (REG_P (operands[0]) && REG_P (operands[1]))
3001 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3003 return "vmovsd\t{%1, %0|%0, %1}";
3006 return "movsd\t{%1, %0|%0, %1}";
3008 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3010 return "%vmovlps\t{%1, %d0|%d0, %1}";
3017 return "%vmovd\t{%1, %0|%0, %1}";
3023 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3026 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3028 (const_string "*")))
3029 (set (attr "length_immediate")
3031 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3033 (const_string "*")))
3034 (set (attr "prefix")
3035 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3036 (const_string "orig")
3037 (const_string "maybe_vex")))
3038 (set (attr "prefix_data16")
3039 (if_then_else (eq_attr "mode" "V1DF")
3041 (const_string "*")))
3043 (cond [(eq_attr "alternative" "0,1,2")
3045 (eq_attr "alternative" "3,4,5,6,11,12")
3048 /* For SSE1, we have many fewer alternatives. */
3049 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3050 (cond [(eq_attr "alternative" "7,8")
3051 (const_string "V4SF")
3053 (const_string "V2SF"))
3055 /* xorps is one byte shorter. */
3056 (eq_attr "alternative" "7")
3057 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3059 (const_string "V4SF")
3060 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3064 (const_string "V2DF"))
3066 /* For architectures resolving dependencies on
3067 whole SSE registers use APD move to break dependency
3068 chains, otherwise use short move to avoid extra work.
3070 movaps encodes one byte shorter. */
3071 (eq_attr "alternative" "8")
3073 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3075 (const_string "V4SF")
3076 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3078 (const_string "V2DF")
3080 (const_string "DF"))
3081 /* For architectures resolving dependencies on register
3082 parts we may avoid extra work to zero out upper part
3084 (eq_attr "alternative" "9")
3086 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3088 (const_string "V1DF")
3089 (const_string "DF"))
3091 (const_string "DF")))])
3093 (define_insn "*movdf_internal"
3094 [(set (match_operand:DF 0 "nonimmediate_operand"
3095 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3096 (match_operand:DF 1 "general_operand"
3097 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3098 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3099 && optimize_function_for_speed_p (cfun)
3100 && TARGET_INTEGER_DFMODE_MOVES
3101 && (reload_in_progress || reload_completed
3102 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3103 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3104 && optimize_function_for_size_p (cfun)
3105 && standard_80387_constant_p (operands[1]))
3106 || GET_CODE (operands[1]) != CONST_DOUBLE
3107 || memory_operand (operands[0], DFmode))"
3109 switch (which_alternative)
3113 return output_387_reg_move (insn, operands);
3116 return standard_80387_constant_opcode (operands[1]);
3123 switch (get_attr_mode (insn))
3126 return "xorps\t%0, %0";
3128 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3129 return "xorps\t%0, %0";
3131 return "xorpd\t%0, %0";
3133 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3134 return "xorps\t%0, %0";
3136 return "pxor\t%0, %0";
3143 switch (get_attr_mode (insn))
3146 return "movaps\t{%1, %0|%0, %1}";
3148 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3149 return "movaps\t{%1, %0|%0, %1}";
3151 return "movapd\t{%1, %0|%0, %1}";
3153 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3154 return "movaps\t{%1, %0|%0, %1}";
3156 return "movdqa\t{%1, %0|%0, %1}";
3158 return "movq\t{%1, %0|%0, %1}";
3160 return "movsd\t{%1, %0|%0, %1}";
3162 return "movlpd\t{%1, %0|%0, %1}";
3164 return "movlps\t{%1, %0|%0, %1}";
3173 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3174 (set (attr "prefix_data16")
3175 (if_then_else (eq_attr "mode" "V1DF")
3177 (const_string "*")))
3179 (cond [(eq_attr "alternative" "0,1,2")
3181 (eq_attr "alternative" "3,4")
3184 /* For SSE1, we have many fewer alternatives. */
3185 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3186 (cond [(eq_attr "alternative" "5,6")
3187 (const_string "V4SF")
3189 (const_string "V2SF"))
3191 /* xorps is one byte shorter. */
3192 (eq_attr "alternative" "5")
3193 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3195 (const_string "V4SF")
3196 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3200 (const_string "V2DF"))
3202 /* For architectures resolving dependencies on
3203 whole SSE registers use APD move to break dependency
3204 chains, otherwise use short move to avoid extra work.
3206 movaps encodes one byte shorter. */
3207 (eq_attr "alternative" "6")
3209 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3211 (const_string "V4SF")
3212 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3214 (const_string "V2DF")
3216 (const_string "DF"))
3217 /* For architectures resolving dependencies on register
3218 parts we may avoid extra work to zero out upper part
3220 (eq_attr "alternative" "7")
3222 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3224 (const_string "V1DF")
3225 (const_string "DF"))
3227 (const_string "DF")))])
3229 ;; Moving is usually shorter when only FP registers are used. This separate
3230 ;; movdf pattern avoids the use of integer registers for FP operations
3231 ;; when optimizing for size.
3233 (define_insn "*movdf_internal_nointeger"
3234 [(set (match_operand:DF 0 "nonimmediate_operand"
3235 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3236 (match_operand:DF 1 "general_operand"
3237 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3238 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3239 && (optimize_function_for_size_p (cfun)
3240 || !TARGET_INTEGER_DFMODE_MOVES)
3241 && (reload_in_progress || reload_completed
3242 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3243 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3244 && optimize_function_for_size_p (cfun)
3245 && !memory_operand (operands[0], DFmode)
3246 && standard_80387_constant_p (operands[1]))
3247 || GET_CODE (operands[1]) != CONST_DOUBLE
3248 || ((optimize_function_for_size_p (cfun)
3249 || !TARGET_MEMORY_MISMATCH_STALL
3250 || reload_in_progress || reload_completed)
3251 && memory_operand (operands[0], DFmode)))"
3253 switch (which_alternative)
3257 return output_387_reg_move (insn, operands);
3260 return standard_80387_constant_opcode (operands[1]);
3267 switch (get_attr_mode (insn))
3270 return "%vxorps\t%0, %d0";
3272 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3273 return "%vxorps\t%0, %d0";
3275 return "%vxorpd\t%0, %d0";
3277 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3278 return "%vxorps\t%0, %d0";
3280 return "%vpxor\t%0, %d0";
3287 switch (get_attr_mode (insn))
3290 return "%vmovaps\t{%1, %0|%0, %1}";
3292 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3293 return "%vmovaps\t{%1, %0|%0, %1}";
3295 return "%vmovapd\t{%1, %0|%0, %1}";
3297 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3298 return "%vmovaps\t{%1, %0|%0, %1}";
3300 return "%vmovdqa\t{%1, %0|%0, %1}";
3302 return "%vmovq\t{%1, %0|%0, %1}";
3306 if (REG_P (operands[0]) && REG_P (operands[1]))
3307 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3309 return "vmovsd\t{%1, %0|%0, %1}";
3312 return "movsd\t{%1, %0|%0, %1}";
3316 if (REG_P (operands[0]))
3317 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3319 return "vmovlpd\t{%1, %0|%0, %1}";
3322 return "movlpd\t{%1, %0|%0, %1}";
3326 if (REG_P (operands[0]))
3327 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3329 return "vmovlps\t{%1, %0|%0, %1}";
3332 return "movlps\t{%1, %0|%0, %1}";
3341 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3342 (set (attr "prefix")
3343 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3344 (const_string "orig")
3345 (const_string "maybe_vex")))
3346 (set (attr "prefix_data16")
3347 (if_then_else (eq_attr "mode" "V1DF")
3349 (const_string "*")))
3351 (cond [(eq_attr "alternative" "0,1,2")
3353 (eq_attr "alternative" "3,4")
3356 /* For SSE1, we have many fewer alternatives. */
3357 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3358 (cond [(eq_attr "alternative" "5,6")
3359 (const_string "V4SF")
3361 (const_string "V2SF"))
3363 /* xorps is one byte shorter. */
3364 (eq_attr "alternative" "5")
3365 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3367 (const_string "V4SF")
3368 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3372 (const_string "V2DF"))
3374 /* For architectures resolving dependencies on
3375 whole SSE registers use APD move to break dependency
3376 chains, otherwise use short move to avoid extra work.
3378 movaps encodes one byte shorter. */
3379 (eq_attr "alternative" "6")
3381 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3383 (const_string "V4SF")
3384 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3386 (const_string "V2DF")
3388 (const_string "DF"))
3389 /* For architectures resolving dependencies on register
3390 parts we may avoid extra work to zero out upper part
3392 (eq_attr "alternative" "7")
3394 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3396 (const_string "V1DF")
3397 (const_string "DF"))
3399 (const_string "DF")))])
3402 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3403 (match_operand:DF 1 "general_operand" ""))]
3405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3406 && ! (ANY_FP_REG_P (operands[0]) ||
3407 (GET_CODE (operands[0]) == SUBREG
3408 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3409 && ! (ANY_FP_REG_P (operands[1]) ||
3410 (GET_CODE (operands[1]) == SUBREG
3411 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3413 "ix86_split_long_move (operands); DONE;")
3415 (define_insn "*movsf_internal"
3416 [(set (match_operand:SF 0 "nonimmediate_operand"
3417 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3418 (match_operand:SF 1 "general_operand"
3419 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3420 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3421 && (reload_in_progress || reload_completed
3422 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3423 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3424 && standard_80387_constant_p (operands[1]))
3425 || GET_CODE (operands[1]) != CONST_DOUBLE
3426 || memory_operand (operands[0], SFmode))"
3428 switch (which_alternative)
3432 return output_387_reg_move (insn, operands);
3435 return standard_80387_constant_opcode (operands[1]);
3439 return "mov{l}\t{%1, %0|%0, %1}";
3441 if (get_attr_mode (insn) == MODE_TI)
3442 return "%vpxor\t%0, %d0";
3444 return "%vxorps\t%0, %d0";
3446 if (get_attr_mode (insn) == MODE_V4SF)
3447 return "%vmovaps\t{%1, %0|%0, %1}";
3449 return "%vmovss\t{%1, %d0|%d0, %1}";
3452 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3453 : "vmovss\t{%1, %0|%0, %1}";
3455 return "movss\t{%1, %0|%0, %1}";
3457 return "%vmovss\t{%1, %0|%0, %1}";
3459 case 9: case 10: case 14: case 15:
3460 return "movd\t{%1, %0|%0, %1}";
3462 return "%vmovd\t{%1, %0|%0, %1}";
3465 return "movq\t{%1, %0|%0, %1}";
3471 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3472 (set (attr "prefix")
3473 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3474 (const_string "maybe_vex")
3475 (const_string "orig")))
3477 (cond [(eq_attr "alternative" "3,4,9,10")
3479 (eq_attr "alternative" "5")
3481 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3483 (ne (symbol_ref "TARGET_SSE2")
3485 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3488 (const_string "V4SF"))
3489 /* For architectures resolving dependencies on
3490 whole SSE registers use APS move to break dependency
3491 chains, otherwise use short move to avoid extra work.
3493 Do the same for architectures resolving dependencies on
3494 the parts. While in DF mode it is better to always handle
3495 just register parts, the SF mode is different due to lack
3496 of instructions to load just part of the register. It is
3497 better to maintain the whole registers in single format
3498 to avoid problems on using packed logical operations. */
3499 (eq_attr "alternative" "6")
3501 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3503 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3505 (const_string "V4SF")
3506 (const_string "SF"))
3507 (eq_attr "alternative" "11")
3508 (const_string "DI")]
3509 (const_string "SF")))])
3512 [(set (match_operand 0 "register_operand" "")
3513 (match_operand 1 "memory_operand" ""))]
3515 && MEM_P (operands[1])
3516 && (GET_MODE (operands[0]) == TFmode
3517 || GET_MODE (operands[0]) == XFmode
3518 || GET_MODE (operands[0]) == DFmode
3519 || GET_MODE (operands[0]) == SFmode)
3520 && (operands[2] = find_constant_src (insn))"
3521 [(set (match_dup 0) (match_dup 2))]
3523 rtx c = operands[2];
3524 rtx r = operands[0];
3526 if (GET_CODE (r) == SUBREG)
3531 if (!standard_sse_constant_p (c))
3534 else if (FP_REG_P (r))
3536 if (!standard_80387_constant_p (c))
3539 else if (MMX_REG_P (r))
3544 [(set (match_operand 0 "register_operand" "")
3545 (float_extend (match_operand 1 "memory_operand" "")))]
3547 && MEM_P (operands[1])
3548 && (GET_MODE (operands[0]) == TFmode
3549 || GET_MODE (operands[0]) == XFmode
3550 || GET_MODE (operands[0]) == DFmode
3551 || GET_MODE (operands[0]) == SFmode)
3552 && (operands[2] = find_constant_src (insn))"
3553 [(set (match_dup 0) (match_dup 2))]
3555 rtx c = operands[2];
3556 rtx r = operands[0];
3558 if (GET_CODE (r) == SUBREG)
3563 if (!standard_sse_constant_p (c))
3566 else if (FP_REG_P (r))
3568 if (!standard_80387_constant_p (c))
3571 else if (MMX_REG_P (r))
3575 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3577 [(set (match_operand:X87MODEF 0 "register_operand" "")
3578 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3579 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3580 && (standard_80387_constant_p (operands[1]) == 8
3581 || standard_80387_constant_p (operands[1]) == 9)"
3582 [(set (match_dup 0)(match_dup 1))
3584 (neg:X87MODEF (match_dup 0)))]
3588 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3589 if (real_isnegzero (&r))
3590 operands[1] = CONST0_RTX (<MODE>mode);
3592 operands[1] = CONST1_RTX (<MODE>mode);
3595 (define_insn "swapxf"
3596 [(set (match_operand:XF 0 "register_operand" "+f")
3597 (match_operand:XF 1 "register_operand" "+f"))
3602 if (STACK_TOP_P (operands[0]))
3607 [(set_attr "type" "fxch")
3608 (set_attr "mode" "XF")])
3610 (define_insn "*swap<mode>"
3611 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3612 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3615 "TARGET_80387 || reload_completed"
3617 if (STACK_TOP_P (operands[0]))
3622 [(set_attr "type" "fxch")
3623 (set_attr "mode" "<MODE>")])
3625 ;; Zero extension instructions
3627 (define_expand "zero_extendsidi2"
3628 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3629 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3634 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3639 (define_insn "*zero_extendsidi2_rex64"
3640 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3642 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3645 mov\t{%k1, %k0|%k0, %k1}
3647 movd\t{%1, %0|%0, %1}
3648 movd\t{%1, %0|%0, %1}
3649 %vmovd\t{%1, %0|%0, %1}
3650 %vmovd\t{%1, %0|%0, %1}"
3651 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3652 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3653 (set_attr "prefix_0f" "0,*,*,*,*,*")
3654 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3657 [(set (match_operand:DI 0 "memory_operand" "")
3658 (zero_extend:DI (match_dup 0)))]
3660 [(set (match_dup 4) (const_int 0))]
3661 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3663 ;; %%% Kill me once multi-word ops are sane.
3664 (define_insn "zero_extendsidi2_1"
3665 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3667 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3668 (clobber (reg:CC FLAGS_REG))]
3674 movd\t{%1, %0|%0, %1}
3675 movd\t{%1, %0|%0, %1}
3676 %vmovd\t{%1, %0|%0, %1}
3677 %vmovd\t{%1, %0|%0, %1}"
3678 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3679 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3680 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3683 [(set (match_operand:DI 0 "register_operand" "")
3684 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3685 (clobber (reg:CC FLAGS_REG))]
3686 "!TARGET_64BIT && reload_completed
3687 && true_regnum (operands[0]) == true_regnum (operands[1])"
3688 [(set (match_dup 4) (const_int 0))]
3689 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3692 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3693 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3694 (clobber (reg:CC FLAGS_REG))]
3695 "!TARGET_64BIT && reload_completed
3696 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3697 [(set (match_dup 3) (match_dup 1))
3698 (set (match_dup 4) (const_int 0))]
3699 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3701 (define_insn "zero_extend<mode>di2"
3702 [(set (match_operand:DI 0 "register_operand" "=r")
3704 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3706 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3707 [(set_attr "type" "imovx")
3708 (set_attr "mode" "SI")])
3710 (define_expand "zero_extendhisi2"
3711 [(set (match_operand:SI 0 "register_operand" "")
3712 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3715 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3717 operands[1] = force_reg (HImode, operands[1]);
3718 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3723 (define_insn_and_split "zero_extendhisi2_and"
3724 [(set (match_operand:SI 0 "register_operand" "=r")
3725 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3726 (clobber (reg:CC FLAGS_REG))]
3727 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3729 "&& reload_completed"
3730 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3731 (clobber (reg:CC FLAGS_REG))])]
3733 [(set_attr "type" "alu1")
3734 (set_attr "mode" "SI")])
3736 (define_insn "*zero_extendhisi2_movzwl"
3737 [(set (match_operand:SI 0 "register_operand" "=r")
3738 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3739 "!TARGET_ZERO_EXTEND_WITH_AND
3740 || optimize_function_for_size_p (cfun)"
3741 "movz{wl|x}\t{%1, %0|%0, %1}"
3742 [(set_attr "type" "imovx")
3743 (set_attr "mode" "SI")])
3745 (define_expand "zero_extendqi<mode>2"
3747 [(set (match_operand:SWI24 0 "register_operand" "")
3748 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3749 (clobber (reg:CC FLAGS_REG))])])
3751 (define_insn "*zero_extendqi<mode>2_and"
3752 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3753 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3754 (clobber (reg:CC FLAGS_REG))]
3755 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3757 [(set_attr "type" "alu1")
3758 (set_attr "mode" "<MODE>")])
3760 ;; When source and destination does not overlap, clear destination
3761 ;; first and then do the movb
3763 [(set (match_operand:SWI24 0 "register_operand" "")
3764 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3765 (clobber (reg:CC FLAGS_REG))]
3767 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3768 && ANY_QI_REG_P (operands[0])
3769 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3770 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3771 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3773 operands[2] = gen_lowpart (QImode, operands[0]);
3774 ix86_expand_clear (operands[0]);
3777 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3778 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3779 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3780 (clobber (reg:CC FLAGS_REG))]
3781 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3783 [(set_attr "type" "imovx,alu1")
3784 (set_attr "mode" "<MODE>")])
3786 ;; For the movzbl case strip only the clobber
3788 [(set (match_operand:SWI24 0 "register_operand" "")
3789 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3790 (clobber (reg:CC FLAGS_REG))]
3792 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3793 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3795 (zero_extend:SWI24 (match_dup 1)))])
3797 ; zero extend to SImode to avoid partial register stalls
3798 (define_insn "*zero_extendqi<mode>2_movzbl"
3799 [(set (match_operand:SWI24 0 "register_operand" "=r")
3800 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3802 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3803 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3804 [(set_attr "type" "imovx")
3805 (set_attr "mode" "SI")])
3807 ;; Rest is handled by single and.
3809 [(set (match_operand:SWI24 0 "register_operand" "")
3810 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3811 (clobber (reg:CC FLAGS_REG))]
3813 && true_regnum (operands[0]) == true_regnum (operands[1])"
3814 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3815 (clobber (reg:CC FLAGS_REG))])])
3817 ;; Sign extension instructions
3819 (define_expand "extendsidi2"
3820 [(set (match_operand:DI 0 "register_operand" "")
3821 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3826 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3831 (define_insn "*extendsidi2_rex64"
3832 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3833 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3837 movs{lq|x}\t{%1, %0|%0, %1}"
3838 [(set_attr "type" "imovx")
3839 (set_attr "mode" "DI")
3840 (set_attr "prefix_0f" "0")
3841 (set_attr "modrm" "0,1")])
3843 (define_insn "extendsidi2_1"
3844 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3845 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3846 (clobber (reg:CC FLAGS_REG))
3847 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3851 ;; Extend to memory case when source register does die.
3853 [(set (match_operand:DI 0 "memory_operand" "")
3854 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3855 (clobber (reg:CC FLAGS_REG))
3856 (clobber (match_operand:SI 2 "register_operand" ""))]
3858 && dead_or_set_p (insn, operands[1])
3859 && !reg_mentioned_p (operands[1], operands[0]))"
3860 [(set (match_dup 3) (match_dup 1))
3861 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3862 (clobber (reg:CC FLAGS_REG))])
3863 (set (match_dup 4) (match_dup 1))]
3864 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3866 ;; Extend to memory case when source register does not die.
3868 [(set (match_operand:DI 0 "memory_operand" "")
3869 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3870 (clobber (reg:CC FLAGS_REG))
3871 (clobber (match_operand:SI 2 "register_operand" ""))]
3875 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3877 emit_move_insn (operands[3], operands[1]);
3879 /* Generate a cltd if possible and doing so it profitable. */
3880 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3881 && true_regnum (operands[1]) == AX_REG
3882 && true_regnum (operands[2]) == DX_REG)
3884 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3888 emit_move_insn (operands[2], operands[1]);
3889 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3891 emit_move_insn (operands[4], operands[2]);
3895 ;; Extend to register case. Optimize case where source and destination
3896 ;; registers match and cases where we can use cltd.
3898 [(set (match_operand:DI 0 "register_operand" "")
3899 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3900 (clobber (reg:CC FLAGS_REG))
3901 (clobber (match_scratch:SI 2 ""))]
3905 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3907 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3908 emit_move_insn (operands[3], operands[1]);
3910 /* Generate a cltd if possible and doing so it profitable. */
3911 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3912 && true_regnum (operands[3]) == AX_REG
3913 && true_regnum (operands[4]) == DX_REG)
3915 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3919 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3920 emit_move_insn (operands[4], operands[1]);
3922 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3926 (define_insn "extend<mode>di2"
3927 [(set (match_operand:DI 0 "register_operand" "=r")
3929 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3931 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3932 [(set_attr "type" "imovx")
3933 (set_attr "mode" "DI")])
3935 (define_insn "extendhisi2"
3936 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3937 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3940 switch (get_attr_prefix_0f (insn))
3943 return "{cwtl|cwde}";
3945 return "movs{wl|x}\t{%1, %0|%0, %1}";
3948 [(set_attr "type" "imovx")
3949 (set_attr "mode" "SI")
3950 (set (attr "prefix_0f")
3951 ;; movsx is short decodable while cwtl is vector decoded.
3952 (if_then_else (and (eq_attr "cpu" "!k6")
3953 (eq_attr "alternative" "0"))
3955 (const_string "1")))
3957 (if_then_else (eq_attr "prefix_0f" "0")
3959 (const_string "1")))])
3961 (define_insn "*extendhisi2_zext"
3962 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3965 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3968 switch (get_attr_prefix_0f (insn))
3971 return "{cwtl|cwde}";
3973 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3976 [(set_attr "type" "imovx")
3977 (set_attr "mode" "SI")
3978 (set (attr "prefix_0f")
3979 ;; movsx is short decodable while cwtl is vector decoded.
3980 (if_then_else (and (eq_attr "cpu" "!k6")
3981 (eq_attr "alternative" "0"))
3983 (const_string "1")))
3985 (if_then_else (eq_attr "prefix_0f" "0")
3987 (const_string "1")))])
3989 (define_insn "extendqisi2"
3990 [(set (match_operand:SI 0 "register_operand" "=r")
3991 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3993 "movs{bl|x}\t{%1, %0|%0, %1}"
3994 [(set_attr "type" "imovx")
3995 (set_attr "mode" "SI")])
3997 (define_insn "*extendqisi2_zext"
3998 [(set (match_operand:DI 0 "register_operand" "=r")
4000 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4002 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4003 [(set_attr "type" "imovx")
4004 (set_attr "mode" "SI")])
4006 (define_insn "extendqihi2"
4007 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4008 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4011 switch (get_attr_prefix_0f (insn))
4014 return "{cbtw|cbw}";
4016 return "movs{bw|x}\t{%1, %0|%0, %1}";
4019 [(set_attr "type" "imovx")
4020 (set_attr "mode" "HI")
4021 (set (attr "prefix_0f")
4022 ;; movsx is short decodable while cwtl is vector decoded.
4023 (if_then_else (and (eq_attr "cpu" "!k6")
4024 (eq_attr "alternative" "0"))
4026 (const_string "1")))
4028 (if_then_else (eq_attr "prefix_0f" "0")
4030 (const_string "1")))])
4032 ;; Conversions between float and double.
4034 ;; These are all no-ops in the model used for the 80387.
4035 ;; So just emit moves.
4037 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4039 [(set (match_operand:DF 0 "push_operand" "")
4040 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4042 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4043 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4046 [(set (match_operand:XF 0 "push_operand" "")
4047 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4049 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4050 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4051 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4053 (define_expand "extendsfdf2"
4054 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4055 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4056 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4058 /* ??? Needed for compress_float_constant since all fp constants
4059 are TARGET_LEGITIMATE_CONSTANT_P. */
4060 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4062 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4063 && standard_80387_constant_p (operands[1]) > 0)
4065 operands[1] = simplify_const_unary_operation
4066 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4067 emit_move_insn_1 (operands[0], operands[1]);
4070 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4074 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4076 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4078 We do the conversion post reload to avoid producing of 128bit spills
4079 that might lead to ICE on 32bit target. The sequence unlikely combine
4082 [(set (match_operand:DF 0 "register_operand" "")
4084 (match_operand:SF 1 "nonimmediate_operand" "")))]
4085 "TARGET_USE_VECTOR_FP_CONVERTS
4086 && optimize_insn_for_speed_p ()
4087 && reload_completed && SSE_REG_P (operands[0])"
4092 (parallel [(const_int 0) (const_int 1)]))))]
4094 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4095 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4096 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4097 Try to avoid move when unpacking can be done in source. */
4098 if (REG_P (operands[1]))
4100 /* If it is unsafe to overwrite upper half of source, we need
4101 to move to destination and unpack there. */
4102 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4103 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4104 && true_regnum (operands[0]) != true_regnum (operands[1]))
4106 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4107 emit_move_insn (tmp, operands[1]);
4110 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4111 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4115 emit_insn (gen_vec_setv4sf_0 (operands[3],
4116 CONST0_RTX (V4SFmode), operands[1]));
4119 (define_insn "*extendsfdf2_mixed"
4120 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4122 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4123 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4125 switch (which_alternative)
4129 return output_387_reg_move (insn, operands);
4132 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4138 [(set_attr "type" "fmov,fmov,ssecvt")
4139 (set_attr "prefix" "orig,orig,maybe_vex")
4140 (set_attr "mode" "SF,XF,DF")])
4142 (define_insn "*extendsfdf2_sse"
4143 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4144 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4145 "TARGET_SSE2 && TARGET_SSE_MATH"
4146 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4147 [(set_attr "type" "ssecvt")
4148 (set_attr "prefix" "maybe_vex")
4149 (set_attr "mode" "DF")])
4151 (define_insn "*extendsfdf2_i387"
4152 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4153 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4155 "* return output_387_reg_move (insn, operands);"
4156 [(set_attr "type" "fmov")
4157 (set_attr "mode" "SF,XF")])
4159 (define_expand "extend<mode>xf2"
4160 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4161 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4164 /* ??? Needed for compress_float_constant since all fp constants
4165 are TARGET_LEGITIMATE_CONSTANT_P. */
4166 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4168 if (standard_80387_constant_p (operands[1]) > 0)
4170 operands[1] = simplify_const_unary_operation
4171 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4172 emit_move_insn_1 (operands[0], operands[1]);
4175 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4179 (define_insn "*extend<mode>xf2_i387"
4180 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4182 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4184 "* return output_387_reg_move (insn, operands);"
4185 [(set_attr "type" "fmov")
4186 (set_attr "mode" "<MODE>,XF")])
4188 ;; %%% This seems bad bad news.
4189 ;; This cannot output into an f-reg because there is no way to be sure
4190 ;; of truncating in that case. Otherwise this is just like a simple move
4191 ;; insn. So we pretend we can output to a reg in order to get better
4192 ;; register preferencing, but we really use a stack slot.
4194 ;; Conversion from DFmode to SFmode.
4196 (define_expand "truncdfsf2"
4197 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4199 (match_operand:DF 1 "nonimmediate_operand" "")))]
4200 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4202 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4204 else if (flag_unsafe_math_optimizations)
4208 enum ix86_stack_slot slot = (virtuals_instantiated
4211 rtx temp = assign_386_stack_local (SFmode, slot);
4212 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4217 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4219 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4221 We do the conversion post reload to avoid producing of 128bit spills
4222 that might lead to ICE on 32bit target. The sequence unlikely combine
4225 [(set (match_operand:SF 0 "register_operand" "")
4227 (match_operand:DF 1 "nonimmediate_operand" "")))]
4228 "TARGET_USE_VECTOR_FP_CONVERTS
4229 && optimize_insn_for_speed_p ()
4230 && reload_completed && SSE_REG_P (operands[0])"
4233 (float_truncate:V2SF
4237 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4238 operands[3] = CONST0_RTX (V2SFmode);
4239 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4240 /* Use movsd for loading from memory, unpcklpd for registers.
4241 Try to avoid move when unpacking can be done in source, or SSE3
4242 movddup is available. */
4243 if (REG_P (operands[1]))
4246 && true_regnum (operands[0]) != true_regnum (operands[1])
4247 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4248 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4250 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4251 emit_move_insn (tmp, operands[1]);
4254 else if (!TARGET_SSE3)
4255 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4256 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4259 emit_insn (gen_sse2_loadlpd (operands[4],
4260 CONST0_RTX (V2DFmode), operands[1]));
4263 (define_expand "truncdfsf2_with_temp"
4264 [(parallel [(set (match_operand:SF 0 "" "")
4265 (float_truncate:SF (match_operand:DF 1 "" "")))
4266 (clobber (match_operand:SF 2 "" ""))])])
4268 (define_insn "*truncdfsf_fast_mixed"
4269 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4271 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4272 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4274 switch (which_alternative)
4277 return output_387_reg_move (insn, operands);
4279 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4284 [(set_attr "type" "fmov,ssecvt")
4285 (set_attr "prefix" "orig,maybe_vex")
4286 (set_attr "mode" "SF")])
4288 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4289 ;; because nothing we do here is unsafe.
4290 (define_insn "*truncdfsf_fast_sse"
4291 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4293 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4294 "TARGET_SSE2 && TARGET_SSE_MATH"
4295 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4296 [(set_attr "type" "ssecvt")
4297 (set_attr "prefix" "maybe_vex")
4298 (set_attr "mode" "SF")])
4300 (define_insn "*truncdfsf_fast_i387"
4301 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4303 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4304 "TARGET_80387 && flag_unsafe_math_optimizations"
4305 "* return output_387_reg_move (insn, operands);"
4306 [(set_attr "type" "fmov")
4307 (set_attr "mode" "SF")])
4309 (define_insn "*truncdfsf_mixed"
4310 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4312 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4313 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4314 "TARGET_MIX_SSE_I387"
4316 switch (which_alternative)
4319 return output_387_reg_move (insn, operands);
4321 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4327 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4328 (set_attr "unit" "*,*,i387,i387,i387")
4329 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4330 (set_attr "mode" "SF")])
4332 (define_insn "*truncdfsf_i387"
4333 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4335 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4336 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4339 switch (which_alternative)
4342 return output_387_reg_move (insn, operands);
4348 [(set_attr "type" "fmov,multi,multi,multi")
4349 (set_attr "unit" "*,i387,i387,i387")
4350 (set_attr "mode" "SF")])
4352 (define_insn "*truncdfsf2_i387_1"
4353 [(set (match_operand:SF 0 "memory_operand" "=m")
4355 (match_operand:DF 1 "register_operand" "f")))]
4357 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4358 && !TARGET_MIX_SSE_I387"
4359 "* return output_387_reg_move (insn, operands);"
4360 [(set_attr "type" "fmov")
4361 (set_attr "mode" "SF")])
4364 [(set (match_operand:SF 0 "register_operand" "")
4366 (match_operand:DF 1 "fp_register_operand" "")))
4367 (clobber (match_operand 2 "" ""))]
4369 [(set (match_dup 2) (match_dup 1))
4370 (set (match_dup 0) (match_dup 2))]
4371 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4373 ;; Conversion from XFmode to {SF,DF}mode
4375 (define_expand "truncxf<mode>2"
4376 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4377 (float_truncate:MODEF
4378 (match_operand:XF 1 "register_operand" "")))
4379 (clobber (match_dup 2))])]
4382 if (flag_unsafe_math_optimizations)
4384 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4385 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4386 if (reg != operands[0])
4387 emit_move_insn (operands[0], reg);
4392 enum ix86_stack_slot slot = (virtuals_instantiated
4395 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4399 (define_insn "*truncxfsf2_mixed"
4400 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4402 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4403 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4406 gcc_assert (!which_alternative);
4407 return output_387_reg_move (insn, operands);
4409 [(set_attr "type" "fmov,multi,multi,multi")
4410 (set_attr "unit" "*,i387,i387,i387")
4411 (set_attr "mode" "SF")])
4413 (define_insn "*truncxfdf2_mixed"
4414 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4416 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4417 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4420 gcc_assert (!which_alternative);
4421 return output_387_reg_move (insn, operands);
4423 [(set_attr "type" "fmov,multi,multi,multi")
4424 (set_attr "unit" "*,i387,i387,i387")
4425 (set_attr "mode" "DF")])
4427 (define_insn "truncxf<mode>2_i387_noop"
4428 [(set (match_operand:MODEF 0 "register_operand" "=f")
4429 (float_truncate:MODEF
4430 (match_operand:XF 1 "register_operand" "f")))]
4431 "TARGET_80387 && flag_unsafe_math_optimizations"
4432 "* return output_387_reg_move (insn, operands);"
4433 [(set_attr "type" "fmov")
4434 (set_attr "mode" "<MODE>")])
4436 (define_insn "*truncxf<mode>2_i387"
4437 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4438 (float_truncate:MODEF
4439 (match_operand:XF 1 "register_operand" "f")))]
4441 "* return output_387_reg_move (insn, operands);"
4442 [(set_attr "type" "fmov")
4443 (set_attr "mode" "<MODE>")])
4446 [(set (match_operand:MODEF 0 "register_operand" "")
4447 (float_truncate:MODEF
4448 (match_operand:XF 1 "register_operand" "")))
4449 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4450 "TARGET_80387 && reload_completed"
4451 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4452 (set (match_dup 0) (match_dup 2))])
4455 [(set (match_operand:MODEF 0 "memory_operand" "")
4456 (float_truncate:MODEF
4457 (match_operand:XF 1 "register_operand" "")))
4458 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4460 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4462 ;; Signed conversion to DImode.
4464 (define_expand "fix_truncxfdi2"
4465 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4466 (fix:DI (match_operand:XF 1 "register_operand" "")))
4467 (clobber (reg:CC FLAGS_REG))])]
4472 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4477 (define_expand "fix_trunc<mode>di2"
4478 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4479 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4480 (clobber (reg:CC FLAGS_REG))])]
4481 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4484 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4486 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4489 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4491 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4492 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4493 if (out != operands[0])
4494 emit_move_insn (operands[0], out);
4499 ;; Signed conversion to SImode.
4501 (define_expand "fix_truncxfsi2"
4502 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4503 (fix:SI (match_operand:XF 1 "register_operand" "")))
4504 (clobber (reg:CC FLAGS_REG))])]
4509 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4514 (define_expand "fix_trunc<mode>si2"
4515 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4516 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4517 (clobber (reg:CC FLAGS_REG))])]
4518 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4521 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4523 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4526 if (SSE_FLOAT_MODE_P (<MODE>mode))
4528 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4529 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4530 if (out != operands[0])
4531 emit_move_insn (operands[0], out);
4536 ;; Signed conversion to HImode.
4538 (define_expand "fix_trunc<mode>hi2"
4539 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4540 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4541 (clobber (reg:CC FLAGS_REG))])]
4543 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4547 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4552 ;; Unsigned conversion to SImode.
4554 (define_expand "fixuns_trunc<mode>si2"
4556 [(set (match_operand:SI 0 "register_operand" "")
4558 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4560 (clobber (match_scratch:<ssevecmode> 3 ""))
4561 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4562 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4564 enum machine_mode mode = <MODE>mode;
4565 enum machine_mode vecmode = <ssevecmode>mode;
4566 REAL_VALUE_TYPE TWO31r;
4569 if (optimize_insn_for_size_p ())
4572 real_ldexp (&TWO31r, &dconst1, 31);
4573 two31 = const_double_from_real_value (TWO31r, mode);
4574 two31 = ix86_build_const_vector (vecmode, true, two31);
4575 operands[2] = force_reg (vecmode, two31);
4578 (define_insn_and_split "*fixuns_trunc<mode>_1"
4579 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4581 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4582 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4583 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4584 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4585 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4586 && optimize_function_for_speed_p (cfun)"
4588 "&& reload_completed"
4591 ix86_split_convert_uns_si_sse (operands);
4595 ;; Unsigned conversion to HImode.
4596 ;; Without these patterns, we'll try the unsigned SI conversion which
4597 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4599 (define_expand "fixuns_trunc<mode>hi2"
4601 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4602 (set (match_operand:HI 0 "nonimmediate_operand" "")
4603 (subreg:HI (match_dup 2) 0))]
4604 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4605 "operands[2] = gen_reg_rtx (SImode);")
4607 ;; When SSE is available, it is always faster to use it!
4608 (define_insn "fix_trunc<mode>di_sse"
4609 [(set (match_operand:DI 0 "register_operand" "=r,r")
4610 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4611 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4612 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4613 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4614 [(set_attr "type" "sseicvt")
4615 (set_attr "prefix" "maybe_vex")
4616 (set_attr "prefix_rex" "1")
4617 (set_attr "mode" "<MODE>")
4618 (set_attr "athlon_decode" "double,vector")
4619 (set_attr "amdfam10_decode" "double,double")
4620 (set_attr "bdver1_decode" "double,double")])
4622 (define_insn "fix_trunc<mode>si_sse"
4623 [(set (match_operand:SI 0 "register_operand" "=r,r")
4624 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4625 "SSE_FLOAT_MODE_P (<MODE>mode)
4626 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4627 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4628 [(set_attr "type" "sseicvt")
4629 (set_attr "prefix" "maybe_vex")
4630 (set_attr "mode" "<MODE>")
4631 (set_attr "athlon_decode" "double,vector")
4632 (set_attr "amdfam10_decode" "double,double")
4633 (set_attr "bdver1_decode" "double,double")])
4635 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4637 [(set (match_operand:MODEF 0 "register_operand" "")
4638 (match_operand:MODEF 1 "memory_operand" ""))
4639 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4640 (fix:SSEMODEI24 (match_dup 0)))]
4641 "TARGET_SHORTEN_X87_SSE
4642 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4643 && peep2_reg_dead_p (2, operands[0])"
4644 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4646 ;; Avoid vector decoded forms of the instruction.
4648 [(match_scratch:DF 2 "Y2")
4649 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4650 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4651 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4652 [(set (match_dup 2) (match_dup 1))
4653 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4656 [(match_scratch:SF 2 "x")
4657 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4658 (fix:SSEMODEI24 (match_operand:SF 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)))])
4663 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4664 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4665 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4666 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4668 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4669 && (TARGET_64BIT || <MODE>mode != DImode))
4671 && can_create_pseudo_p ()"
4676 if (memory_operand (operands[0], VOIDmode))
4677 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4680 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4681 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4687 [(set_attr "type" "fisttp")
4688 (set_attr "mode" "<MODE>")])
4690 (define_insn "fix_trunc<mode>_i387_fisttp"
4691 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4692 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4693 (clobber (match_scratch:XF 2 "=&1f"))]
4694 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4696 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4697 && (TARGET_64BIT || <MODE>mode != DImode))
4698 && TARGET_SSE_MATH)"
4699 "* return output_fix_trunc (insn, operands, 1);"
4700 [(set_attr "type" "fisttp")
4701 (set_attr "mode" "<MODE>")])
4703 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4704 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4705 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4706 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4707 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4708 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4710 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4711 && (TARGET_64BIT || <MODE>mode != DImode))
4712 && TARGET_SSE_MATH)"
4714 [(set_attr "type" "fisttp")
4715 (set_attr "mode" "<MODE>")])
4718 [(set (match_operand:X87MODEI 0 "register_operand" "")
4719 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4720 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4721 (clobber (match_scratch 3 ""))]
4723 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4724 (clobber (match_dup 3))])
4725 (set (match_dup 0) (match_dup 2))])
4728 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4729 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4730 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4731 (clobber (match_scratch 3 ""))]
4733 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4734 (clobber (match_dup 3))])])
4736 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4737 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4738 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4739 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4740 ;; function in i386.c.
4741 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4742 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4743 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4744 (clobber (reg:CC FLAGS_REG))]
4745 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4747 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4748 && (TARGET_64BIT || <MODE>mode != DImode))
4749 && can_create_pseudo_p ()"
4754 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4756 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4757 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4758 if (memory_operand (operands[0], VOIDmode))
4759 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4760 operands[2], operands[3]));
4763 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4764 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4765 operands[2], operands[3],
4770 [(set_attr "type" "fistp")
4771 (set_attr "i387_cw" "trunc")
4772 (set_attr "mode" "<MODE>")])
4774 (define_insn "fix_truncdi_i387"
4775 [(set (match_operand:DI 0 "memory_operand" "=m")
4776 (fix:DI (match_operand 1 "register_operand" "f")))
4777 (use (match_operand:HI 2 "memory_operand" "m"))
4778 (use (match_operand:HI 3 "memory_operand" "m"))
4779 (clobber (match_scratch:XF 4 "=&1f"))]
4780 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4782 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4783 "* return output_fix_trunc (insn, operands, 0);"
4784 [(set_attr "type" "fistp")
4785 (set_attr "i387_cw" "trunc")
4786 (set_attr "mode" "DI")])
4788 (define_insn "fix_truncdi_i387_with_temp"
4789 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4790 (fix:DI (match_operand 1 "register_operand" "f,f")))
4791 (use (match_operand:HI 2 "memory_operand" "m,m"))
4792 (use (match_operand:HI 3 "memory_operand" "m,m"))
4793 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4794 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4795 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4797 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4799 [(set_attr "type" "fistp")
4800 (set_attr "i387_cw" "trunc")
4801 (set_attr "mode" "DI")])
4804 [(set (match_operand:DI 0 "register_operand" "")
4805 (fix:DI (match_operand 1 "register_operand" "")))
4806 (use (match_operand:HI 2 "memory_operand" ""))
4807 (use (match_operand:HI 3 "memory_operand" ""))
4808 (clobber (match_operand:DI 4 "memory_operand" ""))
4809 (clobber (match_scratch 5 ""))]
4811 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4814 (clobber (match_dup 5))])
4815 (set (match_dup 0) (match_dup 4))])
4818 [(set (match_operand:DI 0 "memory_operand" "")
4819 (fix:DI (match_operand 1 "register_operand" "")))
4820 (use (match_operand:HI 2 "memory_operand" ""))
4821 (use (match_operand:HI 3 "memory_operand" ""))
4822 (clobber (match_operand:DI 4 "memory_operand" ""))
4823 (clobber (match_scratch 5 ""))]
4825 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4828 (clobber (match_dup 5))])])
4830 (define_insn "fix_trunc<mode>_i387"
4831 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4832 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4833 (use (match_operand:HI 2 "memory_operand" "m"))
4834 (use (match_operand:HI 3 "memory_operand" "m"))]
4835 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4837 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4838 "* return output_fix_trunc (insn, operands, 0);"
4839 [(set_attr "type" "fistp")
4840 (set_attr "i387_cw" "trunc")
4841 (set_attr "mode" "<MODE>")])
4843 (define_insn "fix_trunc<mode>_i387_with_temp"
4844 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4845 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4846 (use (match_operand:HI 2 "memory_operand" "m,m"))
4847 (use (match_operand:HI 3 "memory_operand" "m,m"))
4848 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4849 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4851 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4853 [(set_attr "type" "fistp")
4854 (set_attr "i387_cw" "trunc")
4855 (set_attr "mode" "<MODE>")])
4858 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4859 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4860 (use (match_operand:HI 2 "memory_operand" ""))
4861 (use (match_operand:HI 3 "memory_operand" ""))
4862 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4864 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4866 (use (match_dup 3))])
4867 (set (match_dup 0) (match_dup 4))])
4870 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4871 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4872 (use (match_operand:HI 2 "memory_operand" ""))
4873 (use (match_operand:HI 3 "memory_operand" ""))
4874 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4876 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4878 (use (match_dup 3))])])
4880 (define_insn "x86_fnstcw_1"
4881 [(set (match_operand:HI 0 "memory_operand" "=m")
4882 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4885 [(set (attr "length")
4886 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4887 (set_attr "mode" "HI")
4888 (set_attr "unit" "i387")
4889 (set_attr "bdver1_decode" "vector")])
4891 (define_insn "x86_fldcw_1"
4892 [(set (reg:HI FPCR_REG)
4893 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4896 [(set (attr "length")
4897 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4898 (set_attr "mode" "HI")
4899 (set_attr "unit" "i387")
4900 (set_attr "athlon_decode" "vector")
4901 (set_attr "amdfam10_decode" "vector")
4902 (set_attr "bdver1_decode" "vector")])
4904 ;; Conversion between fixed point and floating point.
4906 ;; Even though we only accept memory inputs, the backend _really_
4907 ;; wants to be able to do this between registers.
4909 (define_expand "floathi<mode>2"
4910 [(set (match_operand:X87MODEF 0 "register_operand" "")
4911 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4913 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4914 || TARGET_MIX_SSE_I387)")
4916 ;; Pre-reload splitter to add memory clobber to the pattern.
4917 (define_insn_and_split "*floathi<mode>2_1"
4918 [(set (match_operand:X87MODEF 0 "register_operand" "")
4919 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4921 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4922 || TARGET_MIX_SSE_I387)
4923 && can_create_pseudo_p ()"
4926 [(parallel [(set (match_dup 0)
4927 (float:X87MODEF (match_dup 1)))
4928 (clobber (match_dup 2))])]
4929 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4931 (define_insn "*floathi<mode>2_i387_with_temp"
4932 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4933 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4934 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4936 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4937 || TARGET_MIX_SSE_I387)"
4939 [(set_attr "type" "fmov,multi")
4940 (set_attr "mode" "<MODE>")
4941 (set_attr "unit" "*,i387")
4942 (set_attr "fp_int_src" "true")])
4944 (define_insn "*floathi<mode>2_i387"
4945 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4946 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4948 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4949 || TARGET_MIX_SSE_I387)"
4951 [(set_attr "type" "fmov")
4952 (set_attr "mode" "<MODE>")
4953 (set_attr "fp_int_src" "true")])
4956 [(set (match_operand:X87MODEF 0 "register_operand" "")
4957 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4958 (clobber (match_operand:HI 2 "memory_operand" ""))]
4960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4961 || TARGET_MIX_SSE_I387)
4962 && reload_completed"
4963 [(set (match_dup 2) (match_dup 1))
4964 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4967 [(set (match_operand:X87MODEF 0 "register_operand" "")
4968 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4969 (clobber (match_operand:HI 2 "memory_operand" ""))]
4971 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4972 || TARGET_MIX_SSE_I387)
4973 && reload_completed"
4974 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4976 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4977 [(set (match_operand:X87MODEF 0 "register_operand" "")
4979 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4981 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4982 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4984 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4985 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4986 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4988 rtx reg = gen_reg_rtx (XFmode);
4989 rtx (*insn)(rtx, rtx);
4991 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4993 if (<X87MODEF:MODE>mode == SFmode)
4994 insn = gen_truncxfsf2;
4995 else if (<X87MODEF:MODE>mode == DFmode)
4996 insn = gen_truncxfdf2;
5000 emit_insn (insn (operands[0], reg));
5005 ;; Pre-reload splitter to add memory clobber to the pattern.
5006 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5007 [(set (match_operand:X87MODEF 0 "register_operand" "")
5008 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5010 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5011 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5012 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5013 || TARGET_MIX_SSE_I387))
5014 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5015 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5016 && ((<SSEMODEI24:MODE>mode == SImode
5017 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5018 && optimize_function_for_speed_p (cfun)
5019 && flag_trapping_math)
5020 || !(TARGET_INTER_UNIT_CONVERSIONS
5021 || optimize_function_for_size_p (cfun)))))
5022 && can_create_pseudo_p ()"
5025 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5026 (clobber (match_dup 2))])]
5028 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5030 /* Avoid store forwarding (partial memory) stall penalty
5031 by passing DImode value through XMM registers. */
5032 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5033 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5034 && optimize_function_for_speed_p (cfun))
5036 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5043 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5044 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5046 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5047 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5048 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5049 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5051 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5052 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5053 (set_attr "unit" "*,i387,*,*,*")
5054 (set_attr "athlon_decode" "*,*,double,direct,double")
5055 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5056 (set_attr "bdver1_decode" "*,*,double,direct,double")
5057 (set_attr "fp_int_src" "true")])
5059 (define_insn "*floatsi<mode>2_vector_mixed"
5060 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5061 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5062 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5063 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5067 [(set_attr "type" "fmov,sseicvt")
5068 (set_attr "mode" "<MODE>,<ssevecmode>")
5069 (set_attr "unit" "i387,*")
5070 (set_attr "athlon_decode" "*,direct")
5071 (set_attr "amdfam10_decode" "*,double")
5072 (set_attr "bdver1_decode" "*,direct")
5073 (set_attr "fp_int_src" "true")])
5075 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5076 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5078 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5079 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5080 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5081 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5083 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5084 (set_attr "mode" "<MODEF:MODE>")
5085 (set_attr "unit" "*,i387,*,*")
5086 (set_attr "athlon_decode" "*,*,double,direct")
5087 (set_attr "amdfam10_decode" "*,*,vector,double")
5088 (set_attr "bdver1_decode" "*,*,double,direct")
5089 (set_attr "fp_int_src" "true")])
5092 [(set (match_operand:MODEF 0 "register_operand" "")
5093 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5094 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5095 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5096 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5097 && TARGET_INTER_UNIT_CONVERSIONS
5099 && (SSE_REG_P (operands[0])
5100 || (GET_CODE (operands[0]) == SUBREG
5101 && SSE_REG_P (operands[0])))"
5102 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5105 [(set (match_operand:MODEF 0 "register_operand" "")
5106 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5107 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5108 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5109 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5110 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5112 && (SSE_REG_P (operands[0])
5113 || (GET_CODE (operands[0]) == SUBREG
5114 && SSE_REG_P (operands[0])))"
5115 [(set (match_dup 2) (match_dup 1))
5116 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5118 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5119 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5121 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5122 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5123 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5124 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5127 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5128 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5129 [(set_attr "type" "fmov,sseicvt,sseicvt")
5130 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5131 (set_attr "mode" "<MODEF:MODE>")
5132 (set (attr "prefix_rex")
5134 (and (eq_attr "prefix" "maybe_vex")
5135 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5137 (const_string "*")))
5138 (set_attr "unit" "i387,*,*")
5139 (set_attr "athlon_decode" "*,double,direct")
5140 (set_attr "amdfam10_decode" "*,vector,double")
5141 (set_attr "bdver1_decode" "*,double,direct")
5142 (set_attr "fp_int_src" "true")])
5144 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5145 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5147 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5148 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5149 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5150 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5153 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5154 [(set_attr "type" "fmov,sseicvt")
5155 (set_attr "prefix" "orig,maybe_vex")
5156 (set_attr "mode" "<MODEF:MODE>")
5157 (set (attr "prefix_rex")
5159 (and (eq_attr "prefix" "maybe_vex")
5160 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5162 (const_string "*")))
5163 (set_attr "athlon_decode" "*,direct")
5164 (set_attr "amdfam10_decode" "*,double")
5165 (set_attr "bdver1_decode" "*,direct")
5166 (set_attr "fp_int_src" "true")])
5168 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5169 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5171 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5172 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5173 "TARGET_SSE2 && TARGET_SSE_MATH
5174 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5176 [(set_attr "type" "sseicvt")
5177 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5178 (set_attr "athlon_decode" "double,direct,double")
5179 (set_attr "amdfam10_decode" "vector,double,double")
5180 (set_attr "bdver1_decode" "double,direct,double")
5181 (set_attr "fp_int_src" "true")])
5183 (define_insn "*floatsi<mode>2_vector_sse"
5184 [(set (match_operand:MODEF 0 "register_operand" "=x")
5185 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5186 "TARGET_SSE2 && TARGET_SSE_MATH
5187 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5189 [(set_attr "type" "sseicvt")
5190 (set_attr "mode" "<MODE>")
5191 (set_attr "athlon_decode" "direct")
5192 (set_attr "amdfam10_decode" "double")
5193 (set_attr "bdver1_decode" "direct")
5194 (set_attr "fp_int_src" "true")])
5197 [(set (match_operand:MODEF 0 "register_operand" "")
5198 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5199 (clobber (match_operand:SI 2 "memory_operand" ""))]
5200 "TARGET_SSE2 && TARGET_SSE_MATH
5201 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5203 && (SSE_REG_P (operands[0])
5204 || (GET_CODE (operands[0]) == SUBREG
5205 && SSE_REG_P (operands[0])))"
5208 rtx op1 = operands[1];
5210 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5212 if (GET_CODE (op1) == SUBREG)
5213 op1 = SUBREG_REG (op1);
5215 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5217 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5218 emit_insn (gen_sse2_loadld (operands[4],
5219 CONST0_RTX (V4SImode), operands[1]));
5221 /* We can ignore possible trapping value in the
5222 high part of SSE register for non-trapping math. */
5223 else if (SSE_REG_P (op1) && !flag_trapping_math)
5224 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5227 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5228 emit_move_insn (operands[2], operands[1]);
5229 emit_insn (gen_sse2_loadld (operands[4],
5230 CONST0_RTX (V4SImode), operands[2]));
5233 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5238 [(set (match_operand:MODEF 0 "register_operand" "")
5239 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5240 (clobber (match_operand:SI 2 "memory_operand" ""))]
5241 "TARGET_SSE2 && TARGET_SSE_MATH
5242 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5244 && (SSE_REG_P (operands[0])
5245 || (GET_CODE (operands[0]) == SUBREG
5246 && SSE_REG_P (operands[0])))"
5249 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5251 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5253 emit_insn (gen_sse2_loadld (operands[4],
5254 CONST0_RTX (V4SImode), operands[1]));
5256 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5261 [(set (match_operand:MODEF 0 "register_operand" "")
5262 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5263 "TARGET_SSE2 && TARGET_SSE_MATH
5264 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5266 && (SSE_REG_P (operands[0])
5267 || (GET_CODE (operands[0]) == SUBREG
5268 && SSE_REG_P (operands[0])))"
5271 rtx op1 = operands[1];
5273 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5275 if (GET_CODE (op1) == SUBREG)
5276 op1 = SUBREG_REG (op1);
5278 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5280 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5281 emit_insn (gen_sse2_loadld (operands[4],
5282 CONST0_RTX (V4SImode), operands[1]));
5284 /* We can ignore possible trapping value in the
5285 high part of SSE register for non-trapping math. */
5286 else if (SSE_REG_P (op1) && !flag_trapping_math)
5287 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5291 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5296 [(set (match_operand:MODEF 0 "register_operand" "")
5297 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5298 "TARGET_SSE2 && TARGET_SSE_MATH
5299 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5301 && (SSE_REG_P (operands[0])
5302 || (GET_CODE (operands[0]) == SUBREG
5303 && SSE_REG_P (operands[0])))"
5306 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5308 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5310 emit_insn (gen_sse2_loadld (operands[4],
5311 CONST0_RTX (V4SImode), operands[1]));
5313 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5317 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5318 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5320 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5321 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5322 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5323 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5325 [(set_attr "type" "sseicvt")
5326 (set_attr "mode" "<MODEF:MODE>")
5327 (set_attr "athlon_decode" "double,direct")
5328 (set_attr "amdfam10_decode" "vector,double")
5329 (set_attr "bdver1_decode" "double,direct")
5330 (set_attr "fp_int_src" "true")])
5332 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5333 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5335 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5336 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5337 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5338 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5339 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5340 [(set_attr "type" "sseicvt")
5341 (set_attr "prefix" "maybe_vex")
5342 (set_attr "mode" "<MODEF:MODE>")
5343 (set (attr "prefix_rex")
5345 (and (eq_attr "prefix" "maybe_vex")
5346 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5348 (const_string "*")))
5349 (set_attr "athlon_decode" "double,direct")
5350 (set_attr "amdfam10_decode" "vector,double")
5351 (set_attr "bdver1_decode" "double,direct")
5352 (set_attr "fp_int_src" "true")])
5355 [(set (match_operand:MODEF 0 "register_operand" "")
5356 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5357 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5358 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5359 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5360 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5362 && (SSE_REG_P (operands[0])
5363 || (GET_CODE (operands[0]) == SUBREG
5364 && SSE_REG_P (operands[0])))"
5365 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5367 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5368 [(set (match_operand:MODEF 0 "register_operand" "=x")
5370 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5371 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5372 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5373 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5374 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5375 [(set_attr "type" "sseicvt")
5376 (set_attr "prefix" "maybe_vex")
5377 (set_attr "mode" "<MODEF:MODE>")
5378 (set (attr "prefix_rex")
5380 (and (eq_attr "prefix" "maybe_vex")
5381 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5383 (const_string "*")))
5384 (set_attr "athlon_decode" "direct")
5385 (set_attr "amdfam10_decode" "double")
5386 (set_attr "bdver1_decode" "direct")
5387 (set_attr "fp_int_src" "true")])
5390 [(set (match_operand:MODEF 0 "register_operand" "")
5391 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5392 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5393 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5394 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5395 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5397 && (SSE_REG_P (operands[0])
5398 || (GET_CODE (operands[0]) == SUBREG
5399 && SSE_REG_P (operands[0])))"
5400 [(set (match_dup 2) (match_dup 1))
5401 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5404 [(set (match_operand:MODEF 0 "register_operand" "")
5405 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5406 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5407 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5408 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5410 && (SSE_REG_P (operands[0])
5411 || (GET_CODE (operands[0]) == SUBREG
5412 && SSE_REG_P (operands[0])))"
5413 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5415 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5416 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5418 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5419 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5421 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5425 [(set_attr "type" "fmov,multi")
5426 (set_attr "mode" "<X87MODEF:MODE>")
5427 (set_attr "unit" "*,i387")
5428 (set_attr "fp_int_src" "true")])
5430 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5431 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5433 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5435 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5437 [(set_attr "type" "fmov")
5438 (set_attr "mode" "<X87MODEF:MODE>")
5439 (set_attr "fp_int_src" "true")])
5442 [(set (match_operand:X87MODEF 0 "register_operand" "")
5443 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5444 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5446 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5448 && FP_REG_P (operands[0])"
5449 [(set (match_dup 2) (match_dup 1))
5450 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5453 [(set (match_operand:X87MODEF 0 "register_operand" "")
5454 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5455 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5457 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5459 && FP_REG_P (operands[0])"
5460 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5462 ;; Avoid store forwarding (partial memory) stall penalty
5463 ;; by passing DImode value through XMM registers. */
5465 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5466 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5468 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5469 (clobber (match_scratch:V4SI 3 "=X,x"))
5470 (clobber (match_scratch:V4SI 4 "=X,x"))
5471 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5472 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5473 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5474 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5476 [(set_attr "type" "multi")
5477 (set_attr "mode" "<X87MODEF:MODE>")
5478 (set_attr "unit" "i387")
5479 (set_attr "fp_int_src" "true")])
5482 [(set (match_operand:X87MODEF 0 "register_operand" "")
5483 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5484 (clobber (match_scratch:V4SI 3 ""))
5485 (clobber (match_scratch:V4SI 4 ""))
5486 (clobber (match_operand:DI 2 "memory_operand" ""))]
5487 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5488 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5489 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5491 && FP_REG_P (operands[0])"
5492 [(set (match_dup 2) (match_dup 3))
5493 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5495 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5496 Assemble the 64-bit DImode value in an xmm register. */
5497 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5498 gen_rtx_SUBREG (SImode, operands[1], 0)));
5499 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5500 gen_rtx_SUBREG (SImode, operands[1], 4)));
5501 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5504 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5508 [(set (match_operand:X87MODEF 0 "register_operand" "")
5509 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5510 (clobber (match_scratch:V4SI 3 ""))
5511 (clobber (match_scratch:V4SI 4 ""))
5512 (clobber (match_operand:DI 2 "memory_operand" ""))]
5513 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5514 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5515 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5517 && FP_REG_P (operands[0])"
5518 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5520 ;; Avoid store forwarding (partial memory) stall penalty by extending
5521 ;; SImode value to DImode through XMM register instead of pushing two
5522 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5523 ;; targets benefit from this optimization. Also note that fild
5524 ;; loads from memory only.
5526 (define_insn "*floatunssi<mode>2_1"
5527 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5528 (unsigned_float:X87MODEF
5529 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5530 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5531 (clobber (match_scratch:SI 3 "=X,x"))]
5533 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5536 [(set_attr "type" "multi")
5537 (set_attr "mode" "<MODE>")])
5540 [(set (match_operand:X87MODEF 0 "register_operand" "")
5541 (unsigned_float:X87MODEF
5542 (match_operand:SI 1 "register_operand" "")))
5543 (clobber (match_operand:DI 2 "memory_operand" ""))
5544 (clobber (match_scratch:SI 3 ""))]
5546 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5548 && reload_completed"
5549 [(set (match_dup 2) (match_dup 1))
5551 (float:X87MODEF (match_dup 2)))]
5552 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5555 [(set (match_operand:X87MODEF 0 "register_operand" "")
5556 (unsigned_float:X87MODEF
5557 (match_operand:SI 1 "memory_operand" "")))
5558 (clobber (match_operand:DI 2 "memory_operand" ""))
5559 (clobber (match_scratch:SI 3 ""))]
5561 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5563 && reload_completed"
5564 [(set (match_dup 2) (match_dup 3))
5566 (float:X87MODEF (match_dup 2)))]
5568 emit_move_insn (operands[3], operands[1]);
5569 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5572 (define_expand "floatunssi<mode>2"
5574 [(set (match_operand:X87MODEF 0 "register_operand" "")
5575 (unsigned_float:X87MODEF
5576 (match_operand:SI 1 "nonimmediate_operand" "")))
5577 (clobber (match_dup 2))
5578 (clobber (match_scratch:SI 3 ""))])]
5580 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5582 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5584 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5586 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5591 enum ix86_stack_slot slot = (virtuals_instantiated
5594 operands[2] = assign_386_stack_local (DImode, slot);
5598 (define_expand "floatunsdisf2"
5599 [(use (match_operand:SF 0 "register_operand" ""))
5600 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5601 "TARGET_64BIT && TARGET_SSE_MATH"
5602 "x86_emit_floatuns (operands); DONE;")
5604 (define_expand "floatunsdidf2"
5605 [(use (match_operand:DF 0 "register_operand" ""))
5606 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5607 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5608 && TARGET_SSE2 && TARGET_SSE_MATH"
5611 x86_emit_floatuns (operands);
5613 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5619 (define_expand "add<mode>3"
5620 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5621 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5622 (match_operand:SDWIM 2 "<general_operand>" "")))]
5624 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5626 (define_insn_and_split "*add<dwi>3_doubleword"
5627 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5629 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5630 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5631 (clobber (reg:CC FLAGS_REG))]
5632 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5635 [(parallel [(set (reg:CC FLAGS_REG)
5636 (unspec:CC [(match_dup 1) (match_dup 2)]
5639 (plus:DWIH (match_dup 1) (match_dup 2)))])
5640 (parallel [(set (match_dup 3)
5644 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5646 (clobber (reg:CC FLAGS_REG))])]
5647 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5649 (define_insn "*add<mode>3_cc"
5650 [(set (reg:CC FLAGS_REG)
5652 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5653 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5655 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5656 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5657 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5658 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5659 [(set_attr "type" "alu")
5660 (set_attr "mode" "<MODE>")])
5662 (define_insn "addqi3_cc"
5663 [(set (reg:CC FLAGS_REG)
5665 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5666 (match_operand:QI 2 "general_operand" "qn,qm")]
5668 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5669 (plus:QI (match_dup 1) (match_dup 2)))]
5670 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5671 "add{b}\t{%2, %0|%0, %2}"
5672 [(set_attr "type" "alu")
5673 (set_attr "mode" "QI")])
5675 (define_insn "*lea_1"
5676 [(set (match_operand:P 0 "register_operand" "=r")
5677 (match_operand:P 1 "no_seg_address_operand" "p"))]
5679 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5680 [(set_attr "type" "lea")
5681 (set_attr "mode" "<MODE>")])
5683 (define_insn "*lea_2"
5684 [(set (match_operand:SI 0 "register_operand" "=r")
5685 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5687 "lea{l}\t{%a1, %0|%0, %a1}"
5688 [(set_attr "type" "lea")
5689 (set_attr "mode" "SI")])
5691 (define_insn "*lea_2_zext"
5692 [(set (match_operand:DI 0 "register_operand" "=r")
5694 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5696 "lea{l}\t{%a1, %k0|%k0, %a1}"
5697 [(set_attr "type" "lea")
5698 (set_attr "mode" "SI")])
5700 (define_insn "*add<mode>_1"
5701 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5703 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5704 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5705 (clobber (reg:CC FLAGS_REG))]
5706 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5708 switch (get_attr_type (insn))
5714 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5715 if (operands[2] == const1_rtx)
5716 return "inc{<imodesuffix>}\t%0";
5719 gcc_assert (operands[2] == constm1_rtx);
5720 return "dec{<imodesuffix>}\t%0";
5724 /* For most processors, ADD is faster than LEA. This alternative
5725 was added to use ADD as much as possible. */
5726 if (which_alternative == 2)
5729 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5732 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5733 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5734 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5736 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5740 (cond [(eq_attr "alternative" "3")
5741 (const_string "lea")
5742 (match_operand:SWI48 2 "incdec_operand" "")
5743 (const_string "incdec")
5745 (const_string "alu")))
5746 (set (attr "length_immediate")
5748 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5750 (const_string "*")))
5751 (set_attr "mode" "<MODE>")])
5753 ;; It may seem that nonimmediate operand is proper one for operand 1.
5754 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5755 ;; we take care in ix86_binary_operator_ok to not allow two memory
5756 ;; operands so proper swapping will be done in reload. This allow
5757 ;; patterns constructed from addsi_1 to match.
5759 (define_insn "*addsi_1_zext"
5760 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5762 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5763 (match_operand:SI 2 "general_operand" "g,0,li"))))
5764 (clobber (reg:CC FLAGS_REG))]
5765 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5767 switch (get_attr_type (insn))
5773 if (operands[2] == const1_rtx)
5774 return "inc{l}\t%k0";
5777 gcc_assert (operands[2] == constm1_rtx);
5778 return "dec{l}\t%k0";
5782 /* For most processors, ADD is faster than LEA. This alternative
5783 was added to use ADD as much as possible. */
5784 if (which_alternative == 1)
5787 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5790 if (x86_maybe_negate_const_int (&operands[2], SImode))
5791 return "sub{l}\t{%2, %k0|%k0, %2}";
5793 return "add{l}\t{%2, %k0|%k0, %2}";
5797 (cond [(eq_attr "alternative" "2")
5798 (const_string "lea")
5799 (match_operand:SI 2 "incdec_operand" "")
5800 (const_string "incdec")
5802 (const_string "alu")))
5803 (set (attr "length_immediate")
5805 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5807 (const_string "*")))
5808 (set_attr "mode" "SI")])
5810 (define_insn "*addhi_1"
5811 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5812 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5813 (match_operand:HI 2 "general_operand" "rn,rm")))
5814 (clobber (reg:CC FLAGS_REG))]
5815 "TARGET_PARTIAL_REG_STALL
5816 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5818 switch (get_attr_type (insn))
5821 if (operands[2] == const1_rtx)
5822 return "inc{w}\t%0";
5825 gcc_assert (operands[2] == constm1_rtx);
5826 return "dec{w}\t%0";
5830 if (x86_maybe_negate_const_int (&operands[2], HImode))
5831 return "sub{w}\t{%2, %0|%0, %2}";
5833 return "add{w}\t{%2, %0|%0, %2}";
5837 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5838 (const_string "incdec")
5839 (const_string "alu")))
5840 (set (attr "length_immediate")
5842 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5844 (const_string "*")))
5845 (set_attr "mode" "HI")])
5847 (define_insn "*addhi_1_lea"
5848 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5849 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5850 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5851 (clobber (reg:CC FLAGS_REG))]
5852 "!TARGET_PARTIAL_REG_STALL
5853 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5855 switch (get_attr_type (insn))
5861 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5862 if (operands[2] == const1_rtx)
5863 return "inc{w}\t%0";
5866 gcc_assert (operands[2] == constm1_rtx);
5867 return "dec{w}\t%0";
5871 /* For most processors, ADD is faster than LEA. This alternative
5872 was added to use ADD as much as possible. */
5873 if (which_alternative == 2)
5876 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5879 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5880 if (x86_maybe_negate_const_int (&operands[2], HImode))
5881 return "sub{w}\t{%2, %0|%0, %2}";
5883 return "add{w}\t{%2, %0|%0, %2}";
5887 (cond [(eq_attr "alternative" "3")
5888 (const_string "lea")
5889 (match_operand:HI 2 "incdec_operand" "")
5890 (const_string "incdec")
5892 (const_string "alu")))
5893 (set (attr "length_immediate")
5895 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5897 (const_string "*")))
5898 (set_attr "mode" "HI,HI,HI,SI")])
5900 ;; %%% Potential partial reg stall on alternative 2. What to do?
5901 (define_insn "*addqi_1"
5902 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5903 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5904 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5905 (clobber (reg:CC FLAGS_REG))]
5906 "TARGET_PARTIAL_REG_STALL
5907 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5909 int widen = (which_alternative == 2);
5910 switch (get_attr_type (insn))
5913 if (operands[2] == const1_rtx)
5914 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5917 gcc_assert (operands[2] == constm1_rtx);
5918 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5922 if (x86_maybe_negate_const_int (&operands[2], QImode))
5925 return "sub{l}\t{%2, %k0|%k0, %2}";
5927 return "sub{b}\t{%2, %0|%0, %2}";
5930 return "add{l}\t{%k2, %k0|%k0, %k2}";
5932 return "add{b}\t{%2, %0|%0, %2}";
5936 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5937 (const_string "incdec")
5938 (const_string "alu")))
5939 (set (attr "length_immediate")
5941 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5943 (const_string "*")))
5944 (set_attr "mode" "QI,QI,SI")])
5946 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5947 (define_insn "*addqi_1_lea"
5948 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5949 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5950 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5951 (clobber (reg:CC FLAGS_REG))]
5952 "!TARGET_PARTIAL_REG_STALL
5953 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5955 int widen = (which_alternative == 3 || which_alternative == 4);
5957 switch (get_attr_type (insn))
5963 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5964 if (operands[2] == const1_rtx)
5965 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5968 gcc_assert (operands[2] == constm1_rtx);
5969 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5973 /* For most processors, ADD is faster than LEA. These alternatives
5974 were added to use ADD as much as possible. */
5975 if (which_alternative == 2 || which_alternative == 4)
5978 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5981 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5982 if (x86_maybe_negate_const_int (&operands[2], QImode))
5985 return "sub{l}\t{%2, %k0|%k0, %2}";
5987 return "sub{b}\t{%2, %0|%0, %2}";
5990 return "add{l}\t{%k2, %k0|%k0, %k2}";
5992 return "add{b}\t{%2, %0|%0, %2}";
5996 (cond [(eq_attr "alternative" "5")
5997 (const_string "lea")
5998 (match_operand:QI 2 "incdec_operand" "")
5999 (const_string "incdec")
6001 (const_string "alu")))
6002 (set (attr "length_immediate")
6004 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6006 (const_string "*")))
6007 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
6009 (define_insn "*addqi_1_slp"
6010 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6011 (plus:QI (match_dup 0)
6012 (match_operand:QI 1 "general_operand" "qn,qnm")))
6013 (clobber (reg:CC FLAGS_REG))]
6014 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6015 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6017 switch (get_attr_type (insn))
6020 if (operands[1] == const1_rtx)
6021 return "inc{b}\t%0";
6024 gcc_assert (operands[1] == constm1_rtx);
6025 return "dec{b}\t%0";
6029 if (x86_maybe_negate_const_int (&operands[1], QImode))
6030 return "sub{b}\t{%1, %0|%0, %1}";
6032 return "add{b}\t{%1, %0|%0, %1}";
6036 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6037 (const_string "incdec")
6038 (const_string "alu1")))
6039 (set (attr "memory")
6040 (if_then_else (match_operand 1 "memory_operand" "")
6041 (const_string "load")
6042 (const_string "none")))
6043 (set_attr "mode" "QI")])
6045 ;; Convert lea to the lea pattern to avoid flags dependency.
6047 [(set (match_operand 0 "register_operand" "")
6048 (plus (match_operand 1 "register_operand" "")
6049 (match_operand 2 "nonmemory_operand" "")))
6050 (clobber (reg:CC FLAGS_REG))]
6051 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6055 enum machine_mode mode = GET_MODE (operands[0]);
6057 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6058 may confuse gen_lowpart. */
6061 operands[1] = gen_lowpart (Pmode, operands[1]);
6062 operands[2] = gen_lowpart (Pmode, operands[2]);
6065 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6067 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6068 operands[0] = gen_lowpart (SImode, operands[0]);
6070 if (TARGET_64BIT && mode != Pmode)
6071 pat = gen_rtx_SUBREG (SImode, pat, 0);
6073 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6077 ;; Convert lea to the lea pattern to avoid flags dependency.
6078 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6079 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
6081 [(set (match_operand:DI 0 "register_operand" "")
6082 (plus:DI (match_operand:DI 1 "register_operand" "")
6083 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6084 (clobber (reg:CC FLAGS_REG))]
6085 "TARGET_64BIT && reload_completed
6086 && true_regnum (operands[0]) != true_regnum (operands[1])"
6088 (plus:DI (match_dup 1) (match_dup 2)))])
6090 ;; Convert lea to the lea pattern to avoid flags dependency.
6092 [(set (match_operand:DI 0 "register_operand" "")
6094 (plus:SI (match_operand:SI 1 "register_operand" "")
6095 (match_operand:SI 2 "nonmemory_operand" ""))))
6096 (clobber (reg:CC FLAGS_REG))]
6097 "TARGET_64BIT && reload_completed
6098 && ix86_lea_for_add_ok (insn, operands)"
6100 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6102 operands[1] = gen_lowpart (DImode, operands[1]);
6103 operands[2] = gen_lowpart (DImode, operands[2]);
6106 (define_insn "*add<mode>_2"
6107 [(set (reg FLAGS_REG)
6110 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6111 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6113 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6114 (plus:SWI (match_dup 1) (match_dup 2)))]
6115 "ix86_match_ccmode (insn, CCGOCmode)
6116 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6118 switch (get_attr_type (insn))
6121 if (operands[2] == const1_rtx)
6122 return "inc{<imodesuffix>}\t%0";
6125 gcc_assert (operands[2] == constm1_rtx);
6126 return "dec{<imodesuffix>}\t%0";
6130 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6131 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6133 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6137 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6138 (const_string "incdec")
6139 (const_string "alu")))
6140 (set (attr "length_immediate")
6142 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6144 (const_string "*")))
6145 (set_attr "mode" "<MODE>")])
6147 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6148 (define_insn "*addsi_2_zext"
6149 [(set (reg FLAGS_REG)
6151 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6152 (match_operand:SI 2 "general_operand" "g"))
6154 (set (match_operand:DI 0 "register_operand" "=r")
6155 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6156 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6157 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6159 switch (get_attr_type (insn))
6162 if (operands[2] == const1_rtx)
6163 return "inc{l}\t%k0";
6166 gcc_assert (operands[2] == constm1_rtx);
6167 return "dec{l}\t%k0";
6171 if (x86_maybe_negate_const_int (&operands[2], SImode))
6172 return "sub{l}\t{%2, %k0|%k0, %2}";
6174 return "add{l}\t{%2, %k0|%k0, %2}";
6178 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6179 (const_string "incdec")
6180 (const_string "alu")))
6181 (set (attr "length_immediate")
6183 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6185 (const_string "*")))
6186 (set_attr "mode" "SI")])
6188 (define_insn "*add<mode>_3"
6189 [(set (reg FLAGS_REG)
6191 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6192 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6193 (clobber (match_scratch:SWI 0 "=<r>"))]
6194 "ix86_match_ccmode (insn, CCZmode)
6195 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6197 switch (get_attr_type (insn))
6200 if (operands[2] == const1_rtx)
6201 return "inc{<imodesuffix>}\t%0";
6204 gcc_assert (operands[2] == constm1_rtx);
6205 return "dec{<imodesuffix>}\t%0";
6209 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6210 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6212 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6216 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6217 (const_string "incdec")
6218 (const_string "alu")))
6219 (set (attr "length_immediate")
6221 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6223 (const_string "*")))
6224 (set_attr "mode" "<MODE>")])
6226 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6227 (define_insn "*addsi_3_zext"
6228 [(set (reg FLAGS_REG)
6230 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6231 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6232 (set (match_operand:DI 0 "register_operand" "=r")
6233 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6234 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6235 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6237 switch (get_attr_type (insn))
6240 if (operands[2] == const1_rtx)
6241 return "inc{l}\t%k0";
6244 gcc_assert (operands[2] == constm1_rtx);
6245 return "dec{l}\t%k0";
6249 if (x86_maybe_negate_const_int (&operands[2], SImode))
6250 return "sub{l}\t{%2, %k0|%k0, %2}";
6252 return "add{l}\t{%2, %k0|%k0, %2}";
6256 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6257 (const_string "incdec")
6258 (const_string "alu")))
6259 (set (attr "length_immediate")
6261 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6263 (const_string "*")))
6264 (set_attr "mode" "SI")])
6266 ; For comparisons against 1, -1 and 128, we may generate better code
6267 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6268 ; is matched then. We can't accept general immediate, because for
6269 ; case of overflows, the result is messed up.
6270 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6271 ; only for comparisons not depending on it.
6273 (define_insn "*adddi_4"
6274 [(set (reg FLAGS_REG)
6276 (match_operand:DI 1 "nonimmediate_operand" "0")
6277 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6278 (clobber (match_scratch:DI 0 "=rm"))]
6280 && ix86_match_ccmode (insn, CCGCmode)"
6282 switch (get_attr_type (insn))
6285 if (operands[2] == constm1_rtx)
6286 return "inc{q}\t%0";
6289 gcc_assert (operands[2] == const1_rtx);
6290 return "dec{q}\t%0";
6294 if (x86_maybe_negate_const_int (&operands[2], DImode))
6295 return "add{q}\t{%2, %0|%0, %2}";
6297 return "sub{q}\t{%2, %0|%0, %2}";
6301 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6302 (const_string "incdec")
6303 (const_string "alu")))
6304 (set (attr "length_immediate")
6306 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6308 (const_string "*")))
6309 (set_attr "mode" "DI")])
6311 ; For comparisons against 1, -1 and 128, we may generate better code
6312 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6313 ; is matched then. We can't accept general immediate, because for
6314 ; case of overflows, the result is messed up.
6315 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6316 ; only for comparisons not depending on it.
6318 (define_insn "*add<mode>_4"
6319 [(set (reg FLAGS_REG)
6321 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6322 (match_operand:SWI124 2 "const_int_operand" "n")))
6323 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6324 "ix86_match_ccmode (insn, CCGCmode)"
6326 switch (get_attr_type (insn))
6329 if (operands[2] == constm1_rtx)
6330 return "inc{<imodesuffix>}\t%0";
6333 gcc_assert (operands[2] == const1_rtx);
6334 return "dec{<imodesuffix>}\t%0";
6338 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6339 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6341 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6345 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6346 (const_string "incdec")
6347 (const_string "alu")))
6348 (set (attr "length_immediate")
6350 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6352 (const_string "*")))
6353 (set_attr "mode" "<MODE>")])
6355 (define_insn "*add<mode>_5"
6356 [(set (reg FLAGS_REG)
6359 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6360 (match_operand:SWI 2 "<general_operand>" "<g>"))
6362 (clobber (match_scratch:SWI 0 "=<r>"))]
6363 "ix86_match_ccmode (insn, CCGOCmode)
6364 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6366 switch (get_attr_type (insn))
6369 if (operands[2] == const1_rtx)
6370 return "inc{<imodesuffix>}\t%0";
6373 gcc_assert (operands[2] == constm1_rtx);
6374 return "dec{<imodesuffix>}\t%0";
6378 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6379 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6381 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6385 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6386 (const_string "incdec")
6387 (const_string "alu")))
6388 (set (attr "length_immediate")
6390 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6392 (const_string "*")))
6393 (set_attr "mode" "<MODE>")])
6395 (define_insn "*addqi_ext_1_rex64"
6396 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6401 (match_operand 1 "ext_register_operand" "0")
6404 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6405 (clobber (reg:CC FLAGS_REG))]
6408 switch (get_attr_type (insn))
6411 if (operands[2] == const1_rtx)
6412 return "inc{b}\t%h0";
6415 gcc_assert (operands[2] == constm1_rtx);
6416 return "dec{b}\t%h0";
6420 return "add{b}\t{%2, %h0|%h0, %2}";
6424 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6425 (const_string "incdec")
6426 (const_string "alu")))
6427 (set_attr "modrm" "1")
6428 (set_attr "mode" "QI")])
6430 (define_insn "addqi_ext_1"
6431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6436 (match_operand 1 "ext_register_operand" "0")
6439 (match_operand:QI 2 "general_operand" "Qmn")))
6440 (clobber (reg:CC FLAGS_REG))]
6443 switch (get_attr_type (insn))
6446 if (operands[2] == const1_rtx)
6447 return "inc{b}\t%h0";
6450 gcc_assert (operands[2] == constm1_rtx);
6451 return "dec{b}\t%h0";
6455 return "add{b}\t{%2, %h0|%h0, %2}";
6459 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6460 (const_string "incdec")
6461 (const_string "alu")))
6462 (set_attr "modrm" "1")
6463 (set_attr "mode" "QI")])
6465 (define_insn "*addqi_ext_2"
6466 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6471 (match_operand 1 "ext_register_operand" "%0")
6475 (match_operand 2 "ext_register_operand" "Q")
6478 (clobber (reg:CC FLAGS_REG))]
6480 "add{b}\t{%h2, %h0|%h0, %h2}"
6481 [(set_attr "type" "alu")
6482 (set_attr "mode" "QI")])
6484 ;; The lea patterns for non-Pmodes needs to be matched by
6485 ;; several insns converted to real lea by splitters.
6487 (define_insn_and_split "*lea_general_1"
6488 [(set (match_operand 0 "register_operand" "=r")
6489 (plus (plus (match_operand 1 "index_register_operand" "l")
6490 (match_operand 2 "register_operand" "r"))
6491 (match_operand 3 "immediate_operand" "i")))]
6492 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6493 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6494 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6495 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6496 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6497 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6498 || GET_MODE (operands[3]) == VOIDmode)"
6500 "&& reload_completed"
6504 operands[0] = gen_lowpart (SImode, operands[0]);
6505 operands[1] = gen_lowpart (Pmode, operands[1]);
6506 operands[2] = gen_lowpart (Pmode, operands[2]);
6507 operands[3] = gen_lowpart (Pmode, operands[3]);
6508 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6510 if (Pmode != SImode)
6511 pat = gen_rtx_SUBREG (SImode, pat, 0);
6512 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6515 [(set_attr "type" "lea")
6516 (set_attr "mode" "SI")])
6518 (define_insn_and_split "*lea_general_1_zext"
6519 [(set (match_operand:DI 0 "register_operand" "=r")
6522 (match_operand:SI 1 "index_register_operand" "l")
6523 (match_operand:SI 2 "register_operand" "r"))
6524 (match_operand:SI 3 "immediate_operand" "i"))))]
6527 "&& reload_completed"
6529 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6531 (match_dup 3)) 0)))]
6533 operands[1] = gen_lowpart (Pmode, operands[1]);
6534 operands[2] = gen_lowpart (Pmode, operands[2]);
6535 operands[3] = gen_lowpart (Pmode, operands[3]);
6537 [(set_attr "type" "lea")
6538 (set_attr "mode" "SI")])
6540 (define_insn_and_split "*lea_general_2"
6541 [(set (match_operand 0 "register_operand" "=r")
6542 (plus (mult (match_operand 1 "index_register_operand" "l")
6543 (match_operand 2 "const248_operand" "i"))
6544 (match_operand 3 "nonmemory_operand" "ri")))]
6545 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6546 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6547 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6548 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6549 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6550 || GET_MODE (operands[3]) == VOIDmode)"
6552 "&& reload_completed"
6556 operands[0] = gen_lowpart (SImode, operands[0]);
6557 operands[1] = gen_lowpart (Pmode, operands[1]);
6558 operands[3] = gen_lowpart (Pmode, operands[3]);
6559 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6561 if (Pmode != SImode)
6562 pat = gen_rtx_SUBREG (SImode, pat, 0);
6563 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6566 [(set_attr "type" "lea")
6567 (set_attr "mode" "SI")])
6569 (define_insn_and_split "*lea_general_2_zext"
6570 [(set (match_operand:DI 0 "register_operand" "=r")
6573 (match_operand:SI 1 "index_register_operand" "l")
6574 (match_operand:SI 2 "const248_operand" "n"))
6575 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6578 "&& reload_completed"
6580 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6582 (match_dup 3)) 0)))]
6584 operands[1] = gen_lowpart (Pmode, operands[1]);
6585 operands[3] = gen_lowpart (Pmode, operands[3]);
6587 [(set_attr "type" "lea")
6588 (set_attr "mode" "SI")])
6590 (define_insn_and_split "*lea_general_3"
6591 [(set (match_operand 0 "register_operand" "=r")
6592 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6593 (match_operand 2 "const248_operand" "i"))
6594 (match_operand 3 "register_operand" "r"))
6595 (match_operand 4 "immediate_operand" "i")))]
6596 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6597 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6598 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6599 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6600 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6602 "&& reload_completed"
6606 operands[0] = gen_lowpart (SImode, operands[0]);
6607 operands[1] = gen_lowpart (Pmode, operands[1]);
6608 operands[3] = gen_lowpart (Pmode, operands[3]);
6609 operands[4] = gen_lowpart (Pmode, operands[4]);
6610 pat = gen_rtx_PLUS (Pmode,
6611 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6615 if (Pmode != SImode)
6616 pat = gen_rtx_SUBREG (SImode, pat, 0);
6617 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6620 [(set_attr "type" "lea")
6621 (set_attr "mode" "SI")])
6623 (define_insn_and_split "*lea_general_3_zext"
6624 [(set (match_operand:DI 0 "register_operand" "=r")
6628 (match_operand:SI 1 "index_register_operand" "l")
6629 (match_operand:SI 2 "const248_operand" "n"))
6630 (match_operand:SI 3 "register_operand" "r"))
6631 (match_operand:SI 4 "immediate_operand" "i"))))]
6634 "&& reload_completed"
6636 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6639 (match_dup 4)) 0)))]
6641 operands[1] = gen_lowpart (Pmode, operands[1]);
6642 operands[3] = gen_lowpart (Pmode, operands[3]);
6643 operands[4] = gen_lowpart (Pmode, operands[4]);
6645 [(set_attr "type" "lea")
6646 (set_attr "mode" "SI")])
6648 ;; Subtract instructions
6650 (define_expand "sub<mode>3"
6651 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6652 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6653 (match_operand:SDWIM 2 "<general_operand>" "")))]
6655 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6657 (define_insn_and_split "*sub<dwi>3_doubleword"
6658 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6660 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6661 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6662 (clobber (reg:CC FLAGS_REG))]
6663 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6666 [(parallel [(set (reg:CC FLAGS_REG)
6667 (compare:CC (match_dup 1) (match_dup 2)))
6669 (minus:DWIH (match_dup 1) (match_dup 2)))])
6670 (parallel [(set (match_dup 3)
6674 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6676 (clobber (reg:CC FLAGS_REG))])]
6677 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6679 (define_insn "*sub<mode>_1"
6680 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6682 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6683 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6684 (clobber (reg:CC FLAGS_REG))]
6685 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6686 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "mode" "<MODE>")])
6690 (define_insn "*subsi_1_zext"
6691 [(set (match_operand:DI 0 "register_operand" "=r")
6693 (minus:SI (match_operand:SI 1 "register_operand" "0")
6694 (match_operand:SI 2 "general_operand" "g"))))
6695 (clobber (reg:CC FLAGS_REG))]
6696 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6697 "sub{l}\t{%2, %k0|%k0, %2}"
6698 [(set_attr "type" "alu")
6699 (set_attr "mode" "SI")])
6701 (define_insn "*subqi_1_slp"
6702 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6703 (minus:QI (match_dup 0)
6704 (match_operand:QI 1 "general_operand" "qn,qm")))
6705 (clobber (reg:CC FLAGS_REG))]
6706 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6707 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6708 "sub{b}\t{%1, %0|%0, %1}"
6709 [(set_attr "type" "alu1")
6710 (set_attr "mode" "QI")])
6712 (define_insn "*sub<mode>_2"
6713 [(set (reg FLAGS_REG)
6716 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6717 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6719 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6720 (minus:SWI (match_dup 1) (match_dup 2)))]
6721 "ix86_match_ccmode (insn, CCGOCmode)
6722 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6723 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6724 [(set_attr "type" "alu")
6725 (set_attr "mode" "<MODE>")])
6727 (define_insn "*subsi_2_zext"
6728 [(set (reg FLAGS_REG)
6730 (minus:SI (match_operand:SI 1 "register_operand" "0")
6731 (match_operand:SI 2 "general_operand" "g"))
6733 (set (match_operand:DI 0 "register_operand" "=r")
6735 (minus:SI (match_dup 1)
6737 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6738 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6739 "sub{l}\t{%2, %k0|%k0, %2}"
6740 [(set_attr "type" "alu")
6741 (set_attr "mode" "SI")])
6743 (define_insn "*sub<mode>_3"
6744 [(set (reg FLAGS_REG)
6745 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6746 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6747 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6748 (minus:SWI (match_dup 1) (match_dup 2)))]
6749 "ix86_match_ccmode (insn, CCmode)
6750 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6751 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6752 [(set_attr "type" "alu")
6753 (set_attr "mode" "<MODE>")])
6755 (define_insn "*subsi_3_zext"
6756 [(set (reg FLAGS_REG)
6757 (compare (match_operand:SI 1 "register_operand" "0")
6758 (match_operand:SI 2 "general_operand" "g")))
6759 (set (match_operand:DI 0 "register_operand" "=r")
6761 (minus:SI (match_dup 1)
6763 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6764 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6765 "sub{l}\t{%2, %1|%1, %2}"
6766 [(set_attr "type" "alu")
6767 (set_attr "mode" "SI")])
6769 ;; Add with carry and subtract with borrow
6771 (define_expand "<plusminus_insn><mode>3_carry"
6773 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6775 (match_operand:SWI 1 "nonimmediate_operand" "")
6776 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6777 [(match_operand 3 "flags_reg_operand" "")
6779 (match_operand:SWI 2 "<general_operand>" ""))))
6780 (clobber (reg:CC FLAGS_REG))])]
6781 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6783 (define_insn "*<plusminus_insn><mode>3_carry"
6784 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6786 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6788 (match_operator 3 "ix86_carry_flag_operator"
6789 [(reg FLAGS_REG) (const_int 0)])
6790 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6791 (clobber (reg:CC FLAGS_REG))]
6792 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6793 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6794 [(set_attr "type" "alu")
6795 (set_attr "use_carry" "1")
6796 (set_attr "pent_pair" "pu")
6797 (set_attr "mode" "<MODE>")])
6799 (define_insn "*addsi3_carry_zext"
6800 [(set (match_operand:DI 0 "register_operand" "=r")
6802 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6803 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6804 [(reg FLAGS_REG) (const_int 0)])
6805 (match_operand:SI 2 "general_operand" "g")))))
6806 (clobber (reg:CC FLAGS_REG))]
6807 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6808 "adc{l}\t{%2, %k0|%k0, %2}"
6809 [(set_attr "type" "alu")
6810 (set_attr "use_carry" "1")
6811 (set_attr "pent_pair" "pu")
6812 (set_attr "mode" "SI")])
6814 (define_insn "*subsi3_carry_zext"
6815 [(set (match_operand:DI 0 "register_operand" "=r")
6817 (minus:SI (match_operand:SI 1 "register_operand" "0")
6818 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6819 [(reg FLAGS_REG) (const_int 0)])
6820 (match_operand:SI 2 "general_operand" "g")))))
6821 (clobber (reg:CC FLAGS_REG))]
6822 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6823 "sbb{l}\t{%2, %k0|%k0, %2}"
6824 [(set_attr "type" "alu")
6825 (set_attr "pent_pair" "pu")
6826 (set_attr "mode" "SI")])
6828 ;; Overflow setting add and subtract instructions
6830 (define_insn "*add<mode>3_cconly_overflow"
6831 [(set (reg:CCC FLAGS_REG)
6834 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6835 (match_operand:SWI 2 "<general_operand>" "<g>"))
6837 (clobber (match_scratch:SWI 0 "=<r>"))]
6838 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6839 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6840 [(set_attr "type" "alu")
6841 (set_attr "mode" "<MODE>")])
6843 (define_insn "*sub<mode>3_cconly_overflow"
6844 [(set (reg:CCC FLAGS_REG)
6847 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6848 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6851 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6852 [(set_attr "type" "icmp")
6853 (set_attr "mode" "<MODE>")])
6855 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6856 [(set (reg:CCC FLAGS_REG)
6859 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6860 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6862 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6863 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6864 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6865 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6866 [(set_attr "type" "alu")
6867 (set_attr "mode" "<MODE>")])
6869 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6870 [(set (reg:CCC FLAGS_REG)
6873 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6874 (match_operand:SI 2 "general_operand" "g"))
6876 (set (match_operand:DI 0 "register_operand" "=r")
6877 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6878 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6879 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6880 [(set_attr "type" "alu")
6881 (set_attr "mode" "SI")])
6883 ;; The patterns that match these are at the end of this file.
6885 (define_expand "<plusminus_insn>xf3"
6886 [(set (match_operand:XF 0 "register_operand" "")
6888 (match_operand:XF 1 "register_operand" "")
6889 (match_operand:XF 2 "register_operand" "")))]
6892 (define_expand "<plusminus_insn><mode>3"
6893 [(set (match_operand:MODEF 0 "register_operand" "")
6895 (match_operand:MODEF 1 "register_operand" "")
6896 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6897 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6898 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6900 ;; Multiply instructions
6902 (define_expand "mul<mode>3"
6903 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6905 (match_operand:SWIM248 1 "register_operand" "")
6906 (match_operand:SWIM248 2 "<general_operand>" "")))
6907 (clobber (reg:CC FLAGS_REG))])])
6909 (define_expand "mulqi3"
6910 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6912 (match_operand:QI 1 "register_operand" "")
6913 (match_operand:QI 2 "nonimmediate_operand" "")))
6914 (clobber (reg:CC FLAGS_REG))])]
6915 "TARGET_QIMODE_MATH")
6918 ;; IMUL reg32/64, reg32/64, imm8 Direct
6919 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6920 ;; IMUL reg32/64, reg32/64, imm32 Direct
6921 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6922 ;; IMUL reg32/64, reg32/64 Direct
6923 ;; IMUL reg32/64, mem32/64 Direct
6925 ;; On BDVER1, all above IMULs use DirectPath
6927 (define_insn "*mul<mode>3_1"
6928 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6930 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6931 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6932 (clobber (reg:CC FLAGS_REG))]
6933 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6935 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6936 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6937 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6938 [(set_attr "type" "imul")
6939 (set_attr "prefix_0f" "0,0,1")
6940 (set (attr "athlon_decode")
6941 (cond [(eq_attr "cpu" "athlon")
6942 (const_string "vector")
6943 (eq_attr "alternative" "1")
6944 (const_string "vector")
6945 (and (eq_attr "alternative" "2")
6946 (match_operand 1 "memory_operand" ""))
6947 (const_string "vector")]
6948 (const_string "direct")))
6949 (set (attr "amdfam10_decode")
6950 (cond [(and (eq_attr "alternative" "0,1")
6951 (match_operand 1 "memory_operand" ""))
6952 (const_string "vector")]
6953 (const_string "direct")))
6954 (set_attr "bdver1_decode" "direct")
6955 (set_attr "mode" "<MODE>")])
6957 (define_insn "*mulsi3_1_zext"
6958 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6960 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6961 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6962 (clobber (reg:CC FLAGS_REG))]
6964 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6966 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6967 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6968 imul{l}\t{%2, %k0|%k0, %2}"
6969 [(set_attr "type" "imul")
6970 (set_attr "prefix_0f" "0,0,1")
6971 (set (attr "athlon_decode")
6972 (cond [(eq_attr "cpu" "athlon")
6973 (const_string "vector")
6974 (eq_attr "alternative" "1")
6975 (const_string "vector")
6976 (and (eq_attr "alternative" "2")
6977 (match_operand 1 "memory_operand" ""))
6978 (const_string "vector")]
6979 (const_string "direct")))
6980 (set (attr "amdfam10_decode")
6981 (cond [(and (eq_attr "alternative" "0,1")
6982 (match_operand 1 "memory_operand" ""))
6983 (const_string "vector")]
6984 (const_string "direct")))
6985 (set_attr "bdver1_decode" "direct")
6986 (set_attr "mode" "SI")])
6989 ;; IMUL reg16, reg16, imm8 VectorPath
6990 ;; IMUL reg16, mem16, imm8 VectorPath
6991 ;; IMUL reg16, reg16, imm16 VectorPath
6992 ;; IMUL reg16, mem16, imm16 VectorPath
6993 ;; IMUL reg16, reg16 Direct
6994 ;; IMUL reg16, mem16 Direct
6996 ;; On BDVER1, all HI MULs use DoublePath
6998 (define_insn "*mulhi3_1"
6999 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7000 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7001 (match_operand:HI 2 "general_operand" "K,n,mr")))
7002 (clobber (reg:CC FLAGS_REG))]
7004 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7006 imul{w}\t{%2, %1, %0|%0, %1, %2}
7007 imul{w}\t{%2, %1, %0|%0, %1, %2}
7008 imul{w}\t{%2, %0|%0, %2}"
7009 [(set_attr "type" "imul")
7010 (set_attr "prefix_0f" "0,0,1")
7011 (set (attr "athlon_decode")
7012 (cond [(eq_attr "cpu" "athlon")
7013 (const_string "vector")
7014 (eq_attr "alternative" "1,2")
7015 (const_string "vector")]
7016 (const_string "direct")))
7017 (set (attr "amdfam10_decode")
7018 (cond [(eq_attr "alternative" "0,1")
7019 (const_string "vector")]
7020 (const_string "direct")))
7021 (set_attr "bdver1_decode" "double")
7022 (set_attr "mode" "HI")])
7024 ;;On AMDFAM10 and BDVER1
7028 (define_insn "*mulqi3_1"
7029 [(set (match_operand:QI 0 "register_operand" "=a")
7030 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7031 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7032 (clobber (reg:CC FLAGS_REG))]
7034 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7036 [(set_attr "type" "imul")
7037 (set_attr "length_immediate" "0")
7038 (set (attr "athlon_decode")
7039 (if_then_else (eq_attr "cpu" "athlon")
7040 (const_string "vector")
7041 (const_string "direct")))
7042 (set_attr "amdfam10_decode" "direct")
7043 (set_attr "bdver1_decode" "direct")
7044 (set_attr "mode" "QI")])
7046 (define_expand "<u>mul<mode><dwi>3"
7047 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7050 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7052 (match_operand:DWIH 2 "register_operand" ""))))
7053 (clobber (reg:CC FLAGS_REG))])])
7055 (define_expand "<u>mulqihi3"
7056 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7059 (match_operand:QI 1 "nonimmediate_operand" ""))
7061 (match_operand:QI 2 "register_operand" ""))))
7062 (clobber (reg:CC FLAGS_REG))])]
7063 "TARGET_QIMODE_MATH")
7065 (define_insn "*<u>mul<mode><dwi>3_1"
7066 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7069 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7071 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7072 (clobber (reg:CC FLAGS_REG))]
7073 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7074 "<sgnprefix>mul{<imodesuffix>}\t%2"
7075 [(set_attr "type" "imul")
7076 (set_attr "length_immediate" "0")
7077 (set (attr "athlon_decode")
7078 (if_then_else (eq_attr "cpu" "athlon")
7079 (const_string "vector")
7080 (const_string "double")))
7081 (set_attr "amdfam10_decode" "double")
7082 (set_attr "bdver1_decode" "direct")
7083 (set_attr "mode" "<MODE>")])
7085 (define_insn "*<u>mulqihi3_1"
7086 [(set (match_operand:HI 0 "register_operand" "=a")
7089 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7091 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7092 (clobber (reg:CC FLAGS_REG))]
7094 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7095 "<sgnprefix>mul{b}\t%2"
7096 [(set_attr "type" "imul")
7097 (set_attr "length_immediate" "0")
7098 (set (attr "athlon_decode")
7099 (if_then_else (eq_attr "cpu" "athlon")
7100 (const_string "vector")
7101 (const_string "direct")))
7102 (set_attr "amdfam10_decode" "direct")
7103 (set_attr "bdver1_decode" "direct")
7104 (set_attr "mode" "QI")])
7106 (define_expand "<s>mul<mode>3_highpart"
7107 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7112 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7114 (match_operand:SWI48 2 "register_operand" "")))
7116 (clobber (match_scratch:SWI48 3 ""))
7117 (clobber (reg:CC FLAGS_REG))])]
7119 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7121 (define_insn "*<s>muldi3_highpart_1"
7122 [(set (match_operand:DI 0 "register_operand" "=d")
7127 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7129 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7131 (clobber (match_scratch:DI 3 "=1"))
7132 (clobber (reg:CC FLAGS_REG))]
7134 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7135 "<sgnprefix>mul{q}\t%2"
7136 [(set_attr "type" "imul")
7137 (set_attr "length_immediate" "0")
7138 (set (attr "athlon_decode")
7139 (if_then_else (eq_attr "cpu" "athlon")
7140 (const_string "vector")
7141 (const_string "double")))
7142 (set_attr "amdfam10_decode" "double")
7143 (set_attr "bdver1_decode" "direct")
7144 (set_attr "mode" "DI")])
7146 (define_insn "*<s>mulsi3_highpart_1"
7147 [(set (match_operand:SI 0 "register_operand" "=d")
7152 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7154 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7156 (clobber (match_scratch:SI 3 "=1"))
7157 (clobber (reg:CC FLAGS_REG))]
7158 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7159 "<sgnprefix>mul{l}\t%2"
7160 [(set_attr "type" "imul")
7161 (set_attr "length_immediate" "0")
7162 (set (attr "athlon_decode")
7163 (if_then_else (eq_attr "cpu" "athlon")
7164 (const_string "vector")
7165 (const_string "double")))
7166 (set_attr "amdfam10_decode" "double")
7167 (set_attr "bdver1_decode" "direct")
7168 (set_attr "mode" "SI")])
7170 (define_insn "*<s>mulsi3_highpart_zext"
7171 [(set (match_operand:DI 0 "register_operand" "=d")
7172 (zero_extend:DI (truncate:SI
7174 (mult:DI (any_extend:DI
7175 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7177 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7179 (clobber (match_scratch:SI 3 "=1"))
7180 (clobber (reg:CC FLAGS_REG))]
7182 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7183 "<sgnprefix>mul{l}\t%2"
7184 [(set_attr "type" "imul")
7185 (set_attr "length_immediate" "0")
7186 (set (attr "athlon_decode")
7187 (if_then_else (eq_attr "cpu" "athlon")
7188 (const_string "vector")
7189 (const_string "double")))
7190 (set_attr "amdfam10_decode" "double")
7191 (set_attr "bdver1_decode" "direct")
7192 (set_attr "mode" "SI")])
7194 ;; The patterns that match these are at the end of this file.
7196 (define_expand "mulxf3"
7197 [(set (match_operand:XF 0 "register_operand" "")
7198 (mult:XF (match_operand:XF 1 "register_operand" "")
7199 (match_operand:XF 2 "register_operand" "")))]
7202 (define_expand "mul<mode>3"
7203 [(set (match_operand:MODEF 0 "register_operand" "")
7204 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7205 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7206 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7207 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7209 ;; Divide instructions
7211 ;; The patterns that match these are at the end of this file.
7213 (define_expand "divxf3"
7214 [(set (match_operand:XF 0 "register_operand" "")
7215 (div:XF (match_operand:XF 1 "register_operand" "")
7216 (match_operand:XF 2 "register_operand" "")))]
7219 (define_expand "divdf3"
7220 [(set (match_operand:DF 0 "register_operand" "")
7221 (div:DF (match_operand:DF 1 "register_operand" "")
7222 (match_operand:DF 2 "nonimmediate_operand" "")))]
7223 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7224 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7226 (define_expand "divsf3"
7227 [(set (match_operand:SF 0 "register_operand" "")
7228 (div:SF (match_operand:SF 1 "register_operand" "")
7229 (match_operand:SF 2 "nonimmediate_operand" "")))]
7230 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7233 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7234 && flag_finite_math_only && !flag_trapping_math
7235 && flag_unsafe_math_optimizations)
7237 ix86_emit_swdivsf (operands[0], operands[1],
7238 operands[2], SFmode);
7243 ;; Divmod instructions.
7245 (define_expand "divmod<mode>4"
7246 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7248 (match_operand:SWIM248 1 "register_operand" "")
7249 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7250 (set (match_operand:SWIM248 3 "register_operand" "")
7251 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7252 (clobber (reg:CC FLAGS_REG))])])
7254 ;; Split with 8bit unsigned divide:
7255 ;; if (dividend an divisor are in [0-255])
7256 ;; use 8bit unsigned integer divide
7258 ;; use original integer divide
7260 [(set (match_operand:SWI48 0 "register_operand" "")
7261 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7262 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7263 (set (match_operand:SWI48 1 "register_operand" "")
7264 (mod:SWI48 (match_dup 2) (match_dup 3)))
7265 (clobber (reg:CC FLAGS_REG))]
7266 "TARGET_USE_8BIT_IDIV
7267 && TARGET_QIMODE_MATH
7268 && can_create_pseudo_p ()
7269 && !optimize_insn_for_size_p ()"
7271 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7273 (define_insn_and_split "divmod<mode>4_1"
7274 [(set (match_operand:SWI48 0 "register_operand" "=a")
7275 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7276 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7277 (set (match_operand:SWI48 1 "register_operand" "=&d")
7278 (mod:SWI48 (match_dup 2) (match_dup 3)))
7279 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7280 (clobber (reg:CC FLAGS_REG))]
7284 [(parallel [(set (match_dup 1)
7285 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7286 (clobber (reg:CC FLAGS_REG))])
7287 (parallel [(set (match_dup 0)
7288 (div:SWI48 (match_dup 2) (match_dup 3)))
7290 (mod:SWI48 (match_dup 2) (match_dup 3)))
7292 (clobber (reg:CC FLAGS_REG))])]
7294 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7296 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7297 operands[4] = operands[2];
7300 /* Avoid use of cltd in favor of a mov+shift. */
7301 emit_move_insn (operands[1], operands[2]);
7302 operands[4] = operands[1];
7305 [(set_attr "type" "multi")
7306 (set_attr "mode" "<MODE>")])
7308 (define_insn_and_split "*divmod<mode>4"
7309 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7310 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7311 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7312 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7313 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7314 (clobber (reg:CC FLAGS_REG))]
7318 [(parallel [(set (match_dup 1)
7319 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7320 (clobber (reg:CC FLAGS_REG))])
7321 (parallel [(set (match_dup 0)
7322 (div:SWIM248 (match_dup 2) (match_dup 3)))
7324 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7326 (clobber (reg:CC FLAGS_REG))])]
7328 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7330 if (<MODE>mode != HImode
7331 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7332 operands[4] = operands[2];
7335 /* Avoid use of cltd in favor of a mov+shift. */
7336 emit_move_insn (operands[1], operands[2]);
7337 operands[4] = operands[1];
7340 [(set_attr "type" "multi")
7341 (set_attr "mode" "<MODE>")])
7343 (define_insn "*divmod<mode>4_noext"
7344 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7345 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7346 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7347 (set (match_operand:SWIM248 1 "register_operand" "=d")
7348 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7349 (use (match_operand:SWIM248 4 "register_operand" "1"))
7350 (clobber (reg:CC FLAGS_REG))]
7352 "idiv{<imodesuffix>}\t%3"
7353 [(set_attr "type" "idiv")
7354 (set_attr "mode" "<MODE>")])
7356 (define_expand "divmodqi4"
7357 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7359 (match_operand:QI 1 "register_operand" "")
7360 (match_operand:QI 2 "nonimmediate_operand" "")))
7361 (set (match_operand:QI 3 "register_operand" "")
7362 (mod:QI (match_dup 1) (match_dup 2)))
7363 (clobber (reg:CC FLAGS_REG))])]
7364 "TARGET_QIMODE_MATH"
7369 tmp0 = gen_reg_rtx (HImode);
7370 tmp1 = gen_reg_rtx (HImode);
7372 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7374 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7375 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7377 /* Extract remainder from AH. */
7378 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7379 insn = emit_move_insn (operands[3], tmp1);
7381 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7382 set_unique_reg_note (insn, REG_EQUAL, mod);
7384 /* Extract quotient from AL. */
7385 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7387 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7388 set_unique_reg_note (insn, REG_EQUAL, div);
7393 ;; Divide AX by r/m8, with result stored in
7396 ;; Change div/mod to HImode and extend the second argument to HImode
7397 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7398 ;; combine may fail.
7399 (define_insn "divmodhiqi3"
7400 [(set (match_operand:HI 0 "register_operand" "=a")
7405 (mod:HI (match_operand:HI 1 "register_operand" "0")
7407 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7411 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7412 (clobber (reg:CC FLAGS_REG))]
7413 "TARGET_QIMODE_MATH"
7415 [(set_attr "type" "idiv")
7416 (set_attr "mode" "QI")])
7418 (define_expand "udivmod<mode>4"
7419 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7421 (match_operand:SWIM248 1 "register_operand" "")
7422 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7423 (set (match_operand:SWIM248 3 "register_operand" "")
7424 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7425 (clobber (reg:CC FLAGS_REG))])])
7427 ;; Split with 8bit unsigned divide:
7428 ;; if (dividend an divisor are in [0-255])
7429 ;; use 8bit unsigned integer divide
7431 ;; use original integer divide
7433 [(set (match_operand:SWI48 0 "register_operand" "")
7434 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7435 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7436 (set (match_operand:SWI48 1 "register_operand" "")
7437 (umod:SWI48 (match_dup 2) (match_dup 3)))
7438 (clobber (reg:CC FLAGS_REG))]
7439 "TARGET_USE_8BIT_IDIV
7440 && TARGET_QIMODE_MATH
7441 && can_create_pseudo_p ()
7442 && !optimize_insn_for_size_p ()"
7444 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7446 (define_insn_and_split "udivmod<mode>4_1"
7447 [(set (match_operand:SWI48 0 "register_operand" "=a")
7448 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7449 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7450 (set (match_operand:SWI48 1 "register_operand" "=&d")
7451 (umod:SWI48 (match_dup 2) (match_dup 3)))
7452 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7453 (clobber (reg:CC FLAGS_REG))]
7457 [(set (match_dup 1) (const_int 0))
7458 (parallel [(set (match_dup 0)
7459 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7461 (umod:SWI48 (match_dup 2) (match_dup 3)))
7463 (clobber (reg:CC FLAGS_REG))])]
7465 [(set_attr "type" "multi")
7466 (set_attr "mode" "<MODE>")])
7468 (define_insn_and_split "*udivmod<mode>4"
7469 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7470 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7471 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7472 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7473 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7474 (clobber (reg:CC FLAGS_REG))]
7478 [(set (match_dup 1) (const_int 0))
7479 (parallel [(set (match_dup 0)
7480 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7482 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7484 (clobber (reg:CC FLAGS_REG))])]
7486 [(set_attr "type" "multi")
7487 (set_attr "mode" "<MODE>")])
7489 (define_insn "*udivmod<mode>4_noext"
7490 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7491 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7492 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7493 (set (match_operand:SWIM248 1 "register_operand" "=d")
7494 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7495 (use (match_operand:SWIM248 4 "register_operand" "1"))
7496 (clobber (reg:CC FLAGS_REG))]
7498 "div{<imodesuffix>}\t%3"
7499 [(set_attr "type" "idiv")
7500 (set_attr "mode" "<MODE>")])
7502 (define_expand "udivmodqi4"
7503 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7505 (match_operand:QI 1 "register_operand" "")
7506 (match_operand:QI 2 "nonimmediate_operand" "")))
7507 (set (match_operand:QI 3 "register_operand" "")
7508 (umod:QI (match_dup 1) (match_dup 2)))
7509 (clobber (reg:CC FLAGS_REG))])]
7510 "TARGET_QIMODE_MATH"
7515 tmp0 = gen_reg_rtx (HImode);
7516 tmp1 = gen_reg_rtx (HImode);
7518 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7520 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7521 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7523 /* Extract remainder from AH. */
7524 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7525 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7526 insn = emit_move_insn (operands[3], tmp1);
7528 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7529 set_unique_reg_note (insn, REG_EQUAL, mod);
7531 /* Extract quotient from AL. */
7532 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7534 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7535 set_unique_reg_note (insn, REG_EQUAL, div);
7540 (define_insn "udivmodhiqi3"
7541 [(set (match_operand:HI 0 "register_operand" "=a")
7546 (mod:HI (match_operand:HI 1 "register_operand" "0")
7548 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7552 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7553 (clobber (reg:CC FLAGS_REG))]
7554 "TARGET_QIMODE_MATH"
7556 [(set_attr "type" "idiv")
7557 (set_attr "mode" "QI")])
7559 ;; We cannot use div/idiv for double division, because it causes
7560 ;; "division by zero" on the overflow and that's not what we expect
7561 ;; from truncate. Because true (non truncating) double division is
7562 ;; never generated, we can't create this insn anyway.
7565 ; [(set (match_operand:SI 0 "register_operand" "=a")
7567 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7569 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7570 ; (set (match_operand:SI 3 "register_operand" "=d")
7572 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7573 ; (clobber (reg:CC FLAGS_REG))]
7575 ; "div{l}\t{%2, %0|%0, %2}"
7576 ; [(set_attr "type" "idiv")])
7578 ;;- Logical AND instructions
7580 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7581 ;; Note that this excludes ah.
7583 (define_expand "testsi_ccno_1"
7584 [(set (reg:CCNO FLAGS_REG)
7586 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7587 (match_operand:SI 1 "nonmemory_operand" ""))
7590 (define_expand "testqi_ccz_1"
7591 [(set (reg:CCZ FLAGS_REG)
7592 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7593 (match_operand:QI 1 "nonmemory_operand" ""))
7596 (define_expand "testdi_ccno_1"
7597 [(set (reg:CCNO FLAGS_REG)
7599 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7600 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7602 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7604 (define_insn "*testdi_1"
7605 [(set (reg FLAGS_REG)
7608 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7609 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7611 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7612 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7614 test{l}\t{%k1, %k0|%k0, %k1}
7615 test{l}\t{%k1, %k0|%k0, %k1}
7616 test{q}\t{%1, %0|%0, %1}
7617 test{q}\t{%1, %0|%0, %1}
7618 test{q}\t{%1, %0|%0, %1}"
7619 [(set_attr "type" "test")
7620 (set_attr "modrm" "0,1,0,1,1")
7621 (set_attr "mode" "SI,SI,DI,DI,DI")])
7623 (define_insn "*testqi_1_maybe_si"
7624 [(set (reg FLAGS_REG)
7627 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7628 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7630 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7631 && ix86_match_ccmode (insn,
7632 CONST_INT_P (operands[1])
7633 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7635 if (which_alternative == 3)
7637 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7638 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7639 return "test{l}\t{%1, %k0|%k0, %1}";
7641 return "test{b}\t{%1, %0|%0, %1}";
7643 [(set_attr "type" "test")
7644 (set_attr "modrm" "0,1,1,1")
7645 (set_attr "mode" "QI,QI,QI,SI")
7646 (set_attr "pent_pair" "uv,np,uv,np")])
7648 (define_insn "*test<mode>_1"
7649 [(set (reg FLAGS_REG)
7652 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7653 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7655 "ix86_match_ccmode (insn, CCNOmode)
7656 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7657 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7658 [(set_attr "type" "test")
7659 (set_attr "modrm" "0,1,1")
7660 (set_attr "mode" "<MODE>")
7661 (set_attr "pent_pair" "uv,np,uv")])
7663 (define_expand "testqi_ext_ccno_0"
7664 [(set (reg:CCNO FLAGS_REG)
7668 (match_operand 0 "ext_register_operand" "")
7671 (match_operand 1 "const_int_operand" ""))
7674 (define_insn "*testqi_ext_0"
7675 [(set (reg FLAGS_REG)
7679 (match_operand 0 "ext_register_operand" "Q")
7682 (match_operand 1 "const_int_operand" "n"))
7684 "ix86_match_ccmode (insn, CCNOmode)"
7685 "test{b}\t{%1, %h0|%h0, %1}"
7686 [(set_attr "type" "test")
7687 (set_attr "mode" "QI")
7688 (set_attr "length_immediate" "1")
7689 (set_attr "modrm" "1")
7690 (set_attr "pent_pair" "np")])
7692 (define_insn "*testqi_ext_1_rex64"
7693 [(set (reg FLAGS_REG)
7697 (match_operand 0 "ext_register_operand" "Q")
7701 (match_operand:QI 1 "register_operand" "Q")))
7703 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7704 "test{b}\t{%1, %h0|%h0, %1}"
7705 [(set_attr "type" "test")
7706 (set_attr "mode" "QI")])
7708 (define_insn "*testqi_ext_1"
7709 [(set (reg FLAGS_REG)
7713 (match_operand 0 "ext_register_operand" "Q")
7717 (match_operand:QI 1 "general_operand" "Qm")))
7719 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7720 "test{b}\t{%1, %h0|%h0, %1}"
7721 [(set_attr "type" "test")
7722 (set_attr "mode" "QI")])
7724 (define_insn "*testqi_ext_2"
7725 [(set (reg FLAGS_REG)
7729 (match_operand 0 "ext_register_operand" "Q")
7733 (match_operand 1 "ext_register_operand" "Q")
7737 "ix86_match_ccmode (insn, CCNOmode)"
7738 "test{b}\t{%h1, %h0|%h0, %h1}"
7739 [(set_attr "type" "test")
7740 (set_attr "mode" "QI")])
7742 (define_insn "*testqi_ext_3_rex64"
7743 [(set (reg FLAGS_REG)
7744 (compare (zero_extract:DI
7745 (match_operand 0 "nonimmediate_operand" "rm")
7746 (match_operand:DI 1 "const_int_operand" "")
7747 (match_operand:DI 2 "const_int_operand" ""))
7750 && ix86_match_ccmode (insn, CCNOmode)
7751 && INTVAL (operands[1]) > 0
7752 && INTVAL (operands[2]) >= 0
7753 /* Ensure that resulting mask is zero or sign extended operand. */
7754 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7755 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7756 && INTVAL (operands[1]) > 32))
7757 && (GET_MODE (operands[0]) == SImode
7758 || GET_MODE (operands[0]) == DImode
7759 || GET_MODE (operands[0]) == HImode
7760 || GET_MODE (operands[0]) == QImode)"
7763 ;; Combine likes to form bit extractions for some tests. Humor it.
7764 (define_insn "*testqi_ext_3"
7765 [(set (reg FLAGS_REG)
7766 (compare (zero_extract:SI
7767 (match_operand 0 "nonimmediate_operand" "rm")
7768 (match_operand:SI 1 "const_int_operand" "")
7769 (match_operand:SI 2 "const_int_operand" ""))
7771 "ix86_match_ccmode (insn, CCNOmode)
7772 && INTVAL (operands[1]) > 0
7773 && INTVAL (operands[2]) >= 0
7774 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7775 && (GET_MODE (operands[0]) == SImode
7776 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7777 || GET_MODE (operands[0]) == HImode
7778 || GET_MODE (operands[0]) == QImode)"
7782 [(set (match_operand 0 "flags_reg_operand" "")
7783 (match_operator 1 "compare_operator"
7785 (match_operand 2 "nonimmediate_operand" "")
7786 (match_operand 3 "const_int_operand" "")
7787 (match_operand 4 "const_int_operand" ""))
7789 "ix86_match_ccmode (insn, CCNOmode)"
7790 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7792 rtx val = operands[2];
7793 HOST_WIDE_INT len = INTVAL (operands[3]);
7794 HOST_WIDE_INT pos = INTVAL (operands[4]);
7796 enum machine_mode mode, submode;
7798 mode = GET_MODE (val);
7801 /* ??? Combine likes to put non-volatile mem extractions in QImode
7802 no matter the size of the test. So find a mode that works. */
7803 if (! MEM_VOLATILE_P (val))
7805 mode = smallest_mode_for_size (pos + len, MODE_INT);
7806 val = adjust_address (val, mode, 0);
7809 else if (GET_CODE (val) == SUBREG
7810 && (submode = GET_MODE (SUBREG_REG (val)),
7811 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7812 && pos + len <= GET_MODE_BITSIZE (submode)
7813 && GET_MODE_CLASS (submode) == MODE_INT)
7815 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7817 val = SUBREG_REG (val);
7819 else if (mode == HImode && pos + len <= 8)
7821 /* Small HImode tests can be converted to QImode. */
7823 val = gen_lowpart (QImode, val);
7826 if (len == HOST_BITS_PER_WIDE_INT)
7829 mask = ((HOST_WIDE_INT)1 << len) - 1;
7832 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7835 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7836 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7837 ;; this is relatively important trick.
7838 ;; Do the conversion only post-reload to avoid limiting of the register class
7841 [(set (match_operand 0 "flags_reg_operand" "")
7842 (match_operator 1 "compare_operator"
7843 [(and (match_operand 2 "register_operand" "")
7844 (match_operand 3 "const_int_operand" ""))
7847 && QI_REG_P (operands[2])
7848 && GET_MODE (operands[2]) != QImode
7849 && ((ix86_match_ccmode (insn, CCZmode)
7850 && !(INTVAL (operands[3]) & ~(255 << 8)))
7851 || (ix86_match_ccmode (insn, CCNOmode)
7852 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7855 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7858 "operands[2] = gen_lowpart (SImode, operands[2]);
7859 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7862 [(set (match_operand 0 "flags_reg_operand" "")
7863 (match_operator 1 "compare_operator"
7864 [(and (match_operand 2 "nonimmediate_operand" "")
7865 (match_operand 3 "const_int_operand" ""))
7868 && GET_MODE (operands[2]) != QImode
7869 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7870 && ((ix86_match_ccmode (insn, CCZmode)
7871 && !(INTVAL (operands[3]) & ~255))
7872 || (ix86_match_ccmode (insn, CCNOmode)
7873 && !(INTVAL (operands[3]) & ~127)))"
7875 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7877 "operands[2] = gen_lowpart (QImode, operands[2]);
7878 operands[3] = gen_lowpart (QImode, operands[3]);")
7880 ;; %%% This used to optimize known byte-wide and operations to memory,
7881 ;; and sometimes to QImode registers. If this is considered useful,
7882 ;; it should be done with splitters.
7884 (define_expand "and<mode>3"
7885 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7886 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7887 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7889 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7891 (define_insn "*anddi_1"
7892 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7894 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7895 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7896 (clobber (reg:CC FLAGS_REG))]
7897 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7899 switch (get_attr_type (insn))
7903 enum machine_mode mode;
7905 gcc_assert (CONST_INT_P (operands[2]));
7906 if (INTVAL (operands[2]) == 0xff)
7910 gcc_assert (INTVAL (operands[2]) == 0xffff);
7914 operands[1] = gen_lowpart (mode, operands[1]);
7916 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7918 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7922 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7923 if (get_attr_mode (insn) == MODE_SI)
7924 return "and{l}\t{%k2, %k0|%k0, %k2}";
7926 return "and{q}\t{%2, %0|%0, %2}";
7929 [(set_attr "type" "alu,alu,alu,imovx")
7930 (set_attr "length_immediate" "*,*,*,0")
7931 (set (attr "prefix_rex")
7933 (and (eq_attr "type" "imovx")
7934 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7935 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7937 (const_string "*")))
7938 (set_attr "mode" "SI,DI,DI,SI")])
7940 (define_insn "*andsi_1"
7941 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7942 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7943 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7944 (clobber (reg:CC FLAGS_REG))]
7945 "ix86_binary_operator_ok (AND, SImode, operands)"
7947 switch (get_attr_type (insn))
7951 enum machine_mode mode;
7953 gcc_assert (CONST_INT_P (operands[2]));
7954 if (INTVAL (operands[2]) == 0xff)
7958 gcc_assert (INTVAL (operands[2]) == 0xffff);
7962 operands[1] = gen_lowpart (mode, operands[1]);
7964 return "movz{bl|x}\t{%1, %0|%0, %1}";
7966 return "movz{wl|x}\t{%1, %0|%0, %1}";
7970 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7971 return "and{l}\t{%2, %0|%0, %2}";
7974 [(set_attr "type" "alu,alu,imovx")
7975 (set (attr "prefix_rex")
7977 (and (eq_attr "type" "imovx")
7978 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7979 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7981 (const_string "*")))
7982 (set_attr "length_immediate" "*,*,0")
7983 (set_attr "mode" "SI")])
7985 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7986 (define_insn "*andsi_1_zext"
7987 [(set (match_operand:DI 0 "register_operand" "=r")
7989 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7990 (match_operand:SI 2 "general_operand" "g"))))
7991 (clobber (reg:CC FLAGS_REG))]
7992 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7993 "and{l}\t{%2, %k0|%k0, %2}"
7994 [(set_attr "type" "alu")
7995 (set_attr "mode" "SI")])
7997 (define_insn "*andhi_1"
7998 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7999 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8000 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8001 (clobber (reg:CC FLAGS_REG))]
8002 "ix86_binary_operator_ok (AND, HImode, operands)"
8004 switch (get_attr_type (insn))
8007 gcc_assert (CONST_INT_P (operands[2]));
8008 gcc_assert (INTVAL (operands[2]) == 0xff);
8009 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8012 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8014 return "and{w}\t{%2, %0|%0, %2}";
8017 [(set_attr "type" "alu,alu,imovx")
8018 (set_attr "length_immediate" "*,*,0")
8019 (set (attr "prefix_rex")
8021 (and (eq_attr "type" "imovx")
8022 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8024 (const_string "*")))
8025 (set_attr "mode" "HI,HI,SI")])
8027 ;; %%% Potential partial reg stall on alternative 2. What to do?
8028 (define_insn "*andqi_1"
8029 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8030 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8031 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8032 (clobber (reg:CC FLAGS_REG))]
8033 "ix86_binary_operator_ok (AND, QImode, operands)"
8035 and{b}\t{%2, %0|%0, %2}
8036 and{b}\t{%2, %0|%0, %2}
8037 and{l}\t{%k2, %k0|%k0, %k2}"
8038 [(set_attr "type" "alu")
8039 (set_attr "mode" "QI,QI,SI")])
8041 (define_insn "*andqi_1_slp"
8042 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8043 (and:QI (match_dup 0)
8044 (match_operand:QI 1 "general_operand" "qn,qmn")))
8045 (clobber (reg:CC FLAGS_REG))]
8046 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8047 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8048 "and{b}\t{%1, %0|%0, %1}"
8049 [(set_attr "type" "alu1")
8050 (set_attr "mode" "QI")])
8053 [(set (match_operand 0 "register_operand" "")
8055 (const_int -65536)))
8056 (clobber (reg:CC FLAGS_REG))]
8057 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8058 || optimize_function_for_size_p (cfun)"
8059 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8060 "operands[1] = gen_lowpart (HImode, operands[0]);")
8063 [(set (match_operand 0 "ext_register_operand" "")
8066 (clobber (reg:CC FLAGS_REG))]
8067 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8068 && reload_completed"
8069 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8070 "operands[1] = gen_lowpart (QImode, operands[0]);")
8073 [(set (match_operand 0 "ext_register_operand" "")
8075 (const_int -65281)))
8076 (clobber (reg:CC FLAGS_REG))]
8077 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8078 && reload_completed"
8079 [(parallel [(set (zero_extract:SI (match_dup 0)
8083 (zero_extract:SI (match_dup 0)
8086 (zero_extract:SI (match_dup 0)
8089 (clobber (reg:CC FLAGS_REG))])]
8090 "operands[0] = gen_lowpart (SImode, operands[0]);")
8092 (define_insn "*anddi_2"
8093 [(set (reg FLAGS_REG)
8096 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8097 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8099 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8100 (and:DI (match_dup 1) (match_dup 2)))]
8101 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8102 && ix86_binary_operator_ok (AND, DImode, operands)"
8104 and{l}\t{%k2, %k0|%k0, %k2}
8105 and{q}\t{%2, %0|%0, %2}
8106 and{q}\t{%2, %0|%0, %2}"
8107 [(set_attr "type" "alu")
8108 (set_attr "mode" "SI,DI,DI")])
8110 (define_insn "*andqi_2_maybe_si"
8111 [(set (reg FLAGS_REG)
8113 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8114 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8116 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8117 (and:QI (match_dup 1) (match_dup 2)))]
8118 "ix86_binary_operator_ok (AND, QImode, operands)
8119 && ix86_match_ccmode (insn,
8120 CONST_INT_P (operands[2])
8121 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8123 if (which_alternative == 2)
8125 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8126 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8127 return "and{l}\t{%2, %k0|%k0, %2}";
8129 return "and{b}\t{%2, %0|%0, %2}";
8131 [(set_attr "type" "alu")
8132 (set_attr "mode" "QI,QI,SI")])
8134 (define_insn "*and<mode>_2"
8135 [(set (reg FLAGS_REG)
8136 (compare (and:SWI124
8137 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8138 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8140 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8141 (and:SWI124 (match_dup 1) (match_dup 2)))]
8142 "ix86_match_ccmode (insn, CCNOmode)
8143 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8144 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8145 [(set_attr "type" "alu")
8146 (set_attr "mode" "<MODE>")])
8148 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8149 (define_insn "*andsi_2_zext"
8150 [(set (reg FLAGS_REG)
8152 (match_operand:SI 1 "nonimmediate_operand" "%0")
8153 (match_operand:SI 2 "general_operand" "g"))
8155 (set (match_operand:DI 0 "register_operand" "=r")
8156 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8157 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8158 && ix86_binary_operator_ok (AND, SImode, operands)"
8159 "and{l}\t{%2, %k0|%k0, %2}"
8160 [(set_attr "type" "alu")
8161 (set_attr "mode" "SI")])
8163 (define_insn "*andqi_2_slp"
8164 [(set (reg FLAGS_REG)
8166 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8167 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8169 (set (strict_low_part (match_dup 0))
8170 (and:QI (match_dup 0) (match_dup 1)))]
8171 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8172 && ix86_match_ccmode (insn, CCNOmode)
8173 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8174 "and{b}\t{%1, %0|%0, %1}"
8175 [(set_attr "type" "alu1")
8176 (set_attr "mode" "QI")])
8178 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8179 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8180 ;; for a QImode operand, which of course failed.
8181 (define_insn "andqi_ext_0"
8182 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8187 (match_operand 1 "ext_register_operand" "0")
8190 (match_operand 2 "const_int_operand" "n")))
8191 (clobber (reg:CC FLAGS_REG))]
8193 "and{b}\t{%2, %h0|%h0, %2}"
8194 [(set_attr "type" "alu")
8195 (set_attr "length_immediate" "1")
8196 (set_attr "modrm" "1")
8197 (set_attr "mode" "QI")])
8199 ;; Generated by peephole translating test to and. This shows up
8200 ;; often in fp comparisons.
8201 (define_insn "*andqi_ext_0_cc"
8202 [(set (reg FLAGS_REG)
8206 (match_operand 1 "ext_register_operand" "0")
8209 (match_operand 2 "const_int_operand" "n"))
8211 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8220 "ix86_match_ccmode (insn, CCNOmode)"
8221 "and{b}\t{%2, %h0|%h0, %2}"
8222 [(set_attr "type" "alu")
8223 (set_attr "length_immediate" "1")
8224 (set_attr "modrm" "1")
8225 (set_attr "mode" "QI")])
8227 (define_insn "*andqi_ext_1_rex64"
8228 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8233 (match_operand 1 "ext_register_operand" "0")
8237 (match_operand 2 "ext_register_operand" "Q"))))
8238 (clobber (reg:CC FLAGS_REG))]
8240 "and{b}\t{%2, %h0|%h0, %2}"
8241 [(set_attr "type" "alu")
8242 (set_attr "length_immediate" "0")
8243 (set_attr "mode" "QI")])
8245 (define_insn "*andqi_ext_1"
8246 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8251 (match_operand 1 "ext_register_operand" "0")
8255 (match_operand:QI 2 "general_operand" "Qm"))))
8256 (clobber (reg:CC FLAGS_REG))]
8258 "and{b}\t{%2, %h0|%h0, %2}"
8259 [(set_attr "type" "alu")
8260 (set_attr "length_immediate" "0")
8261 (set_attr "mode" "QI")])
8263 (define_insn "*andqi_ext_2"
8264 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8269 (match_operand 1 "ext_register_operand" "%0")
8273 (match_operand 2 "ext_register_operand" "Q")
8276 (clobber (reg:CC FLAGS_REG))]
8278 "and{b}\t{%h2, %h0|%h0, %h2}"
8279 [(set_attr "type" "alu")
8280 (set_attr "length_immediate" "0")
8281 (set_attr "mode" "QI")])
8283 ;; Convert wide AND instructions with immediate operand to shorter QImode
8284 ;; equivalents when possible.
8285 ;; Don't do the splitting with memory operands, since it introduces risk
8286 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8287 ;; for size, but that can (should?) be handled by generic code instead.
8289 [(set (match_operand 0 "register_operand" "")
8290 (and (match_operand 1 "register_operand" "")
8291 (match_operand 2 "const_int_operand" "")))
8292 (clobber (reg:CC FLAGS_REG))]
8294 && QI_REG_P (operands[0])
8295 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8296 && !(~INTVAL (operands[2]) & ~(255 << 8))
8297 && GET_MODE (operands[0]) != QImode"
8298 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8299 (and:SI (zero_extract:SI (match_dup 1)
8300 (const_int 8) (const_int 8))
8302 (clobber (reg:CC FLAGS_REG))])]
8303 "operands[0] = gen_lowpart (SImode, operands[0]);
8304 operands[1] = gen_lowpart (SImode, operands[1]);
8305 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8307 ;; Since AND can be encoded with sign extended immediate, this is only
8308 ;; profitable when 7th bit is not set.
8310 [(set (match_operand 0 "register_operand" "")
8311 (and (match_operand 1 "general_operand" "")
8312 (match_operand 2 "const_int_operand" "")))
8313 (clobber (reg:CC FLAGS_REG))]
8315 && ANY_QI_REG_P (operands[0])
8316 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8317 && !(~INTVAL (operands[2]) & ~255)
8318 && !(INTVAL (operands[2]) & 128)
8319 && GET_MODE (operands[0]) != QImode"
8320 [(parallel [(set (strict_low_part (match_dup 0))
8321 (and:QI (match_dup 1)
8323 (clobber (reg:CC FLAGS_REG))])]
8324 "operands[0] = gen_lowpart (QImode, operands[0]);
8325 operands[1] = gen_lowpart (QImode, operands[1]);
8326 operands[2] = gen_lowpart (QImode, operands[2]);")
8328 ;; Logical inclusive and exclusive OR instructions
8330 ;; %%% This used to optimize known byte-wide and operations to memory.
8331 ;; If this is considered useful, it should be done with splitters.
8333 (define_expand "<code><mode>3"
8334 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8335 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8336 (match_operand:SWIM 2 "<general_operand>" "")))]
8338 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8340 (define_insn "*<code><mode>_1"
8341 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8343 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8344 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8345 (clobber (reg:CC FLAGS_REG))]
8346 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8347 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8348 [(set_attr "type" "alu")
8349 (set_attr "mode" "<MODE>")])
8351 ;; %%% Potential partial reg stall on alternative 2. What to do?
8352 (define_insn "*<code>qi_1"
8353 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8354 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8355 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8356 (clobber (reg:CC FLAGS_REG))]
8357 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8359 <logic>{b}\t{%2, %0|%0, %2}
8360 <logic>{b}\t{%2, %0|%0, %2}
8361 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8362 [(set_attr "type" "alu")
8363 (set_attr "mode" "QI,QI,SI")])
8365 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8366 (define_insn "*<code>si_1_zext"
8367 [(set (match_operand:DI 0 "register_operand" "=r")
8369 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8370 (match_operand:SI 2 "general_operand" "g"))))
8371 (clobber (reg:CC FLAGS_REG))]
8372 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8373 "<logic>{l}\t{%2, %k0|%k0, %2}"
8374 [(set_attr "type" "alu")
8375 (set_attr "mode" "SI")])
8377 (define_insn "*<code>si_1_zext_imm"
8378 [(set (match_operand:DI 0 "register_operand" "=r")
8380 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8381 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8382 (clobber (reg:CC FLAGS_REG))]
8383 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8384 "<logic>{l}\t{%2, %k0|%k0, %2}"
8385 [(set_attr "type" "alu")
8386 (set_attr "mode" "SI")])
8388 (define_insn "*<code>qi_1_slp"
8389 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8390 (any_or:QI (match_dup 0)
8391 (match_operand:QI 1 "general_operand" "qmn,qn")))
8392 (clobber (reg:CC FLAGS_REG))]
8393 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8394 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8395 "<logic>{b}\t{%1, %0|%0, %1}"
8396 [(set_attr "type" "alu1")
8397 (set_attr "mode" "QI")])
8399 (define_insn "*<code><mode>_2"
8400 [(set (reg FLAGS_REG)
8401 (compare (any_or:SWI
8402 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8403 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8405 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8406 (any_or:SWI (match_dup 1) (match_dup 2)))]
8407 "ix86_match_ccmode (insn, CCNOmode)
8408 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8409 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8410 [(set_attr "type" "alu")
8411 (set_attr "mode" "<MODE>")])
8413 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8414 ;; ??? Special case for immediate operand is missing - it is tricky.
8415 (define_insn "*<code>si_2_zext"
8416 [(set (reg FLAGS_REG)
8417 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8418 (match_operand:SI 2 "general_operand" "g"))
8420 (set (match_operand:DI 0 "register_operand" "=r")
8421 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8422 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8423 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8424 "<logic>{l}\t{%2, %k0|%k0, %2}"
8425 [(set_attr "type" "alu")
8426 (set_attr "mode" "SI")])
8428 (define_insn "*<code>si_2_zext_imm"
8429 [(set (reg FLAGS_REG)
8431 (match_operand:SI 1 "nonimmediate_operand" "%0")
8432 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8434 (set (match_operand:DI 0 "register_operand" "=r")
8435 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8436 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8437 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8438 "<logic>{l}\t{%2, %k0|%k0, %2}"
8439 [(set_attr "type" "alu")
8440 (set_attr "mode" "SI")])
8442 (define_insn "*<code>qi_2_slp"
8443 [(set (reg FLAGS_REG)
8444 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8445 (match_operand:QI 1 "general_operand" "qmn,qn"))
8447 (set (strict_low_part (match_dup 0))
8448 (any_or:QI (match_dup 0) (match_dup 1)))]
8449 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8450 && ix86_match_ccmode (insn, CCNOmode)
8451 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8452 "<logic>{b}\t{%1, %0|%0, %1}"
8453 [(set_attr "type" "alu1")
8454 (set_attr "mode" "QI")])
8456 (define_insn "*<code><mode>_3"
8457 [(set (reg FLAGS_REG)
8458 (compare (any_or:SWI
8459 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8460 (match_operand:SWI 2 "<general_operand>" "<g>"))
8462 (clobber (match_scratch:SWI 0 "=<r>"))]
8463 "ix86_match_ccmode (insn, CCNOmode)
8464 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8465 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8466 [(set_attr "type" "alu")
8467 (set_attr "mode" "<MODE>")])
8469 (define_insn "*<code>qi_ext_0"
8470 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8475 (match_operand 1 "ext_register_operand" "0")
8478 (match_operand 2 "const_int_operand" "n")))
8479 (clobber (reg:CC FLAGS_REG))]
8480 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8481 "<logic>{b}\t{%2, %h0|%h0, %2}"
8482 [(set_attr "type" "alu")
8483 (set_attr "length_immediate" "1")
8484 (set_attr "modrm" "1")
8485 (set_attr "mode" "QI")])
8487 (define_insn "*<code>qi_ext_1_rex64"
8488 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8493 (match_operand 1 "ext_register_operand" "0")
8497 (match_operand 2 "ext_register_operand" "Q"))))
8498 (clobber (reg:CC FLAGS_REG))]
8500 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8501 "<logic>{b}\t{%2, %h0|%h0, %2}"
8502 [(set_attr "type" "alu")
8503 (set_attr "length_immediate" "0")
8504 (set_attr "mode" "QI")])
8506 (define_insn "*<code>qi_ext_1"
8507 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8512 (match_operand 1 "ext_register_operand" "0")
8516 (match_operand:QI 2 "general_operand" "Qm"))))
8517 (clobber (reg:CC FLAGS_REG))]
8519 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8520 "<logic>{b}\t{%2, %h0|%h0, %2}"
8521 [(set_attr "type" "alu")
8522 (set_attr "length_immediate" "0")
8523 (set_attr "mode" "QI")])
8525 (define_insn "*<code>qi_ext_2"
8526 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8530 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8533 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8536 (clobber (reg:CC FLAGS_REG))]
8537 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8538 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8539 [(set_attr "type" "alu")
8540 (set_attr "length_immediate" "0")
8541 (set_attr "mode" "QI")])
8544 [(set (match_operand 0 "register_operand" "")
8545 (any_or (match_operand 1 "register_operand" "")
8546 (match_operand 2 "const_int_operand" "")))
8547 (clobber (reg:CC FLAGS_REG))]
8549 && QI_REG_P (operands[0])
8550 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8551 && !(INTVAL (operands[2]) & ~(255 << 8))
8552 && GET_MODE (operands[0]) != QImode"
8553 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8554 (any_or:SI (zero_extract:SI (match_dup 1)
8555 (const_int 8) (const_int 8))
8557 (clobber (reg:CC FLAGS_REG))])]
8558 "operands[0] = gen_lowpart (SImode, operands[0]);
8559 operands[1] = gen_lowpart (SImode, operands[1]);
8560 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8562 ;; Since OR can be encoded with sign extended immediate, this is only
8563 ;; profitable when 7th bit is set.
8565 [(set (match_operand 0 "register_operand" "")
8566 (any_or (match_operand 1 "general_operand" "")
8567 (match_operand 2 "const_int_operand" "")))
8568 (clobber (reg:CC FLAGS_REG))]
8570 && ANY_QI_REG_P (operands[0])
8571 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8572 && !(INTVAL (operands[2]) & ~255)
8573 && (INTVAL (operands[2]) & 128)
8574 && GET_MODE (operands[0]) != QImode"
8575 [(parallel [(set (strict_low_part (match_dup 0))
8576 (any_or:QI (match_dup 1)
8578 (clobber (reg:CC FLAGS_REG))])]
8579 "operands[0] = gen_lowpart (QImode, operands[0]);
8580 operands[1] = gen_lowpart (QImode, operands[1]);
8581 operands[2] = gen_lowpart (QImode, operands[2]);")
8583 (define_expand "xorqi_cc_ext_1"
8585 (set (reg:CCNO FLAGS_REG)
8589 (match_operand 1 "ext_register_operand" "")
8592 (match_operand:QI 2 "general_operand" ""))
8594 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8604 (define_insn "*xorqi_cc_ext_1_rex64"
8605 [(set (reg FLAGS_REG)
8609 (match_operand 1 "ext_register_operand" "0")
8612 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8614 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8623 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8624 "xor{b}\t{%2, %h0|%h0, %2}"
8625 [(set_attr "type" "alu")
8626 (set_attr "modrm" "1")
8627 (set_attr "mode" "QI")])
8629 (define_insn "*xorqi_cc_ext_1"
8630 [(set (reg FLAGS_REG)
8634 (match_operand 1 "ext_register_operand" "0")
8637 (match_operand:QI 2 "general_operand" "qmn"))
8639 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8648 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8649 "xor{b}\t{%2, %h0|%h0, %2}"
8650 [(set_attr "type" "alu")
8651 (set_attr "modrm" "1")
8652 (set_attr "mode" "QI")])
8654 ;; Negation instructions
8656 (define_expand "neg<mode>2"
8657 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8658 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8660 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8662 (define_insn_and_split "*neg<dwi>2_doubleword"
8663 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8664 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8665 (clobber (reg:CC FLAGS_REG))]
8666 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8670 [(set (reg:CCZ FLAGS_REG)
8671 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8672 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8675 (plus:DWIH (match_dup 3)
8676 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8678 (clobber (reg:CC FLAGS_REG))])
8681 (neg:DWIH (match_dup 2)))
8682 (clobber (reg:CC FLAGS_REG))])]
8683 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8685 (define_insn "*neg<mode>2_1"
8686 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8687 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8688 (clobber (reg:CC FLAGS_REG))]
8689 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8690 "neg{<imodesuffix>}\t%0"
8691 [(set_attr "type" "negnot")
8692 (set_attr "mode" "<MODE>")])
8694 ;; Combine is quite creative about this pattern.
8695 (define_insn "*negsi2_1_zext"
8696 [(set (match_operand:DI 0 "register_operand" "=r")
8698 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8701 (clobber (reg:CC FLAGS_REG))]
8702 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8704 [(set_attr "type" "negnot")
8705 (set_attr "mode" "SI")])
8707 ;; The problem with neg is that it does not perform (compare x 0),
8708 ;; it really performs (compare 0 x), which leaves us with the zero
8709 ;; flag being the only useful item.
8711 (define_insn "*neg<mode>2_cmpz"
8712 [(set (reg:CCZ FLAGS_REG)
8714 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8716 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8717 (neg:SWI (match_dup 1)))]
8718 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8719 "neg{<imodesuffix>}\t%0"
8720 [(set_attr "type" "negnot")
8721 (set_attr "mode" "<MODE>")])
8723 (define_insn "*negsi2_cmpz_zext"
8724 [(set (reg:CCZ FLAGS_REG)
8728 (match_operand:DI 1 "register_operand" "0")
8732 (set (match_operand:DI 0 "register_operand" "=r")
8733 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8736 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8738 [(set_attr "type" "negnot")
8739 (set_attr "mode" "SI")])
8741 ;; Changing of sign for FP values is doable using integer unit too.
8743 (define_expand "<code><mode>2"
8744 [(set (match_operand:X87MODEF 0 "register_operand" "")
8745 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8746 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8747 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8749 (define_insn "*absneg<mode>2_mixed"
8750 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8751 (match_operator:MODEF 3 "absneg_operator"
8752 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8753 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8754 (clobber (reg:CC FLAGS_REG))]
8755 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8758 (define_insn "*absneg<mode>2_sse"
8759 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8760 (match_operator:MODEF 3 "absneg_operator"
8761 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8762 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8763 (clobber (reg:CC FLAGS_REG))]
8764 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8767 (define_insn "*absneg<mode>2_i387"
8768 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8769 (match_operator:X87MODEF 3 "absneg_operator"
8770 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8771 (use (match_operand 2 "" ""))
8772 (clobber (reg:CC FLAGS_REG))]
8773 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8776 (define_expand "<code>tf2"
8777 [(set (match_operand:TF 0 "register_operand" "")
8778 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8780 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8782 (define_insn "*absnegtf2_sse"
8783 [(set (match_operand:TF 0 "register_operand" "=x,x")
8784 (match_operator:TF 3 "absneg_operator"
8785 [(match_operand:TF 1 "register_operand" "0,x")]))
8786 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8787 (clobber (reg:CC FLAGS_REG))]
8791 ;; Splitters for fp abs and neg.
8794 [(set (match_operand 0 "fp_register_operand" "")
8795 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8796 (use (match_operand 2 "" ""))
8797 (clobber (reg:CC FLAGS_REG))]
8799 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8802 [(set (match_operand 0 "register_operand" "")
8803 (match_operator 3 "absneg_operator"
8804 [(match_operand 1 "register_operand" "")]))
8805 (use (match_operand 2 "nonimmediate_operand" ""))
8806 (clobber (reg:CC FLAGS_REG))]
8807 "reload_completed && SSE_REG_P (operands[0])"
8808 [(set (match_dup 0) (match_dup 3))]
8810 enum machine_mode mode = GET_MODE (operands[0]);
8811 enum machine_mode vmode = GET_MODE (operands[2]);
8814 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8815 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8816 if (operands_match_p (operands[0], operands[2]))
8819 operands[1] = operands[2];
8822 if (GET_CODE (operands[3]) == ABS)
8823 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8825 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8830 [(set (match_operand:SF 0 "register_operand" "")
8831 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8832 (use (match_operand:V4SF 2 "" ""))
8833 (clobber (reg:CC FLAGS_REG))]
8835 [(parallel [(set (match_dup 0) (match_dup 1))
8836 (clobber (reg:CC FLAGS_REG))])]
8839 operands[0] = gen_lowpart (SImode, operands[0]);
8840 if (GET_CODE (operands[1]) == ABS)
8842 tmp = gen_int_mode (0x7fffffff, SImode);
8843 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8847 tmp = gen_int_mode (0x80000000, SImode);
8848 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8854 [(set (match_operand:DF 0 "register_operand" "")
8855 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8856 (use (match_operand 2 "" ""))
8857 (clobber (reg:CC FLAGS_REG))]
8859 [(parallel [(set (match_dup 0) (match_dup 1))
8860 (clobber (reg:CC FLAGS_REG))])]
8865 tmp = gen_lowpart (DImode, operands[0]);
8866 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8869 if (GET_CODE (operands[1]) == ABS)
8872 tmp = gen_rtx_NOT (DImode, tmp);
8876 operands[0] = gen_highpart (SImode, operands[0]);
8877 if (GET_CODE (operands[1]) == ABS)
8879 tmp = gen_int_mode (0x7fffffff, SImode);
8880 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8884 tmp = gen_int_mode (0x80000000, SImode);
8885 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8892 [(set (match_operand:XF 0 "register_operand" "")
8893 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8894 (use (match_operand 2 "" ""))
8895 (clobber (reg:CC FLAGS_REG))]
8897 [(parallel [(set (match_dup 0) (match_dup 1))
8898 (clobber (reg:CC FLAGS_REG))])]
8901 operands[0] = gen_rtx_REG (SImode,
8902 true_regnum (operands[0])
8903 + (TARGET_64BIT ? 1 : 2));
8904 if (GET_CODE (operands[1]) == ABS)
8906 tmp = GEN_INT (0x7fff);
8907 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8911 tmp = GEN_INT (0x8000);
8912 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8917 ;; Conditionalize these after reload. If they match before reload, we
8918 ;; lose the clobber and ability to use integer instructions.
8920 (define_insn "*<code><mode>2_1"
8921 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8922 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8924 && (reload_completed
8925 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8926 "f<absneg_mnemonic>"
8927 [(set_attr "type" "fsgn")
8928 (set_attr "mode" "<MODE>")])
8930 (define_insn "*<code>extendsfdf2"
8931 [(set (match_operand:DF 0 "register_operand" "=f")
8932 (absneg:DF (float_extend:DF
8933 (match_operand:SF 1 "register_operand" "0"))))]
8934 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8935 "f<absneg_mnemonic>"
8936 [(set_attr "type" "fsgn")
8937 (set_attr "mode" "DF")])
8939 (define_insn "*<code>extendsfxf2"
8940 [(set (match_operand:XF 0 "register_operand" "=f")
8941 (absneg:XF (float_extend:XF
8942 (match_operand:SF 1 "register_operand" "0"))))]
8944 "f<absneg_mnemonic>"
8945 [(set_attr "type" "fsgn")
8946 (set_attr "mode" "XF")])
8948 (define_insn "*<code>extenddfxf2"
8949 [(set (match_operand:XF 0 "register_operand" "=f")
8950 (absneg:XF (float_extend:XF
8951 (match_operand:DF 1 "register_operand" "0"))))]
8953 "f<absneg_mnemonic>"
8954 [(set_attr "type" "fsgn")
8955 (set_attr "mode" "XF")])
8957 ;; Copysign instructions
8959 (define_mode_iterator CSGNMODE [SF DF TF])
8960 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8962 (define_expand "copysign<mode>3"
8963 [(match_operand:CSGNMODE 0 "register_operand" "")
8964 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8965 (match_operand:CSGNMODE 2 "register_operand" "")]
8966 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8967 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8968 "ix86_expand_copysign (operands); DONE;")
8970 (define_insn_and_split "copysign<mode>3_const"
8971 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8973 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8974 (match_operand:CSGNMODE 2 "register_operand" "0")
8975 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8977 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8978 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8980 "&& reload_completed"
8982 "ix86_split_copysign_const (operands); DONE;")
8984 (define_insn "copysign<mode>3_var"
8985 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8987 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8988 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8989 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8990 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8992 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8993 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8994 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8998 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9000 [(match_operand:CSGNMODE 2 "register_operand" "")
9001 (match_operand:CSGNMODE 3 "register_operand" "")
9002 (match_operand:<CSGNVMODE> 4 "" "")
9003 (match_operand:<CSGNVMODE> 5 "" "")]
9005 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9006 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9007 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9008 && reload_completed"
9010 "ix86_split_copysign_var (operands); DONE;")
9012 ;; One complement instructions
9014 (define_expand "one_cmpl<mode>2"
9015 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9016 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9018 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9020 (define_insn "*one_cmpl<mode>2_1"
9021 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9022 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9023 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9024 "not{<imodesuffix>}\t%0"
9025 [(set_attr "type" "negnot")
9026 (set_attr "mode" "<MODE>")])
9028 ;; %%% Potential partial reg stall on alternative 1. What to do?
9029 (define_insn "*one_cmplqi2_1"
9030 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9031 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9032 "ix86_unary_operator_ok (NOT, QImode, operands)"
9036 [(set_attr "type" "negnot")
9037 (set_attr "mode" "QI,SI")])
9039 ;; ??? Currently never generated - xor is used instead.
9040 (define_insn "*one_cmplsi2_1_zext"
9041 [(set (match_operand:DI 0 "register_operand" "=r")
9043 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9044 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9046 [(set_attr "type" "negnot")
9047 (set_attr "mode" "SI")])
9049 (define_insn "*one_cmpl<mode>2_2"
9050 [(set (reg FLAGS_REG)
9051 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9053 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9054 (not:SWI (match_dup 1)))]
9055 "ix86_match_ccmode (insn, CCNOmode)
9056 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9058 [(set_attr "type" "alu1")
9059 (set_attr "mode" "<MODE>")])
9062 [(set (match_operand 0 "flags_reg_operand" "")
9063 (match_operator 2 "compare_operator"
9064 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9066 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9067 (not:SWI (match_dup 3)))]
9068 "ix86_match_ccmode (insn, CCNOmode)"
9069 [(parallel [(set (match_dup 0)
9070 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9073 (xor:SWI (match_dup 3) (const_int -1)))])])
9075 ;; ??? Currently never generated - xor is used instead.
9076 (define_insn "*one_cmplsi2_2_zext"
9077 [(set (reg FLAGS_REG)
9078 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9080 (set (match_operand:DI 0 "register_operand" "=r")
9081 (zero_extend:DI (not:SI (match_dup 1))))]
9082 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9083 && ix86_unary_operator_ok (NOT, SImode, operands)"
9085 [(set_attr "type" "alu1")
9086 (set_attr "mode" "SI")])
9089 [(set (match_operand 0 "flags_reg_operand" "")
9090 (match_operator 2 "compare_operator"
9091 [(not:SI (match_operand:SI 3 "register_operand" ""))
9093 (set (match_operand:DI 1 "register_operand" "")
9094 (zero_extend:DI (not:SI (match_dup 3))))]
9095 "ix86_match_ccmode (insn, CCNOmode)"
9096 [(parallel [(set (match_dup 0)
9097 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9100 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9102 ;; Shift instructions
9104 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9105 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9106 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9107 ;; from the assembler input.
9109 ;; This instruction shifts the target reg/mem as usual, but instead of
9110 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9111 ;; is a left shift double, bits are taken from the high order bits of
9112 ;; reg, else if the insn is a shift right double, bits are taken from the
9113 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9114 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9116 ;; Since sh[lr]d does not change the `reg' operand, that is done
9117 ;; separately, making all shifts emit pairs of shift double and normal
9118 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9119 ;; support a 63 bit shift, each shift where the count is in a reg expands
9120 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9122 ;; If the shift count is a constant, we need never emit more than one
9123 ;; shift pair, instead using moves and sign extension for counts greater
9126 (define_expand "ashl<mode>3"
9127 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9128 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9129 (match_operand:QI 2 "nonmemory_operand" "")))]
9131 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9133 (define_insn "*ashl<mode>3_doubleword"
9134 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9135 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9136 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9137 (clobber (reg:CC FLAGS_REG))]
9140 [(set_attr "type" "multi")])
9143 [(set (match_operand:DWI 0 "register_operand" "")
9144 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9145 (match_operand:QI 2 "nonmemory_operand" "")))
9146 (clobber (reg:CC FLAGS_REG))]
9147 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9149 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9151 ;; By default we don't ask for a scratch register, because when DWImode
9152 ;; values are manipulated, registers are already at a premium. But if
9153 ;; we have one handy, we won't turn it away.
9156 [(match_scratch:DWIH 3 "r")
9157 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9159 (match_operand:<DWI> 1 "nonmemory_operand" "")
9160 (match_operand:QI 2 "nonmemory_operand" "")))
9161 (clobber (reg:CC FLAGS_REG))])
9165 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9167 (define_insn "x86_64_shld"
9168 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9169 (ior:DI (ashift:DI (match_dup 0)
9170 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9171 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9172 (minus:QI (const_int 64) (match_dup 2)))))
9173 (clobber (reg:CC FLAGS_REG))]
9175 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9176 [(set_attr "type" "ishift")
9177 (set_attr "prefix_0f" "1")
9178 (set_attr "mode" "DI")
9179 (set_attr "athlon_decode" "vector")
9180 (set_attr "amdfam10_decode" "vector")
9181 (set_attr "bdver1_decode" "vector")])
9183 (define_insn "x86_shld"
9184 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9185 (ior:SI (ashift:SI (match_dup 0)
9186 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9187 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9188 (minus:QI (const_int 32) (match_dup 2)))))
9189 (clobber (reg:CC FLAGS_REG))]
9191 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9192 [(set_attr "type" "ishift")
9193 (set_attr "prefix_0f" "1")
9194 (set_attr "mode" "SI")
9195 (set_attr "pent_pair" "np")
9196 (set_attr "athlon_decode" "vector")
9197 (set_attr "amdfam10_decode" "vector")
9198 (set_attr "bdver1_decode" "vector")])
9200 (define_expand "x86_shift<mode>_adj_1"
9201 [(set (reg:CCZ FLAGS_REG)
9202 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9205 (set (match_operand:SWI48 0 "register_operand" "")
9206 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9207 (match_operand:SWI48 1 "register_operand" "")
9210 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9211 (match_operand:SWI48 3 "register_operand" "r")
9214 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9216 (define_expand "x86_shift<mode>_adj_2"
9217 [(use (match_operand:SWI48 0 "register_operand" ""))
9218 (use (match_operand:SWI48 1 "register_operand" ""))
9219 (use (match_operand:QI 2 "register_operand" ""))]
9222 rtx label = gen_label_rtx ();
9225 emit_insn (gen_testqi_ccz_1 (operands[2],
9226 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9228 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9229 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9230 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9231 gen_rtx_LABEL_REF (VOIDmode, label),
9233 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9234 JUMP_LABEL (tmp) = label;
9236 emit_move_insn (operands[0], operands[1]);
9237 ix86_expand_clear (operands[1]);
9240 LABEL_NUSES (label) = 1;
9245 ;; Avoid useless masking of count operand.
9246 (define_insn_and_split "*ashl<mode>3_mask"
9247 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9249 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9252 (match_operand:SI 2 "nonimmediate_operand" "c")
9253 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9254 (clobber (reg:CC FLAGS_REG))]
9255 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9256 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9257 == GET_MODE_BITSIZE (<MODE>mode)-1"
9260 [(parallel [(set (match_dup 0)
9261 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9262 (clobber (reg:CC FLAGS_REG))])]
9264 if (can_create_pseudo_p ())
9265 operands [2] = force_reg (SImode, operands[2]);
9267 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9269 [(set_attr "type" "ishift")
9270 (set_attr "mode" "<MODE>")])
9272 (define_insn "*ashl<mode>3_1"
9273 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9274 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9275 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9276 (clobber (reg:CC FLAGS_REG))]
9277 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9279 switch (get_attr_type (insn))
9285 gcc_assert (operands[2] == const1_rtx);
9286 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9287 return "add{<imodesuffix>}\t%0, %0";
9290 if (operands[2] == const1_rtx
9291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9292 return "sal{<imodesuffix>}\t%0";
9294 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9298 (cond [(eq_attr "alternative" "1")
9299 (const_string "lea")
9300 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9302 (match_operand 0 "register_operand" ""))
9303 (match_operand 2 "const1_operand" ""))
9304 (const_string "alu")
9306 (const_string "ishift")))
9307 (set (attr "length_immediate")
9309 (ior (eq_attr "type" "alu")
9310 (and (eq_attr "type" "ishift")
9311 (and (match_operand 2 "const1_operand" "")
9312 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9315 (const_string "*")))
9316 (set_attr "mode" "<MODE>")])
9318 (define_insn "*ashlsi3_1_zext"
9319 [(set (match_operand:DI 0 "register_operand" "=r,r")
9321 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9322 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9323 (clobber (reg:CC FLAGS_REG))]
9324 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9326 switch (get_attr_type (insn))
9332 gcc_assert (operands[2] == const1_rtx);
9333 return "add{l}\t%k0, %k0";
9336 if (operands[2] == const1_rtx
9337 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9338 return "sal{l}\t%k0";
9340 return "sal{l}\t{%2, %k0|%k0, %2}";
9344 (cond [(eq_attr "alternative" "1")
9345 (const_string "lea")
9346 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9348 (match_operand 2 "const1_operand" ""))
9349 (const_string "alu")
9351 (const_string "ishift")))
9352 (set (attr "length_immediate")
9354 (ior (eq_attr "type" "alu")
9355 (and (eq_attr "type" "ishift")
9356 (and (match_operand 2 "const1_operand" "")
9357 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9360 (const_string "*")))
9361 (set_attr "mode" "SI")])
9363 (define_insn "*ashlhi3_1"
9364 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9365 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9366 (match_operand:QI 2 "nonmemory_operand" "cI")))
9367 (clobber (reg:CC FLAGS_REG))]
9368 "TARGET_PARTIAL_REG_STALL
9369 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9371 switch (get_attr_type (insn))
9374 gcc_assert (operands[2] == const1_rtx);
9375 return "add{w}\t%0, %0";
9378 if (operands[2] == const1_rtx
9379 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9380 return "sal{w}\t%0";
9382 return "sal{w}\t{%2, %0|%0, %2}";
9386 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9388 (match_operand 0 "register_operand" ""))
9389 (match_operand 2 "const1_operand" ""))
9390 (const_string "alu")
9392 (const_string "ishift")))
9393 (set (attr "length_immediate")
9395 (ior (eq_attr "type" "alu")
9396 (and (eq_attr "type" "ishift")
9397 (and (match_operand 2 "const1_operand" "")
9398 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9401 (const_string "*")))
9402 (set_attr "mode" "HI")])
9404 (define_insn "*ashlhi3_1_lea"
9405 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9406 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9407 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9408 (clobber (reg:CC FLAGS_REG))]
9409 "!TARGET_PARTIAL_REG_STALL
9410 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9412 switch (get_attr_type (insn))
9418 gcc_assert (operands[2] == const1_rtx);
9419 return "add{w}\t%0, %0";
9422 if (operands[2] == const1_rtx
9423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9424 return "sal{w}\t%0";
9426 return "sal{w}\t{%2, %0|%0, %2}";
9430 (cond [(eq_attr "alternative" "1")
9431 (const_string "lea")
9432 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9434 (match_operand 0 "register_operand" ""))
9435 (match_operand 2 "const1_operand" ""))
9436 (const_string "alu")
9438 (const_string "ishift")))
9439 (set (attr "length_immediate")
9441 (ior (eq_attr "type" "alu")
9442 (and (eq_attr "type" "ishift")
9443 (and (match_operand 2 "const1_operand" "")
9444 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9447 (const_string "*")))
9448 (set_attr "mode" "HI,SI")])
9450 (define_insn "*ashlqi3_1"
9451 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9452 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9453 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9454 (clobber (reg:CC FLAGS_REG))]
9455 "TARGET_PARTIAL_REG_STALL
9456 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9458 switch (get_attr_type (insn))
9461 gcc_assert (operands[2] == const1_rtx);
9462 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9463 return "add{l}\t%k0, %k0";
9465 return "add{b}\t%0, %0";
9468 if (operands[2] == const1_rtx
9469 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9471 if (get_attr_mode (insn) == MODE_SI)
9472 return "sal{l}\t%k0";
9474 return "sal{b}\t%0";
9478 if (get_attr_mode (insn) == MODE_SI)
9479 return "sal{l}\t{%2, %k0|%k0, %2}";
9481 return "sal{b}\t{%2, %0|%0, %2}";
9486 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9488 (match_operand 0 "register_operand" ""))
9489 (match_operand 2 "const1_operand" ""))
9490 (const_string "alu")
9492 (const_string "ishift")))
9493 (set (attr "length_immediate")
9495 (ior (eq_attr "type" "alu")
9496 (and (eq_attr "type" "ishift")
9497 (and (match_operand 2 "const1_operand" "")
9498 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9501 (const_string "*")))
9502 (set_attr "mode" "QI,SI")])
9504 ;; %%% Potential partial reg stall on alternative 2. What to do?
9505 (define_insn "*ashlqi3_1_lea"
9506 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9507 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9508 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9509 (clobber (reg:CC FLAGS_REG))]
9510 "!TARGET_PARTIAL_REG_STALL
9511 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9513 switch (get_attr_type (insn))
9519 gcc_assert (operands[2] == const1_rtx);
9520 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9521 return "add{l}\t%k0, %k0";
9523 return "add{b}\t%0, %0";
9526 if (operands[2] == const1_rtx
9527 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9529 if (get_attr_mode (insn) == MODE_SI)
9530 return "sal{l}\t%k0";
9532 return "sal{b}\t%0";
9536 if (get_attr_mode (insn) == MODE_SI)
9537 return "sal{l}\t{%2, %k0|%k0, %2}";
9539 return "sal{b}\t{%2, %0|%0, %2}";
9544 (cond [(eq_attr "alternative" "2")
9545 (const_string "lea")
9546 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9548 (match_operand 0 "register_operand" ""))
9549 (match_operand 2 "const1_operand" ""))
9550 (const_string "alu")
9552 (const_string "ishift")))
9553 (set (attr "length_immediate")
9555 (ior (eq_attr "type" "alu")
9556 (and (eq_attr "type" "ishift")
9557 (and (match_operand 2 "const1_operand" "")
9558 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9561 (const_string "*")))
9562 (set_attr "mode" "QI,SI,SI")])
9564 (define_insn "*ashlqi3_1_slp"
9565 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9566 (ashift:QI (match_dup 0)
9567 (match_operand:QI 1 "nonmemory_operand" "cI")))
9568 (clobber (reg:CC FLAGS_REG))]
9569 "(optimize_function_for_size_p (cfun)
9570 || !TARGET_PARTIAL_FLAG_REG_STALL
9571 || (operands[1] == const1_rtx
9573 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9575 switch (get_attr_type (insn))
9578 gcc_assert (operands[1] == const1_rtx);
9579 return "add{b}\t%0, %0";
9582 if (operands[1] == const1_rtx
9583 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9584 return "sal{b}\t%0";
9586 return "sal{b}\t{%1, %0|%0, %1}";
9590 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9592 (match_operand 0 "register_operand" ""))
9593 (match_operand 1 "const1_operand" ""))
9594 (const_string "alu")
9596 (const_string "ishift1")))
9597 (set (attr "length_immediate")
9599 (ior (eq_attr "type" "alu")
9600 (and (eq_attr "type" "ishift1")
9601 (and (match_operand 1 "const1_operand" "")
9602 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9605 (const_string "*")))
9606 (set_attr "mode" "QI")])
9608 ;; Convert lea to the lea pattern to avoid flags dependency.
9610 [(set (match_operand 0 "register_operand" "")
9611 (ashift (match_operand 1 "index_register_operand" "")
9612 (match_operand:QI 2 "const_int_operand" "")))
9613 (clobber (reg:CC FLAGS_REG))]
9615 && true_regnum (operands[0]) != true_regnum (operands[1])"
9619 enum machine_mode mode = GET_MODE (operands[0]);
9622 operands[1] = gen_lowpart (Pmode, operands[1]);
9623 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9625 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9627 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9628 operands[0] = gen_lowpart (SImode, operands[0]);
9630 if (TARGET_64BIT && mode != Pmode)
9631 pat = gen_rtx_SUBREG (SImode, pat, 0);
9633 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9637 ;; Convert lea to the lea pattern to avoid flags dependency.
9639 [(set (match_operand:DI 0 "register_operand" "")
9641 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9642 (match_operand:QI 2 "const_int_operand" ""))))
9643 (clobber (reg:CC FLAGS_REG))]
9644 "TARGET_64BIT && reload_completed
9645 && true_regnum (operands[0]) != true_regnum (operands[1])"
9647 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9649 operands[1] = gen_lowpart (DImode, operands[1]);
9650 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9653 ;; This pattern can't accept a variable shift count, since shifts by
9654 ;; zero don't affect the flags. We assume that shifts by constant
9655 ;; zero are optimized away.
9656 (define_insn "*ashl<mode>3_cmp"
9657 [(set (reg FLAGS_REG)
9659 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9660 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9662 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9663 (ashift:SWI (match_dup 1) (match_dup 2)))]
9664 "(optimize_function_for_size_p (cfun)
9665 || !TARGET_PARTIAL_FLAG_REG_STALL
9666 || (operands[2] == const1_rtx
9668 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9669 && ix86_match_ccmode (insn, CCGOCmode)
9670 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9672 switch (get_attr_type (insn))
9675 gcc_assert (operands[2] == const1_rtx);
9676 return "add{<imodesuffix>}\t%0, %0";
9679 if (operands[2] == const1_rtx
9680 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9681 return "sal{<imodesuffix>}\t%0";
9683 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9687 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9689 (match_operand 0 "register_operand" ""))
9690 (match_operand 2 "const1_operand" ""))
9691 (const_string "alu")
9693 (const_string "ishift")))
9694 (set (attr "length_immediate")
9696 (ior (eq_attr "type" "alu")
9697 (and (eq_attr "type" "ishift")
9698 (and (match_operand 2 "const1_operand" "")
9699 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9702 (const_string "*")))
9703 (set_attr "mode" "<MODE>")])
9705 (define_insn "*ashlsi3_cmp_zext"
9706 [(set (reg FLAGS_REG)
9708 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9709 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9711 (set (match_operand:DI 0 "register_operand" "=r")
9712 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9714 && (optimize_function_for_size_p (cfun)
9715 || !TARGET_PARTIAL_FLAG_REG_STALL
9716 || (operands[2] == const1_rtx
9718 || TARGET_DOUBLE_WITH_ADD)))
9719 && ix86_match_ccmode (insn, CCGOCmode)
9720 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9722 switch (get_attr_type (insn))
9725 gcc_assert (operands[2] == const1_rtx);
9726 return "add{l}\t%k0, %k0";
9729 if (operands[2] == const1_rtx
9730 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9731 return "sal{l}\t%k0";
9733 return "sal{l}\t{%2, %k0|%k0, %2}";
9737 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9739 (match_operand 2 "const1_operand" ""))
9740 (const_string "alu")
9742 (const_string "ishift")))
9743 (set (attr "length_immediate")
9745 (ior (eq_attr "type" "alu")
9746 (and (eq_attr "type" "ishift")
9747 (and (match_operand 2 "const1_operand" "")
9748 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9751 (const_string "*")))
9752 (set_attr "mode" "SI")])
9754 (define_insn "*ashl<mode>3_cconly"
9755 [(set (reg FLAGS_REG)
9757 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9758 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9760 (clobber (match_scratch:SWI 0 "=<r>"))]
9761 "(optimize_function_for_size_p (cfun)
9762 || !TARGET_PARTIAL_FLAG_REG_STALL
9763 || (operands[2] == const1_rtx
9765 || TARGET_DOUBLE_WITH_ADD)))
9766 && ix86_match_ccmode (insn, CCGOCmode)"
9768 switch (get_attr_type (insn))
9771 gcc_assert (operands[2] == const1_rtx);
9772 return "add{<imodesuffix>}\t%0, %0";
9775 if (operands[2] == const1_rtx
9776 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9777 return "sal{<imodesuffix>}\t%0";
9779 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9783 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9785 (match_operand 0 "register_operand" ""))
9786 (match_operand 2 "const1_operand" ""))
9787 (const_string "alu")
9789 (const_string "ishift")))
9790 (set (attr "length_immediate")
9792 (ior (eq_attr "type" "alu")
9793 (and (eq_attr "type" "ishift")
9794 (and (match_operand 2 "const1_operand" "")
9795 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9798 (const_string "*")))
9799 (set_attr "mode" "<MODE>")])
9801 ;; See comment above `ashl<mode>3' about how this works.
9803 (define_expand "<shiftrt_insn><mode>3"
9804 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9805 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9806 (match_operand:QI 2 "nonmemory_operand" "")))]
9808 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9810 ;; Avoid useless masking of count operand.
9811 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9812 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9814 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9817 (match_operand:SI 2 "nonimmediate_operand" "c")
9818 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9819 (clobber (reg:CC FLAGS_REG))]
9820 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9821 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9822 == GET_MODE_BITSIZE (<MODE>mode)-1"
9825 [(parallel [(set (match_dup 0)
9826 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9827 (clobber (reg:CC FLAGS_REG))])]
9829 if (can_create_pseudo_p ())
9830 operands [2] = force_reg (SImode, operands[2]);
9832 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9834 [(set_attr "type" "ishift")
9835 (set_attr "mode" "<MODE>")])
9837 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9838 [(set (match_operand:DWI 0 "register_operand" "=r")
9839 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9840 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9841 (clobber (reg:CC FLAGS_REG))]
9844 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9846 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9847 [(set_attr "type" "multi")])
9849 ;; By default we don't ask for a scratch register, because when DWImode
9850 ;; values are manipulated, registers are already at a premium. But if
9851 ;; we have one handy, we won't turn it away.
9854 [(match_scratch:DWIH 3 "r")
9855 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9857 (match_operand:<DWI> 1 "register_operand" "")
9858 (match_operand:QI 2 "nonmemory_operand" "")))
9859 (clobber (reg:CC FLAGS_REG))])
9863 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9865 (define_insn "x86_64_shrd"
9866 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9867 (ior:DI (ashiftrt:DI (match_dup 0)
9868 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9869 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9870 (minus:QI (const_int 64) (match_dup 2)))))
9871 (clobber (reg:CC FLAGS_REG))]
9873 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9874 [(set_attr "type" "ishift")
9875 (set_attr "prefix_0f" "1")
9876 (set_attr "mode" "DI")
9877 (set_attr "athlon_decode" "vector")
9878 (set_attr "amdfam10_decode" "vector")
9879 (set_attr "bdver1_decode" "vector")])
9881 (define_insn "x86_shrd"
9882 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9883 (ior:SI (ashiftrt:SI (match_dup 0)
9884 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9885 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9886 (minus:QI (const_int 32) (match_dup 2)))))
9887 (clobber (reg:CC FLAGS_REG))]
9889 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9890 [(set_attr "type" "ishift")
9891 (set_attr "prefix_0f" "1")
9892 (set_attr "mode" "SI")
9893 (set_attr "pent_pair" "np")
9894 (set_attr "athlon_decode" "vector")
9895 (set_attr "amdfam10_decode" "vector")
9896 (set_attr "bdver1_decode" "vector")])
9898 (define_insn "ashrdi3_cvt"
9899 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9900 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9901 (match_operand:QI 2 "const_int_operand" "")))
9902 (clobber (reg:CC FLAGS_REG))]
9903 "TARGET_64BIT && INTVAL (operands[2]) == 63
9904 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9905 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9908 sar{q}\t{%2, %0|%0, %2}"
9909 [(set_attr "type" "imovx,ishift")
9910 (set_attr "prefix_0f" "0,*")
9911 (set_attr "length_immediate" "0,*")
9912 (set_attr "modrm" "0,1")
9913 (set_attr "mode" "DI")])
9915 (define_insn "ashrsi3_cvt"
9916 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9917 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9918 (match_operand:QI 2 "const_int_operand" "")))
9919 (clobber (reg:CC FLAGS_REG))]
9920 "INTVAL (operands[2]) == 31
9921 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9922 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9925 sar{l}\t{%2, %0|%0, %2}"
9926 [(set_attr "type" "imovx,ishift")
9927 (set_attr "prefix_0f" "0,*")
9928 (set_attr "length_immediate" "0,*")
9929 (set_attr "modrm" "0,1")
9930 (set_attr "mode" "SI")])
9932 (define_insn "*ashrsi3_cvt_zext"
9933 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9935 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9936 (match_operand:QI 2 "const_int_operand" ""))))
9937 (clobber (reg:CC FLAGS_REG))]
9938 "TARGET_64BIT && INTVAL (operands[2]) == 31
9939 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9940 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9943 sar{l}\t{%2, %k0|%k0, %2}"
9944 [(set_attr "type" "imovx,ishift")
9945 (set_attr "prefix_0f" "0,*")
9946 (set_attr "length_immediate" "0,*")
9947 (set_attr "modrm" "0,1")
9948 (set_attr "mode" "SI")])
9950 (define_expand "x86_shift<mode>_adj_3"
9951 [(use (match_operand:SWI48 0 "register_operand" ""))
9952 (use (match_operand:SWI48 1 "register_operand" ""))
9953 (use (match_operand:QI 2 "register_operand" ""))]
9956 rtx label = gen_label_rtx ();
9959 emit_insn (gen_testqi_ccz_1 (operands[2],
9960 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9962 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9963 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9964 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9965 gen_rtx_LABEL_REF (VOIDmode, label),
9967 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9968 JUMP_LABEL (tmp) = label;
9970 emit_move_insn (operands[0], operands[1]);
9971 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9972 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9974 LABEL_NUSES (label) = 1;
9979 (define_insn "*<shiftrt_insn><mode>3_1"
9980 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9981 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9982 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9983 (clobber (reg:CC FLAGS_REG))]
9984 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9986 if (operands[2] == const1_rtx
9987 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9988 return "<shiftrt>{<imodesuffix>}\t%0";
9990 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9992 [(set_attr "type" "ishift")
9993 (set (attr "length_immediate")
9995 (and (match_operand 2 "const1_operand" "")
9996 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9999 (const_string "*")))
10000 (set_attr "mode" "<MODE>")])
10002 (define_insn "*<shiftrt_insn>si3_1_zext"
10003 [(set (match_operand:DI 0 "register_operand" "=r")
10005 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10006 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10007 (clobber (reg:CC FLAGS_REG))]
10008 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10010 if (operands[2] == const1_rtx
10011 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10012 return "<shiftrt>{l}\t%k0";
10014 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10016 [(set_attr "type" "ishift")
10017 (set (attr "length_immediate")
10019 (and (match_operand 2 "const1_operand" "")
10020 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10023 (const_string "*")))
10024 (set_attr "mode" "SI")])
10026 (define_insn "*<shiftrt_insn>qi3_1_slp"
10027 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10028 (any_shiftrt:QI (match_dup 0)
10029 (match_operand:QI 1 "nonmemory_operand" "cI")))
10030 (clobber (reg:CC FLAGS_REG))]
10031 "(optimize_function_for_size_p (cfun)
10032 || !TARGET_PARTIAL_REG_STALL
10033 || (operands[1] == const1_rtx
10034 && TARGET_SHIFT1))"
10036 if (operands[1] == const1_rtx
10037 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10038 return "<shiftrt>{b}\t%0";
10040 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10042 [(set_attr "type" "ishift1")
10043 (set (attr "length_immediate")
10045 (and (match_operand 1 "const1_operand" "")
10046 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10049 (const_string "*")))
10050 (set_attr "mode" "QI")])
10052 ;; This pattern can't accept a variable shift count, since shifts by
10053 ;; zero don't affect the flags. We assume that shifts by constant
10054 ;; zero are optimized away.
10055 (define_insn "*<shiftrt_insn><mode>3_cmp"
10056 [(set (reg FLAGS_REG)
10059 (match_operand:SWI 1 "nonimmediate_operand" "0")
10060 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10062 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10063 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10064 "(optimize_function_for_size_p (cfun)
10065 || !TARGET_PARTIAL_FLAG_REG_STALL
10066 || (operands[2] == const1_rtx
10068 && ix86_match_ccmode (insn, CCGOCmode)
10069 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10071 if (operands[2] == const1_rtx
10072 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10073 return "<shiftrt>{<imodesuffix>}\t%0";
10075 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10077 [(set_attr "type" "ishift")
10078 (set (attr "length_immediate")
10080 (and (match_operand 2 "const1_operand" "")
10081 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10084 (const_string "*")))
10085 (set_attr "mode" "<MODE>")])
10087 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10088 [(set (reg FLAGS_REG)
10090 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10091 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10093 (set (match_operand:DI 0 "register_operand" "=r")
10094 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10096 && (optimize_function_for_size_p (cfun)
10097 || !TARGET_PARTIAL_FLAG_REG_STALL
10098 || (operands[2] == const1_rtx
10100 && ix86_match_ccmode (insn, CCGOCmode)
10101 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10103 if (operands[2] == const1_rtx
10104 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10105 return "<shiftrt>{l}\t%k0";
10107 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10109 [(set_attr "type" "ishift")
10110 (set (attr "length_immediate")
10112 (and (match_operand 2 "const1_operand" "")
10113 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10116 (const_string "*")))
10117 (set_attr "mode" "SI")])
10119 (define_insn "*<shiftrt_insn><mode>3_cconly"
10120 [(set (reg FLAGS_REG)
10123 (match_operand:SWI 1 "register_operand" "0")
10124 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10126 (clobber (match_scratch:SWI 0 "=<r>"))]
10127 "(optimize_function_for_size_p (cfun)
10128 || !TARGET_PARTIAL_FLAG_REG_STALL
10129 || (operands[2] == const1_rtx
10131 && ix86_match_ccmode (insn, CCGOCmode)"
10133 if (operands[2] == const1_rtx
10134 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10135 return "<shiftrt>{<imodesuffix>}\t%0";
10137 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10139 [(set_attr "type" "ishift")
10140 (set (attr "length_immediate")
10142 (and (match_operand 2 "const1_operand" "")
10143 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10146 (const_string "*")))
10147 (set_attr "mode" "<MODE>")])
10149 ;; Rotate instructions
10151 (define_expand "<rotate_insn>ti3"
10152 [(set (match_operand:TI 0 "register_operand" "")
10153 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10154 (match_operand:QI 2 "nonmemory_operand" "")))]
10157 if (const_1_to_63_operand (operands[2], VOIDmode))
10158 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10159 (operands[0], operands[1], operands[2]));
10166 (define_expand "<rotate_insn>di3"
10167 [(set (match_operand:DI 0 "shiftdi_operand" "")
10168 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10169 (match_operand:QI 2 "nonmemory_operand" "")))]
10173 ix86_expand_binary_operator (<CODE>, DImode, operands);
10174 else if (const_1_to_31_operand (operands[2], VOIDmode))
10175 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10176 (operands[0], operands[1], operands[2]));
10183 (define_expand "<rotate_insn><mode>3"
10184 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10185 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10186 (match_operand:QI 2 "nonmemory_operand" "")))]
10188 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10190 ;; Avoid useless masking of count operand.
10191 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10192 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10194 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10197 (match_operand:SI 2 "nonimmediate_operand" "c")
10198 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10199 (clobber (reg:CC FLAGS_REG))]
10200 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10201 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10202 == GET_MODE_BITSIZE (<MODE>mode)-1"
10205 [(parallel [(set (match_dup 0)
10206 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10207 (clobber (reg:CC FLAGS_REG))])]
10209 if (can_create_pseudo_p ())
10210 operands [2] = force_reg (SImode, operands[2]);
10212 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10214 [(set_attr "type" "rotate")
10215 (set_attr "mode" "<MODE>")])
10217 ;; Implement rotation using two double-precision
10218 ;; shift instructions and a scratch register.
10220 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10221 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10222 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10223 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10224 (clobber (reg:CC FLAGS_REG))
10225 (clobber (match_scratch:DWIH 3 "=&r"))]
10229 [(set (match_dup 3) (match_dup 4))
10231 [(set (match_dup 4)
10232 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10233 (lshiftrt:DWIH (match_dup 5)
10234 (minus:QI (match_dup 6) (match_dup 2)))))
10235 (clobber (reg:CC FLAGS_REG))])
10237 [(set (match_dup 5)
10238 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10239 (lshiftrt:DWIH (match_dup 3)
10240 (minus:QI (match_dup 6) (match_dup 2)))))
10241 (clobber (reg:CC FLAGS_REG))])]
10243 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10245 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10248 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10249 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10250 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10251 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10252 (clobber (reg:CC FLAGS_REG))
10253 (clobber (match_scratch:DWIH 3 "=&r"))]
10257 [(set (match_dup 3) (match_dup 4))
10259 [(set (match_dup 4)
10260 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10261 (ashift:DWIH (match_dup 5)
10262 (minus:QI (match_dup 6) (match_dup 2)))))
10263 (clobber (reg:CC FLAGS_REG))])
10265 [(set (match_dup 5)
10266 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10267 (ashift:DWIH (match_dup 3)
10268 (minus:QI (match_dup 6) (match_dup 2)))))
10269 (clobber (reg:CC FLAGS_REG))])]
10271 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10273 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10276 (define_insn "*<rotate_insn><mode>3_1"
10277 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10278 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10279 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10280 (clobber (reg:CC FLAGS_REG))]
10281 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10283 if (operands[2] == const1_rtx
10284 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10285 return "<rotate>{<imodesuffix>}\t%0";
10287 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10289 [(set_attr "type" "rotate")
10290 (set (attr "length_immediate")
10292 (and (match_operand 2 "const1_operand" "")
10293 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10296 (const_string "*")))
10297 (set_attr "mode" "<MODE>")])
10299 (define_insn "*<rotate_insn>si3_1_zext"
10300 [(set (match_operand:DI 0 "register_operand" "=r")
10302 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10303 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10304 (clobber (reg:CC FLAGS_REG))]
10305 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10307 if (operands[2] == const1_rtx
10308 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10309 return "<rotate>{l}\t%k0";
10311 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10313 [(set_attr "type" "rotate")
10314 (set (attr "length_immediate")
10316 (and (match_operand 2 "const1_operand" "")
10317 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10320 (const_string "*")))
10321 (set_attr "mode" "SI")])
10323 (define_insn "*<rotate_insn>qi3_1_slp"
10324 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10325 (any_rotate:QI (match_dup 0)
10326 (match_operand:QI 1 "nonmemory_operand" "cI")))
10327 (clobber (reg:CC FLAGS_REG))]
10328 "(optimize_function_for_size_p (cfun)
10329 || !TARGET_PARTIAL_REG_STALL
10330 || (operands[1] == const1_rtx
10331 && TARGET_SHIFT1))"
10333 if (operands[1] == const1_rtx
10334 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10335 return "<rotate>{b}\t%0";
10337 return "<rotate>{b}\t{%1, %0|%0, %1}";
10339 [(set_attr "type" "rotate1")
10340 (set (attr "length_immediate")
10342 (and (match_operand 1 "const1_operand" "")
10343 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10346 (const_string "*")))
10347 (set_attr "mode" "QI")])
10350 [(set (match_operand:HI 0 "register_operand" "")
10351 (any_rotate:HI (match_dup 0) (const_int 8)))
10352 (clobber (reg:CC FLAGS_REG))]
10354 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10355 [(parallel [(set (strict_low_part (match_dup 0))
10356 (bswap:HI (match_dup 0)))
10357 (clobber (reg:CC FLAGS_REG))])])
10359 ;; Bit set / bit test instructions
10361 (define_expand "extv"
10362 [(set (match_operand:SI 0 "register_operand" "")
10363 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10364 (match_operand:SI 2 "const8_operand" "")
10365 (match_operand:SI 3 "const8_operand" "")))]
10368 /* Handle extractions from %ah et al. */
10369 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10372 /* From mips.md: extract_bit_field doesn't verify that our source
10373 matches the predicate, so check it again here. */
10374 if (! ext_register_operand (operands[1], VOIDmode))
10378 (define_expand "extzv"
10379 [(set (match_operand:SI 0 "register_operand" "")
10380 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10381 (match_operand:SI 2 "const8_operand" "")
10382 (match_operand:SI 3 "const8_operand" "")))]
10385 /* Handle extractions from %ah et al. */
10386 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10389 /* From mips.md: extract_bit_field doesn't verify that our source
10390 matches the predicate, so check it again here. */
10391 if (! ext_register_operand (operands[1], VOIDmode))
10395 (define_expand "insv"
10396 [(set (zero_extract (match_operand 0 "register_operand" "")
10397 (match_operand 1 "const_int_operand" "")
10398 (match_operand 2 "const_int_operand" ""))
10399 (match_operand 3 "register_operand" ""))]
10402 rtx (*gen_mov_insv_1) (rtx, rtx);
10404 if (ix86_expand_pinsr (operands))
10407 /* Handle insertions to %ah et al. */
10408 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10411 /* From mips.md: insert_bit_field doesn't verify that our source
10412 matches the predicate, so check it again here. */
10413 if (! ext_register_operand (operands[0], VOIDmode))
10416 gen_mov_insv_1 = (TARGET_64BIT
10417 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10419 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10423 ;; %%% bts, btr, btc, bt.
10424 ;; In general these instructions are *slow* when applied to memory,
10425 ;; since they enforce atomic operation. When applied to registers,
10426 ;; it depends on the cpu implementation. They're never faster than
10427 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10428 ;; no point. But in 64-bit, we can't hold the relevant immediates
10429 ;; within the instruction itself, so operating on bits in the high
10430 ;; 32-bits of a register becomes easier.
10432 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10433 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10434 ;; negdf respectively, so they can never be disabled entirely.
10436 (define_insn "*btsq"
10437 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10439 (match_operand:DI 1 "const_0_to_63_operand" ""))
10441 (clobber (reg:CC FLAGS_REG))]
10442 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10443 "bts{q}\t{%1, %0|%0, %1}"
10444 [(set_attr "type" "alu1")
10445 (set_attr "prefix_0f" "1")
10446 (set_attr "mode" "DI")])
10448 (define_insn "*btrq"
10449 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10451 (match_operand:DI 1 "const_0_to_63_operand" ""))
10453 (clobber (reg:CC FLAGS_REG))]
10454 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10455 "btr{q}\t{%1, %0|%0, %1}"
10456 [(set_attr "type" "alu1")
10457 (set_attr "prefix_0f" "1")
10458 (set_attr "mode" "DI")])
10460 (define_insn "*btcq"
10461 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10463 (match_operand:DI 1 "const_0_to_63_operand" ""))
10464 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10465 (clobber (reg:CC FLAGS_REG))]
10466 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10467 "btc{q}\t{%1, %0|%0, %1}"
10468 [(set_attr "type" "alu1")
10469 (set_attr "prefix_0f" "1")
10470 (set_attr "mode" "DI")])
10472 ;; Allow Nocona to avoid these instructions if a register is available.
10475 [(match_scratch:DI 2 "r")
10476 (parallel [(set (zero_extract:DI
10477 (match_operand:DI 0 "register_operand" "")
10479 (match_operand:DI 1 "const_0_to_63_operand" ""))
10481 (clobber (reg:CC FLAGS_REG))])]
10482 "TARGET_64BIT && !TARGET_USE_BT"
10485 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10488 if (HOST_BITS_PER_WIDE_INT >= 64)
10489 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10490 else if (i < HOST_BITS_PER_WIDE_INT)
10491 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10493 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10495 op1 = immed_double_const (lo, hi, DImode);
10498 emit_move_insn (operands[2], op1);
10502 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10507 [(match_scratch:DI 2 "r")
10508 (parallel [(set (zero_extract:DI
10509 (match_operand:DI 0 "register_operand" "")
10511 (match_operand:DI 1 "const_0_to_63_operand" ""))
10513 (clobber (reg:CC FLAGS_REG))])]
10514 "TARGET_64BIT && !TARGET_USE_BT"
10517 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10520 if (HOST_BITS_PER_WIDE_INT >= 64)
10521 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10522 else if (i < HOST_BITS_PER_WIDE_INT)
10523 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10525 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10527 op1 = immed_double_const (~lo, ~hi, DImode);
10530 emit_move_insn (operands[2], op1);
10534 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10539 [(match_scratch:DI 2 "r")
10540 (parallel [(set (zero_extract:DI
10541 (match_operand:DI 0 "register_operand" "")
10543 (match_operand:DI 1 "const_0_to_63_operand" ""))
10544 (not:DI (zero_extract:DI
10545 (match_dup 0) (const_int 1) (match_dup 1))))
10546 (clobber (reg:CC FLAGS_REG))])]
10547 "TARGET_64BIT && !TARGET_USE_BT"
10550 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10553 if (HOST_BITS_PER_WIDE_INT >= 64)
10554 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10555 else if (i < HOST_BITS_PER_WIDE_INT)
10556 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10558 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10560 op1 = immed_double_const (lo, hi, DImode);
10563 emit_move_insn (operands[2], op1);
10567 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10571 (define_insn "*bt<mode>"
10572 [(set (reg:CCC FLAGS_REG)
10574 (zero_extract:SWI48
10575 (match_operand:SWI48 0 "register_operand" "r")
10577 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10579 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10580 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10581 [(set_attr "type" "alu1")
10582 (set_attr "prefix_0f" "1")
10583 (set_attr "mode" "<MODE>")])
10585 ;; Store-flag instructions.
10587 ;; For all sCOND expanders, also expand the compare or test insn that
10588 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10590 (define_insn_and_split "*setcc_di_1"
10591 [(set (match_operand:DI 0 "register_operand" "=q")
10592 (match_operator:DI 1 "ix86_comparison_operator"
10593 [(reg FLAGS_REG) (const_int 0)]))]
10594 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10596 "&& reload_completed"
10597 [(set (match_dup 2) (match_dup 1))
10598 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10600 PUT_MODE (operands[1], QImode);
10601 operands[2] = gen_lowpart (QImode, operands[0]);
10604 (define_insn_and_split "*setcc_si_1_and"
10605 [(set (match_operand:SI 0 "register_operand" "=q")
10606 (match_operator:SI 1 "ix86_comparison_operator"
10607 [(reg FLAGS_REG) (const_int 0)]))
10608 (clobber (reg:CC FLAGS_REG))]
10609 "!TARGET_PARTIAL_REG_STALL
10610 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10612 "&& reload_completed"
10613 [(set (match_dup 2) (match_dup 1))
10614 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10615 (clobber (reg:CC FLAGS_REG))])]
10617 PUT_MODE (operands[1], QImode);
10618 operands[2] = gen_lowpart (QImode, operands[0]);
10621 (define_insn_and_split "*setcc_si_1_movzbl"
10622 [(set (match_operand:SI 0 "register_operand" "=q")
10623 (match_operator:SI 1 "ix86_comparison_operator"
10624 [(reg FLAGS_REG) (const_int 0)]))]
10625 "!TARGET_PARTIAL_REG_STALL
10626 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10628 "&& reload_completed"
10629 [(set (match_dup 2) (match_dup 1))
10630 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10632 PUT_MODE (operands[1], QImode);
10633 operands[2] = gen_lowpart (QImode, operands[0]);
10636 (define_insn "*setcc_qi"
10637 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10638 (match_operator:QI 1 "ix86_comparison_operator"
10639 [(reg FLAGS_REG) (const_int 0)]))]
10642 [(set_attr "type" "setcc")
10643 (set_attr "mode" "QI")])
10645 (define_insn "*setcc_qi_slp"
10646 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10647 (match_operator:QI 1 "ix86_comparison_operator"
10648 [(reg FLAGS_REG) (const_int 0)]))]
10651 [(set_attr "type" "setcc")
10652 (set_attr "mode" "QI")])
10654 ;; In general it is not safe to assume too much about CCmode registers,
10655 ;; so simplify-rtx stops when it sees a second one. Under certain
10656 ;; conditions this is safe on x86, so help combine not create
10663 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10664 (ne:QI (match_operator 1 "ix86_comparison_operator"
10665 [(reg FLAGS_REG) (const_int 0)])
10668 [(set (match_dup 0) (match_dup 1))]
10669 "PUT_MODE (operands[1], QImode);")
10672 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10673 (ne:QI (match_operator 1 "ix86_comparison_operator"
10674 [(reg FLAGS_REG) (const_int 0)])
10677 [(set (match_dup 0) (match_dup 1))]
10678 "PUT_MODE (operands[1], QImode);")
10681 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10682 (eq:QI (match_operator 1 "ix86_comparison_operator"
10683 [(reg FLAGS_REG) (const_int 0)])
10686 [(set (match_dup 0) (match_dup 1))]
10688 rtx new_op1 = copy_rtx (operands[1]);
10689 operands[1] = new_op1;
10690 PUT_MODE (new_op1, QImode);
10691 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10692 GET_MODE (XEXP (new_op1, 0))));
10694 /* Make sure that (a) the CCmode we have for the flags is strong
10695 enough for the reversed compare or (b) we have a valid FP compare. */
10696 if (! ix86_comparison_operator (new_op1, VOIDmode))
10701 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10702 (eq:QI (match_operator 1 "ix86_comparison_operator"
10703 [(reg FLAGS_REG) (const_int 0)])
10706 [(set (match_dup 0) (match_dup 1))]
10708 rtx new_op1 = copy_rtx (operands[1]);
10709 operands[1] = new_op1;
10710 PUT_MODE (new_op1, QImode);
10711 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10712 GET_MODE (XEXP (new_op1, 0))));
10714 /* Make sure that (a) the CCmode we have for the flags is strong
10715 enough for the reversed compare or (b) we have a valid FP compare. */
10716 if (! ix86_comparison_operator (new_op1, VOIDmode))
10720 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10721 ;; subsequent logical operations are used to imitate conditional moves.
10722 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10725 (define_insn "setcc_<mode>_sse"
10726 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10727 (match_operator:MODEF 3 "sse_comparison_operator"
10728 [(match_operand:MODEF 1 "register_operand" "0,x")
10729 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10730 "SSE_FLOAT_MODE_P (<MODE>mode)"
10732 cmp%D3s<ssemodefsuffix>\t{%2, %0|%0, %2}
10733 vcmp%D3s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
10734 [(set_attr "isa" "noavx,avx")
10735 (set_attr "type" "ssecmp")
10736 (set_attr "length_immediate" "1")
10737 (set_attr "prefix" "orig,vex")
10738 (set_attr "mode" "<MODE>")])
10740 ;; Basic conditional jump instructions.
10741 ;; We ignore the overflow flag for signed branch instructions.
10743 (define_insn "*jcc_1"
10745 (if_then_else (match_operator 1 "ix86_comparison_operator"
10746 [(reg FLAGS_REG) (const_int 0)])
10747 (label_ref (match_operand 0 "" ""))
10751 [(set_attr "type" "ibr")
10752 (set_attr "modrm" "0")
10753 (set (attr "length")
10754 (if_then_else (and (ge (minus (match_dup 0) (pc))
10756 (lt (minus (match_dup 0) (pc))
10761 (define_insn "*jcc_2"
10763 (if_then_else (match_operator 1 "ix86_comparison_operator"
10764 [(reg FLAGS_REG) (const_int 0)])
10766 (label_ref (match_operand 0 "" ""))))]
10769 [(set_attr "type" "ibr")
10770 (set_attr "modrm" "0")
10771 (set (attr "length")
10772 (if_then_else (and (ge (minus (match_dup 0) (pc))
10774 (lt (minus (match_dup 0) (pc))
10779 ;; In general it is not safe to assume too much about CCmode registers,
10780 ;; so simplify-rtx stops when it sees a second one. Under certain
10781 ;; conditions this is safe on x86, so help combine not create
10789 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10790 [(reg FLAGS_REG) (const_int 0)])
10792 (label_ref (match_operand 1 "" ""))
10796 (if_then_else (match_dup 0)
10797 (label_ref (match_dup 1))
10799 "PUT_MODE (operands[0], VOIDmode);")
10803 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10804 [(reg FLAGS_REG) (const_int 0)])
10806 (label_ref (match_operand 1 "" ""))
10810 (if_then_else (match_dup 0)
10811 (label_ref (match_dup 1))
10814 rtx new_op0 = copy_rtx (operands[0]);
10815 operands[0] = new_op0;
10816 PUT_MODE (new_op0, VOIDmode);
10817 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10818 GET_MODE (XEXP (new_op0, 0))));
10820 /* Make sure that (a) the CCmode we have for the flags is strong
10821 enough for the reversed compare or (b) we have a valid FP compare. */
10822 if (! ix86_comparison_operator (new_op0, VOIDmode))
10826 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10827 ;; pass generates from shift insn with QImode operand. Actually, the mode
10828 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10829 ;; appropriate modulo of the bit offset value.
10831 (define_insn_and_split "*jcc_bt<mode>"
10833 (if_then_else (match_operator 0 "bt_comparison_operator"
10834 [(zero_extract:SWI48
10835 (match_operand:SWI48 1 "register_operand" "r")
10838 (match_operand:QI 2 "register_operand" "r")))
10840 (label_ref (match_operand 3 "" ""))
10842 (clobber (reg:CC FLAGS_REG))]
10843 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10846 [(set (reg:CCC FLAGS_REG)
10848 (zero_extract:SWI48
10854 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10855 (label_ref (match_dup 3))
10858 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10860 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10863 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10864 ;; also for DImode, this is what combine produces.
10865 (define_insn_and_split "*jcc_bt<mode>_mask"
10867 (if_then_else (match_operator 0 "bt_comparison_operator"
10868 [(zero_extract:SWI48
10869 (match_operand:SWI48 1 "register_operand" "r")
10872 (match_operand:SI 2 "register_operand" "r")
10873 (match_operand:SI 3 "const_int_operand" "n")))])
10874 (label_ref (match_operand 4 "" ""))
10876 (clobber (reg:CC FLAGS_REG))]
10877 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10878 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10879 == GET_MODE_BITSIZE (<MODE>mode)-1"
10882 [(set (reg:CCC FLAGS_REG)
10884 (zero_extract:SWI48
10890 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10891 (label_ref (match_dup 4))
10894 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10896 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10899 (define_insn_and_split "*jcc_btsi_1"
10901 (if_then_else (match_operator 0 "bt_comparison_operator"
10904 (match_operand:SI 1 "register_operand" "r")
10905 (match_operand:QI 2 "register_operand" "r"))
10908 (label_ref (match_operand 3 "" ""))
10910 (clobber (reg:CC FLAGS_REG))]
10911 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10914 [(set (reg:CCC FLAGS_REG)
10922 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10923 (label_ref (match_dup 3))
10926 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10928 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10931 ;; avoid useless masking of bit offset operand
10932 (define_insn_and_split "*jcc_btsi_mask_1"
10935 (match_operator 0 "bt_comparison_operator"
10938 (match_operand:SI 1 "register_operand" "r")
10941 (match_operand:SI 2 "register_operand" "r")
10942 (match_operand:SI 3 "const_int_operand" "n")) 0))
10945 (label_ref (match_operand 4 "" ""))
10947 (clobber (reg:CC FLAGS_REG))]
10948 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10949 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10952 [(set (reg:CCC FLAGS_REG)
10960 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10961 (label_ref (match_dup 4))
10963 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10965 ;; Define combination compare-and-branch fp compare instructions to help
10968 (define_insn "*fp_jcc_1_387"
10970 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10971 [(match_operand 1 "register_operand" "f")
10972 (match_operand 2 "nonimmediate_operand" "fm")])
10973 (label_ref (match_operand 3 "" ""))
10975 (clobber (reg:CCFP FPSR_REG))
10976 (clobber (reg:CCFP FLAGS_REG))
10977 (clobber (match_scratch:HI 4 "=a"))]
10979 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10980 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10981 && SELECT_CC_MODE (GET_CODE (operands[0]),
10982 operands[1], operands[2]) == CCFPmode
10986 (define_insn "*fp_jcc_1r_387"
10988 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10989 [(match_operand 1 "register_operand" "f")
10990 (match_operand 2 "nonimmediate_operand" "fm")])
10992 (label_ref (match_operand 3 "" ""))))
10993 (clobber (reg:CCFP FPSR_REG))
10994 (clobber (reg:CCFP FLAGS_REG))
10995 (clobber (match_scratch:HI 4 "=a"))]
10997 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10998 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10999 && SELECT_CC_MODE (GET_CODE (operands[0]),
11000 operands[1], operands[2]) == CCFPmode
11004 (define_insn "*fp_jcc_2_387"
11006 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11007 [(match_operand 1 "register_operand" "f")
11008 (match_operand 2 "register_operand" "f")])
11009 (label_ref (match_operand 3 "" ""))
11011 (clobber (reg:CCFP FPSR_REG))
11012 (clobber (reg:CCFP FLAGS_REG))
11013 (clobber (match_scratch:HI 4 "=a"))]
11014 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11015 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11019 (define_insn "*fp_jcc_2r_387"
11021 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11022 [(match_operand 1 "register_operand" "f")
11023 (match_operand 2 "register_operand" "f")])
11025 (label_ref (match_operand 3 "" ""))))
11026 (clobber (reg:CCFP FPSR_REG))
11027 (clobber (reg:CCFP FLAGS_REG))
11028 (clobber (match_scratch:HI 4 "=a"))]
11029 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11030 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11034 (define_insn "*fp_jcc_3_387"
11036 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11037 [(match_operand 1 "register_operand" "f")
11038 (match_operand 2 "const0_operand" "")])
11039 (label_ref (match_operand 3 "" ""))
11041 (clobber (reg:CCFP FPSR_REG))
11042 (clobber (reg:CCFP FLAGS_REG))
11043 (clobber (match_scratch:HI 4 "=a"))]
11044 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11045 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11046 && SELECT_CC_MODE (GET_CODE (operands[0]),
11047 operands[1], operands[2]) == CCFPmode
11053 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11054 [(match_operand 1 "register_operand" "")
11055 (match_operand 2 "nonimmediate_operand" "")])
11056 (match_operand 3 "" "")
11057 (match_operand 4 "" "")))
11058 (clobber (reg:CCFP FPSR_REG))
11059 (clobber (reg:CCFP FLAGS_REG))]
11063 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11064 operands[3], operands[4], NULL_RTX, NULL_RTX);
11070 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11071 [(match_operand 1 "register_operand" "")
11072 (match_operand 2 "general_operand" "")])
11073 (match_operand 3 "" "")
11074 (match_operand 4 "" "")))
11075 (clobber (reg:CCFP FPSR_REG))
11076 (clobber (reg:CCFP FLAGS_REG))
11077 (clobber (match_scratch:HI 5 "=a"))]
11081 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11082 operands[3], operands[4], operands[5], NULL_RTX);
11086 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11087 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11088 ;; with a precedence over other operators and is always put in the first
11089 ;; place. Swap condition and operands to match ficom instruction.
11091 (define_insn "*fp_jcc_4_<mode>_387"
11094 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11095 [(match_operator 1 "float_operator"
11096 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11097 (match_operand 3 "register_operand" "f,f")])
11098 (label_ref (match_operand 4 "" ""))
11100 (clobber (reg:CCFP FPSR_REG))
11101 (clobber (reg:CCFP FLAGS_REG))
11102 (clobber (match_scratch:HI 5 "=a,a"))]
11103 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11104 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11105 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11106 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11113 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11114 [(match_operator 1 "float_operator"
11115 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11116 (match_operand 3 "register_operand" "")])
11117 (match_operand 4 "" "")
11118 (match_operand 5 "" "")))
11119 (clobber (reg:CCFP FPSR_REG))
11120 (clobber (reg:CCFP FLAGS_REG))
11121 (clobber (match_scratch:HI 6 "=a"))]
11125 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11127 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11128 operands[3], operands[7],
11129 operands[4], operands[5], operands[6], NULL_RTX);
11133 ;; %%% Kill this when reload knows how to do it.
11137 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11138 [(match_operator 1 "float_operator"
11139 [(match_operand:X87MODEI12 2 "register_operand" "")])
11140 (match_operand 3 "register_operand" "")])
11141 (match_operand 4 "" "")
11142 (match_operand 5 "" "")))
11143 (clobber (reg:CCFP FPSR_REG))
11144 (clobber (reg:CCFP FLAGS_REG))
11145 (clobber (match_scratch:HI 6 "=a"))]
11149 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11150 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11152 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11153 operands[3], operands[7],
11154 operands[4], operands[5], operands[6], operands[2]);
11158 ;; Unconditional and other jump instructions
11160 (define_insn "jump"
11162 (label_ref (match_operand 0 "" "")))]
11165 [(set_attr "type" "ibr")
11166 (set (attr "length")
11167 (if_then_else (and (ge (minus (match_dup 0) (pc))
11169 (lt (minus (match_dup 0) (pc))
11173 (set_attr "modrm" "0")])
11175 (define_expand "indirect_jump"
11176 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11180 (define_insn "*indirect_jump"
11181 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11184 [(set_attr "type" "ibr")
11185 (set_attr "length_immediate" "0")])
11187 (define_expand "tablejump"
11188 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11189 (use (label_ref (match_operand 1 "" "")))])]
11192 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11193 relative. Convert the relative address to an absolute address. */
11197 enum rtx_code code;
11199 /* We can't use @GOTOFF for text labels on VxWorks;
11200 see gotoff_operand. */
11201 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11205 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11207 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11211 op1 = pic_offset_table_rtx;
11216 op0 = pic_offset_table_rtx;
11220 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11225 (define_insn "*tablejump_1"
11226 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11227 (use (label_ref (match_operand 1 "" "")))]
11230 [(set_attr "type" "ibr")
11231 (set_attr "length_immediate" "0")])
11233 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11236 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11237 (set (match_operand:QI 1 "register_operand" "")
11238 (match_operator:QI 2 "ix86_comparison_operator"
11239 [(reg FLAGS_REG) (const_int 0)]))
11240 (set (match_operand 3 "q_regs_operand" "")
11241 (zero_extend (match_dup 1)))]
11242 "(peep2_reg_dead_p (3, operands[1])
11243 || operands_match_p (operands[1], operands[3]))
11244 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11245 [(set (match_dup 4) (match_dup 0))
11246 (set (strict_low_part (match_dup 5))
11249 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11250 operands[5] = gen_lowpart (QImode, operands[3]);
11251 ix86_expand_clear (operands[3]);
11254 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11257 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11258 (set (match_operand:QI 1 "register_operand" "")
11259 (match_operator:QI 2 "ix86_comparison_operator"
11260 [(reg FLAGS_REG) (const_int 0)]))
11261 (parallel [(set (match_operand 3 "q_regs_operand" "")
11262 (zero_extend (match_dup 1)))
11263 (clobber (reg:CC FLAGS_REG))])]
11264 "(peep2_reg_dead_p (3, operands[1])
11265 || operands_match_p (operands[1], operands[3]))
11266 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11267 [(set (match_dup 4) (match_dup 0))
11268 (set (strict_low_part (match_dup 5))
11271 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11272 operands[5] = gen_lowpart (QImode, operands[3]);
11273 ix86_expand_clear (operands[3]);
11276 ;; Call instructions.
11278 ;; The predicates normally associated with named expanders are not properly
11279 ;; checked for calls. This is a bug in the generic code, but it isn't that
11280 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11282 ;; P6 processors will jump to the address after the decrement when %esp
11283 ;; is used as a call operand, so they will execute return address as a code.
11284 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11286 ;; Call subroutine returning no value.
11288 (define_expand "call_pop"
11289 [(parallel [(call (match_operand:QI 0 "" "")
11290 (match_operand:SI 1 "" ""))
11291 (set (reg:SI SP_REG)
11292 (plus:SI (reg:SI SP_REG)
11293 (match_operand:SI 3 "" "")))])]
11296 ix86_expand_call (NULL, operands[0], operands[1],
11297 operands[2], operands[3], 0);
11301 (define_insn_and_split "*call_pop_0_vzeroupper"
11303 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11304 (match_operand:SI 1 "" ""))
11305 (set (reg:SI SP_REG)
11306 (plus:SI (reg:SI SP_REG)
11307 (match_operand:SI 2 "immediate_operand" "")))])
11308 (unspec [(match_operand 3 "const_int_operand" "")]
11309 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11310 "TARGET_VZEROUPPER && !TARGET_64BIT"
11312 "&& reload_completed"
11314 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11315 [(set_attr "type" "call")])
11317 (define_insn "*call_pop_0"
11318 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11319 (match_operand:SI 1 "" ""))
11320 (set (reg:SI SP_REG)
11321 (plus:SI (reg:SI SP_REG)
11322 (match_operand:SI 2 "immediate_operand" "")))]
11325 if (SIBLING_CALL_P (insn))
11328 return "call\t%P0";
11330 [(set_attr "type" "call")])
11332 (define_insn_and_split "*call_pop_1_vzeroupper"
11334 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11335 (match_operand:SI 1 "" ""))
11336 (set (reg:SI SP_REG)
11337 (plus:SI (reg:SI SP_REG)
11338 (match_operand:SI 2 "immediate_operand" "i")))])
11339 (unspec [(match_operand 3 "const_int_operand" "")]
11340 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11341 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11343 "&& reload_completed"
11345 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11346 [(set_attr "type" "call")])
11348 (define_insn "*call_pop_1"
11349 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11350 (match_operand:SI 1 "" ""))
11351 (set (reg:SI SP_REG)
11352 (plus:SI (reg:SI SP_REG)
11353 (match_operand:SI 2 "immediate_operand" "i")))]
11354 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11356 if (constant_call_address_operand (operands[0], Pmode))
11357 return "call\t%P0";
11358 return "call\t%A0";
11360 [(set_attr "type" "call")])
11362 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11364 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11365 (match_operand:SI 1 "" ""))
11366 (set (reg:SI SP_REG)
11367 (plus:SI (reg:SI SP_REG)
11368 (match_operand:SI 2 "immediate_operand" "i,i")))])
11369 (unspec [(match_operand 3 "const_int_operand" "")]
11370 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11371 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11373 "&& reload_completed"
11375 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11376 [(set_attr "type" "call")])
11378 (define_insn "*sibcall_pop_1"
11379 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11380 (match_operand:SI 1 "" ""))
11381 (set (reg:SI SP_REG)
11382 (plus:SI (reg:SI SP_REG)
11383 (match_operand:SI 2 "immediate_operand" "i,i")))]
11384 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11388 [(set_attr "type" "call")])
11390 (define_expand "call"
11391 [(call (match_operand:QI 0 "" "")
11392 (match_operand 1 "" ""))
11393 (use (match_operand 2 "" ""))]
11396 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11400 (define_expand "sibcall"
11401 [(call (match_operand:QI 0 "" "")
11402 (match_operand 1 "" ""))
11403 (use (match_operand 2 "" ""))]
11406 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11410 (define_insn_and_split "*call_0_vzeroupper"
11411 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11412 (match_operand 1 "" ""))
11413 (unspec [(match_operand 2 "const_int_operand" "")]
11414 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11415 "TARGET_VZEROUPPER"
11417 "&& reload_completed"
11419 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11420 [(set_attr "type" "call")])
11422 (define_insn "*call_0"
11423 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11424 (match_operand 1 "" ""))]
11426 { return ix86_output_call_insn (insn, operands[0], 0); }
11427 [(set_attr "type" "call")])
11429 (define_insn_and_split "*call_1_vzeroupper"
11430 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11431 (match_operand 1 "" ""))
11432 (unspec [(match_operand 2 "const_int_operand" "")]
11433 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11434 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11436 "&& reload_completed"
11438 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11439 [(set_attr "type" "call")])
11441 (define_insn "*call_1"
11442 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11443 (match_operand 1 "" ""))]
11444 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11445 { return ix86_output_call_insn (insn, operands[0], 0); }
11446 [(set_attr "type" "call")])
11448 (define_insn_and_split "*sibcall_1_vzeroupper"
11449 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11450 (match_operand 1 "" ""))
11451 (unspec [(match_operand 2 "const_int_operand" "")]
11452 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11453 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11455 "&& reload_completed"
11457 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11458 [(set_attr "type" "call")])
11460 (define_insn "*sibcall_1"
11461 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11462 (match_operand 1 "" ""))]
11463 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11464 { return ix86_output_call_insn (insn, operands[0], 0); }
11465 [(set_attr "type" "call")])
11467 (define_insn_and_split "*call_1_rex64_vzeroupper"
11468 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11469 (match_operand 1 "" ""))
11470 (unspec [(match_operand 2 "const_int_operand" "")]
11471 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11472 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11473 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11475 "&& reload_completed"
11477 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11478 [(set_attr "type" "call")])
11480 (define_insn "*call_1_rex64"
11481 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11482 (match_operand 1 "" ""))]
11483 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11484 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11485 { return ix86_output_call_insn (insn, operands[0], 0); }
11486 [(set_attr "type" "call")])
11488 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11490 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11491 (match_operand 1 "" ""))
11492 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11493 (clobber (reg:TI XMM6_REG))
11494 (clobber (reg:TI XMM7_REG))
11495 (clobber (reg:TI XMM8_REG))
11496 (clobber (reg:TI XMM9_REG))
11497 (clobber (reg:TI XMM10_REG))
11498 (clobber (reg:TI XMM11_REG))
11499 (clobber (reg:TI XMM12_REG))
11500 (clobber (reg:TI XMM13_REG))
11501 (clobber (reg:TI XMM14_REG))
11502 (clobber (reg:TI XMM15_REG))
11503 (clobber (reg:DI SI_REG))
11504 (clobber (reg:DI DI_REG))])
11505 (unspec [(match_operand 2 "const_int_operand" "")]
11506 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11507 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11509 "&& reload_completed"
11511 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11512 [(set_attr "type" "call")])
11514 (define_insn "*call_1_rex64_ms_sysv"
11515 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11516 (match_operand 1 "" ""))
11517 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11518 (clobber (reg:TI XMM6_REG))
11519 (clobber (reg:TI XMM7_REG))
11520 (clobber (reg:TI XMM8_REG))
11521 (clobber (reg:TI XMM9_REG))
11522 (clobber (reg:TI XMM10_REG))
11523 (clobber (reg:TI XMM11_REG))
11524 (clobber (reg:TI XMM12_REG))
11525 (clobber (reg:TI XMM13_REG))
11526 (clobber (reg:TI XMM14_REG))
11527 (clobber (reg:TI XMM15_REG))
11528 (clobber (reg:DI SI_REG))
11529 (clobber (reg:DI DI_REG))]
11530 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11531 { return ix86_output_call_insn (insn, operands[0], 0); }
11532 [(set_attr "type" "call")])
11534 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11535 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11536 (match_operand 1 "" ""))
11537 (unspec [(match_operand 2 "const_int_operand" "")]
11538 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11539 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11541 "&& reload_completed"
11543 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11544 [(set_attr "type" "call")])
11546 (define_insn "*call_1_rex64_large"
11547 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11548 (match_operand 1 "" ""))]
11549 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11550 { return ix86_output_call_insn (insn, operands[0], 0); }
11551 [(set_attr "type" "call")])
11553 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11554 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11555 (match_operand 1 "" ""))
11556 (unspec [(match_operand 2 "const_int_operand" "")]
11557 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11558 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11560 "&& reload_completed"
11562 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11563 [(set_attr "type" "call")])
11565 (define_insn "*sibcall_1_rex64"
11566 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11567 (match_operand 1 "" ""))]
11568 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11569 { return ix86_output_call_insn (insn, operands[0], 0); }
11570 [(set_attr "type" "call")])
11572 ;; Call subroutine, returning value in operand 0
11573 (define_expand "call_value_pop"
11574 [(parallel [(set (match_operand 0 "" "")
11575 (call (match_operand:QI 1 "" "")
11576 (match_operand:SI 2 "" "")))
11577 (set (reg:SI SP_REG)
11578 (plus:SI (reg:SI SP_REG)
11579 (match_operand:SI 4 "" "")))])]
11582 ix86_expand_call (operands[0], operands[1], operands[2],
11583 operands[3], operands[4], 0);
11587 (define_expand "call_value"
11588 [(set (match_operand 0 "" "")
11589 (call (match_operand:QI 1 "" "")
11590 (match_operand:SI 2 "" "")))
11591 (use (match_operand:SI 3 "" ""))]
11592 ;; Operand 3 is not used on the i386.
11595 ix86_expand_call (operands[0], operands[1], operands[2],
11596 operands[3], NULL, 0);
11600 (define_expand "sibcall_value"
11601 [(set (match_operand 0 "" "")
11602 (call (match_operand:QI 1 "" "")
11603 (match_operand:SI 2 "" "")))
11604 (use (match_operand:SI 3 "" ""))]
11605 ;; Operand 3 is not used on the i386.
11608 ix86_expand_call (operands[0], operands[1], operands[2],
11609 operands[3], NULL, 1);
11613 ;; Call subroutine returning any type.
11615 (define_expand "untyped_call"
11616 [(parallel [(call (match_operand 0 "" "")
11618 (match_operand 1 "" "")
11619 (match_operand 2 "" "")])]
11624 /* In order to give reg-stack an easier job in validating two
11625 coprocessor registers as containing a possible return value,
11626 simply pretend the untyped call returns a complex long double
11629 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11630 and should have the default ABI. */
11632 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11633 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11634 operands[0], const0_rtx,
11635 GEN_INT ((TARGET_64BIT
11636 ? (ix86_abi == SYSV_ABI
11637 ? X86_64_SSE_REGPARM_MAX
11638 : X86_64_MS_SSE_REGPARM_MAX)
11639 : X86_32_SSE_REGPARM_MAX)
11643 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11645 rtx set = XVECEXP (operands[2], 0, i);
11646 emit_move_insn (SET_DEST (set), SET_SRC (set));
11649 /* The optimizer does not know that the call sets the function value
11650 registers we stored in the result block. We avoid problems by
11651 claiming that all hard registers are used and clobbered at this
11653 emit_insn (gen_blockage ());
11658 ;; Prologue and epilogue instructions
11660 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11661 ;; all of memory. This blocks insns from being moved across this point.
11663 (define_insn "blockage"
11664 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11667 [(set_attr "length" "0")])
11669 ;; Do not schedule instructions accessing memory across this point.
11671 (define_expand "memory_blockage"
11672 [(set (match_dup 0)
11673 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11676 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11677 MEM_VOLATILE_P (operands[0]) = 1;
11680 (define_insn "*memory_blockage"
11681 [(set (match_operand:BLK 0 "" "")
11682 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11685 [(set_attr "length" "0")])
11687 ;; As USE insns aren't meaningful after reload, this is used instead
11688 ;; to prevent deleting instructions setting registers for PIC code
11689 (define_insn "prologue_use"
11690 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11693 [(set_attr "length" "0")])
11695 ;; Insn emitted into the body of a function to return from a function.
11696 ;; This is only done if the function's epilogue is known to be simple.
11697 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11699 (define_expand "return"
11701 "ix86_can_use_return_insn_p ()"
11703 if (crtl->args.pops_args)
11705 rtx popc = GEN_INT (crtl->args.pops_args);
11706 emit_jump_insn (gen_return_pop_internal (popc));
11711 (define_insn "return_internal"
11715 [(set_attr "length" "1")
11716 (set_attr "atom_unit" "jeu")
11717 (set_attr "length_immediate" "0")
11718 (set_attr "modrm" "0")])
11720 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11721 ;; instruction Athlon and K8 have.
11723 (define_insn "return_internal_long"
11725 (unspec [(const_int 0)] UNSPEC_REP)]
11728 [(set_attr "length" "2")
11729 (set_attr "atom_unit" "jeu")
11730 (set_attr "length_immediate" "0")
11731 (set_attr "prefix_rep" "1")
11732 (set_attr "modrm" "0")])
11734 (define_insn "return_pop_internal"
11736 (use (match_operand:SI 0 "const_int_operand" ""))]
11739 [(set_attr "length" "3")
11740 (set_attr "atom_unit" "jeu")
11741 (set_attr "length_immediate" "2")
11742 (set_attr "modrm" "0")])
11744 (define_insn "return_indirect_internal"
11746 (use (match_operand:SI 0 "register_operand" "r"))]
11749 [(set_attr "type" "ibr")
11750 (set_attr "length_immediate" "0")])
11756 [(set_attr "length" "1")
11757 (set_attr "length_immediate" "0")
11758 (set_attr "modrm" "0")])
11760 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11761 (define_insn "nops"
11762 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11766 int num = INTVAL (operands[0]);
11768 gcc_assert (num >= 1 && num <= 8);
11771 fputs ("\tnop\n", asm_out_file);
11775 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11776 (set_attr "length_immediate" "0")
11777 (set_attr "modrm" "0")])
11779 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11780 ;; branch prediction penalty for the third jump in a 16-byte
11784 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11787 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11788 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11790 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11791 The align insn is used to avoid 3 jump instructions in the row to improve
11792 branch prediction and the benefits hardly outweigh the cost of extra 8
11793 nops on the average inserted by full alignment pseudo operation. */
11797 [(set_attr "length" "16")])
11799 (define_expand "prologue"
11802 "ix86_expand_prologue (); DONE;")
11804 (define_insn "set_got"
11805 [(set (match_operand:SI 0 "register_operand" "=r")
11806 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11807 (clobber (reg:CC FLAGS_REG))]
11809 "* return output_set_got (operands[0], NULL_RTX);"
11810 [(set_attr "type" "multi")
11811 (set_attr "length" "12")])
11813 (define_insn "set_got_labelled"
11814 [(set (match_operand:SI 0 "register_operand" "=r")
11815 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11817 (clobber (reg:CC FLAGS_REG))]
11819 "* return output_set_got (operands[0], operands[1]);"
11820 [(set_attr "type" "multi")
11821 (set_attr "length" "12")])
11823 (define_insn "set_got_rex64"
11824 [(set (match_operand:DI 0 "register_operand" "=r")
11825 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11827 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11828 [(set_attr "type" "lea")
11829 (set_attr "length_address" "4")
11830 (set_attr "mode" "DI")])
11832 (define_insn "set_rip_rex64"
11833 [(set (match_operand:DI 0 "register_operand" "=r")
11834 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11836 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11837 [(set_attr "type" "lea")
11838 (set_attr "length_address" "4")
11839 (set_attr "mode" "DI")])
11841 (define_insn "set_got_offset_rex64"
11842 [(set (match_operand:DI 0 "register_operand" "=r")
11844 [(label_ref (match_operand 1 "" ""))]
11845 UNSPEC_SET_GOT_OFFSET))]
11847 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11848 [(set_attr "type" "imov")
11849 (set_attr "length_immediate" "0")
11850 (set_attr "length_address" "8")
11851 (set_attr "mode" "DI")])
11853 (define_expand "epilogue"
11856 "ix86_expand_epilogue (1); DONE;")
11858 (define_expand "sibcall_epilogue"
11861 "ix86_expand_epilogue (0); DONE;")
11863 (define_expand "eh_return"
11864 [(use (match_operand 0 "register_operand" ""))]
11867 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11869 /* Tricky bit: we write the address of the handler to which we will
11870 be returning into someone else's stack frame, one word below the
11871 stack address we wish to restore. */
11872 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11873 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11874 tmp = gen_rtx_MEM (Pmode, tmp);
11875 emit_move_insn (tmp, ra);
11877 emit_jump_insn (gen_eh_return_internal ());
11882 (define_insn_and_split "eh_return_internal"
11886 "epilogue_completed"
11888 "ix86_expand_epilogue (2); DONE;")
11890 (define_insn "leave"
11891 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11892 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11893 (clobber (mem:BLK (scratch)))]
11896 [(set_attr "type" "leave")])
11898 (define_insn "leave_rex64"
11899 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11900 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11901 (clobber (mem:BLK (scratch)))]
11904 [(set_attr "type" "leave")])
11906 ;; Handle -fsplit-stack.
11908 (define_expand "split_stack_prologue"
11912 ix86_expand_split_stack_prologue ();
11916 ;; In order to support the call/return predictor, we use a return
11917 ;; instruction which the middle-end doesn't see.
11918 (define_insn "split_stack_return"
11919 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11920 UNSPECV_SPLIT_STACK_RETURN)]
11923 if (operands[0] == const0_rtx)
11928 [(set_attr "atom_unit" "jeu")
11929 (set_attr "modrm" "0")
11930 (set (attr "length")
11931 (if_then_else (match_operand:SI 0 "const0_operand" "")
11934 (set (attr "length_immediate")
11935 (if_then_else (match_operand:SI 0 "const0_operand" "")
11939 ;; If there are operand 0 bytes available on the stack, jump to
11942 (define_expand "split_stack_space_check"
11943 [(set (pc) (if_then_else
11944 (ltu (minus (reg SP_REG)
11945 (match_operand 0 "register_operand" ""))
11946 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11947 (label_ref (match_operand 1 "" ""))
11951 rtx reg, size, limit;
11953 reg = gen_reg_rtx (Pmode);
11954 size = force_reg (Pmode, operands[0]);
11955 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11956 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11957 UNSPEC_STACK_CHECK);
11958 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11959 ix86_expand_branch (GEU, reg, limit, operands[1]);
11964 ;; Bit manipulation instructions.
11966 (define_expand "ffs<mode>2"
11967 [(set (match_dup 2) (const_int -1))
11968 (parallel [(set (reg:CCZ FLAGS_REG)
11970 (match_operand:SWI48 1 "nonimmediate_operand" "")
11972 (set (match_operand:SWI48 0 "register_operand" "")
11973 (ctz:SWI48 (match_dup 1)))])
11974 (set (match_dup 0) (if_then_else:SWI48
11975 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11978 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11979 (clobber (reg:CC FLAGS_REG))])]
11982 if (<MODE>mode == SImode && !TARGET_CMOVE)
11984 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11987 operands[2] = gen_reg_rtx (<MODE>mode);
11990 (define_insn_and_split "ffssi2_no_cmove"
11991 [(set (match_operand:SI 0 "register_operand" "=r")
11992 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11993 (clobber (match_scratch:SI 2 "=&q"))
11994 (clobber (reg:CC FLAGS_REG))]
11997 "&& reload_completed"
11998 [(parallel [(set (reg:CCZ FLAGS_REG)
11999 (compare:CCZ (match_dup 1) (const_int 0)))
12000 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12001 (set (strict_low_part (match_dup 3))
12002 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12003 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12004 (clobber (reg:CC FLAGS_REG))])
12005 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12006 (clobber (reg:CC FLAGS_REG))])
12007 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12008 (clobber (reg:CC FLAGS_REG))])]
12010 operands[3] = gen_lowpart (QImode, operands[2]);
12011 ix86_expand_clear (operands[2]);
12014 (define_insn "*ffs<mode>_1"
12015 [(set (reg:CCZ FLAGS_REG)
12016 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12018 (set (match_operand:SWI48 0 "register_operand" "=r")
12019 (ctz:SWI48 (match_dup 1)))]
12021 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12022 [(set_attr "type" "alu1")
12023 (set_attr "prefix_0f" "1")
12024 (set_attr "mode" "<MODE>")])
12026 (define_insn "ctz<mode>2"
12027 [(set (match_operand:SWI248 0 "register_operand" "=r")
12028 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12029 (clobber (reg:CC FLAGS_REG))]
12033 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12035 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12037 [(set_attr "type" "alu1")
12038 (set_attr "prefix_0f" "1")
12039 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12040 (set_attr "mode" "<MODE>")])
12042 (define_expand "clz<mode>2"
12044 [(set (match_operand:SWI248 0 "register_operand" "")
12047 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12048 (clobber (reg:CC FLAGS_REG))])
12050 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12051 (clobber (reg:CC FLAGS_REG))])]
12056 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12059 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12062 (define_insn "clz<mode>2_abm"
12063 [(set (match_operand:SWI248 0 "register_operand" "=r")
12064 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12065 (clobber (reg:CC FLAGS_REG))]
12066 "TARGET_ABM || TARGET_BMI"
12067 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12068 [(set_attr "prefix_rep" "1")
12069 (set_attr "type" "bitmanip")
12070 (set_attr "mode" "<MODE>")])
12072 ;; BMI instructions.
12073 (define_insn "*bmi_andn_<mode>"
12074 [(set (match_operand:SWI48 0 "register_operand" "=r")
12077 (match_operand:SWI48 1 "register_operand" "r"))
12078 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12079 (clobber (reg:CC FLAGS_REG))]
12081 "andn\t{%2, %1, %0|%0, %1, %2}"
12082 [(set_attr "type" "bitmanip")
12083 (set_attr "mode" "<MODE>")])
12085 (define_insn "bmi_bextr_<mode>"
12086 [(set (match_operand:SWI48 0 "register_operand" "=r")
12087 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12088 (match_operand:SWI48 2 "register_operand" "r")]
12090 (clobber (reg:CC FLAGS_REG))]
12092 "bextr\t{%2, %1, %0|%0, %1, %2}"
12093 [(set_attr "type" "bitmanip")
12094 (set_attr "mode" "<MODE>")])
12096 (define_insn "*bmi_blsi_<mode>"
12097 [(set (match_operand:SWI48 0 "register_operand" "=r")
12100 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12102 (clobber (reg:CC FLAGS_REG))]
12104 "blsi\t{%1, %0|%0, %1}"
12105 [(set_attr "type" "bitmanip")
12106 (set_attr "mode" "<MODE>")])
12108 (define_insn "*bmi_blsmsk_<mode>"
12109 [(set (match_operand:SWI48 0 "register_operand" "=r")
12112 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12115 (clobber (reg:CC FLAGS_REG))]
12117 "blsmsk\t{%1, %0|%0, %1}"
12118 [(set_attr "type" "bitmanip")
12119 (set_attr "mode" "<MODE>")])
12121 (define_insn "*bmi_blsr_<mode>"
12122 [(set (match_operand:SWI48 0 "register_operand" "=r")
12125 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12128 (clobber (reg:CC FLAGS_REG))]
12130 "blsr\t{%1, %0|%0, %1}"
12131 [(set_attr "type" "bitmanip")
12132 (set_attr "mode" "<MODE>")])
12134 ;; TBM instructions.
12135 (define_insn "tbm_bextri_<mode>"
12136 [(set (match_operand:SWI48 0 "register_operand" "=r")
12137 (zero_extract:SWI48
12138 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12139 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12140 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12141 (clobber (reg:CC FLAGS_REG))]
12144 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12145 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12147 [(set_attr "type" "bitmanip")
12148 (set_attr "mode" "<MODE>")])
12150 (define_insn "*tbm_blcfill_<mode>"
12151 [(set (match_operand:SWI48 0 "register_operand" "=r")
12154 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12157 (clobber (reg:CC FLAGS_REG))]
12159 "blcfill\t{%1, %0|%0, %1}"
12160 [(set_attr "type" "bitmanip")
12161 (set_attr "mode" "<MODE>")])
12163 (define_insn "*tbm_blci_<mode>"
12164 [(set (match_operand:SWI48 0 "register_operand" "=r")
12168 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12171 (clobber (reg:CC FLAGS_REG))]
12173 "blci\t{%1, %0|%0, %1}"
12174 [(set_attr "type" "bitmanip")
12175 (set_attr "mode" "<MODE>")])
12177 (define_insn "*tbm_blcic_<mode>"
12178 [(set (match_operand:SWI48 0 "register_operand" "=r")
12181 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12185 (clobber (reg:CC FLAGS_REG))]
12187 "blcic\t{%1, %0|%0, %1}"
12188 [(set_attr "type" "bitmanip")
12189 (set_attr "mode" "<MODE>")])
12191 (define_insn "*tbm_blcmsk_<mode>"
12192 [(set (match_operand:SWI48 0 "register_operand" "=r")
12195 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12198 (clobber (reg:CC FLAGS_REG))]
12200 "blcmsk\t{%1, %0|%0, %1}"
12201 [(set_attr "type" "bitmanip")
12202 (set_attr "mode" "<MODE>")])
12204 (define_insn "*tbm_blcs_<mode>"
12205 [(set (match_operand:SWI48 0 "register_operand" "=r")
12208 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12211 (clobber (reg:CC FLAGS_REG))]
12213 "blcs\t{%1, %0|%0, %1}"
12214 [(set_attr "type" "bitmanip")
12215 (set_attr "mode" "<MODE>")])
12217 (define_insn "*tbm_blsfill_<mode>"
12218 [(set (match_operand:SWI48 0 "register_operand" "=r")
12221 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12224 (clobber (reg:CC FLAGS_REG))]
12226 "blsfill\t{%1, %0|%0, %1}"
12227 [(set_attr "type" "bitmanip")
12228 (set_attr "mode" "<MODE>")])
12230 (define_insn "*tbm_blsic_<mode>"
12231 [(set (match_operand:SWI48 0 "register_operand" "=r")
12234 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12238 (clobber (reg:CC FLAGS_REG))]
12240 "blsic\t{%1, %0|%0, %1}"
12241 [(set_attr "type" "bitmanip")
12242 (set_attr "mode" "<MODE>")])
12244 (define_insn "*tbm_t1mskc_<mode>"
12245 [(set (match_operand:SWI48 0 "register_operand" "=r")
12248 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12252 (clobber (reg:CC FLAGS_REG))]
12254 "t1mskc\t{%1, %0|%0, %1}"
12255 [(set_attr "type" "bitmanip")
12256 (set_attr "mode" "<MODE>")])
12258 (define_insn "*tbm_tzmsk_<mode>"
12259 [(set (match_operand:SWI48 0 "register_operand" "=r")
12262 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12266 (clobber (reg:CC FLAGS_REG))]
12268 "tzmsk\t{%1, %0|%0, %1}"
12269 [(set_attr "type" "bitmanip")
12270 (set_attr "mode" "<MODE>")])
12272 (define_insn "bsr_rex64"
12273 [(set (match_operand:DI 0 "register_operand" "=r")
12274 (minus:DI (const_int 63)
12275 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12276 (clobber (reg:CC FLAGS_REG))]
12278 "bsr{q}\t{%1, %0|%0, %1}"
12279 [(set_attr "type" "alu1")
12280 (set_attr "prefix_0f" "1")
12281 (set_attr "mode" "DI")])
12284 [(set (match_operand:SI 0 "register_operand" "=r")
12285 (minus:SI (const_int 31)
12286 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12287 (clobber (reg:CC FLAGS_REG))]
12289 "bsr{l}\t{%1, %0|%0, %1}"
12290 [(set_attr "type" "alu1")
12291 (set_attr "prefix_0f" "1")
12292 (set_attr "mode" "SI")])
12294 (define_insn "*bsrhi"
12295 [(set (match_operand:HI 0 "register_operand" "=r")
12296 (minus:HI (const_int 15)
12297 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12298 (clobber (reg:CC FLAGS_REG))]
12300 "bsr{w}\t{%1, %0|%0, %1}"
12301 [(set_attr "type" "alu1")
12302 (set_attr "prefix_0f" "1")
12303 (set_attr "mode" "HI")])
12305 (define_insn "popcount<mode>2"
12306 [(set (match_operand:SWI248 0 "register_operand" "=r")
12308 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12309 (clobber (reg:CC FLAGS_REG))]
12313 return "popcnt\t{%1, %0|%0, %1}";
12315 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12318 [(set_attr "prefix_rep" "1")
12319 (set_attr "type" "bitmanip")
12320 (set_attr "mode" "<MODE>")])
12322 (define_insn "*popcount<mode>2_cmp"
12323 [(set (reg FLAGS_REG)
12326 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12328 (set (match_operand:SWI248 0 "register_operand" "=r")
12329 (popcount:SWI248 (match_dup 1)))]
12330 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12333 return "popcnt\t{%1, %0|%0, %1}";
12335 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12338 [(set_attr "prefix_rep" "1")
12339 (set_attr "type" "bitmanip")
12340 (set_attr "mode" "<MODE>")])
12342 (define_insn "*popcountsi2_cmp_zext"
12343 [(set (reg FLAGS_REG)
12345 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12347 (set (match_operand:DI 0 "register_operand" "=r")
12348 (zero_extend:DI(popcount:SI (match_dup 1))))]
12349 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12352 return "popcnt\t{%1, %0|%0, %1}";
12354 return "popcnt{l}\t{%1, %0|%0, %1}";
12357 [(set_attr "prefix_rep" "1")
12358 (set_attr "type" "bitmanip")
12359 (set_attr "mode" "SI")])
12361 (define_expand "bswap<mode>2"
12362 [(set (match_operand:SWI48 0 "register_operand" "")
12363 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12366 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12368 rtx x = operands[0];
12370 emit_move_insn (x, operands[1]);
12371 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12372 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12373 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12378 (define_insn "*bswap<mode>2_movbe"
12379 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12380 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12382 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12385 movbe\t{%1, %0|%0, %1}
12386 movbe\t{%1, %0|%0, %1}"
12387 [(set_attr "type" "bitmanip,imov,imov")
12388 (set_attr "modrm" "0,1,1")
12389 (set_attr "prefix_0f" "*,1,1")
12390 (set_attr "prefix_extra" "*,1,1")
12391 (set_attr "mode" "<MODE>")])
12393 (define_insn "*bswap<mode>2_1"
12394 [(set (match_operand:SWI48 0 "register_operand" "=r")
12395 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12398 [(set_attr "type" "bitmanip")
12399 (set_attr "modrm" "0")
12400 (set_attr "mode" "<MODE>")])
12402 (define_insn "*bswaphi_lowpart_1"
12403 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12404 (bswap:HI (match_dup 0)))
12405 (clobber (reg:CC FLAGS_REG))]
12406 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12408 xchg{b}\t{%h0, %b0|%b0, %h0}
12409 rol{w}\t{$8, %0|%0, 8}"
12410 [(set_attr "length" "2,4")
12411 (set_attr "mode" "QI,HI")])
12413 (define_insn "bswaphi_lowpart"
12414 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12415 (bswap:HI (match_dup 0)))
12416 (clobber (reg:CC FLAGS_REG))]
12418 "rol{w}\t{$8, %0|%0, 8}"
12419 [(set_attr "length" "4")
12420 (set_attr "mode" "HI")])
12422 (define_expand "paritydi2"
12423 [(set (match_operand:DI 0 "register_operand" "")
12424 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12427 rtx scratch = gen_reg_rtx (QImode);
12430 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12431 NULL_RTX, operands[1]));
12433 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12434 gen_rtx_REG (CCmode, FLAGS_REG),
12436 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12439 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12442 rtx tmp = gen_reg_rtx (SImode);
12444 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12445 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12450 (define_expand "paritysi2"
12451 [(set (match_operand:SI 0 "register_operand" "")
12452 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12455 rtx scratch = gen_reg_rtx (QImode);
12458 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12460 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12461 gen_rtx_REG (CCmode, FLAGS_REG),
12463 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12465 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12469 (define_insn_and_split "paritydi2_cmp"
12470 [(set (reg:CC FLAGS_REG)
12471 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12473 (clobber (match_scratch:DI 0 "=r"))
12474 (clobber (match_scratch:SI 1 "=&r"))
12475 (clobber (match_scratch:HI 2 "=Q"))]
12478 "&& reload_completed"
12480 [(set (match_dup 1)
12481 (xor:SI (match_dup 1) (match_dup 4)))
12482 (clobber (reg:CC FLAGS_REG))])
12484 [(set (reg:CC FLAGS_REG)
12485 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12486 (clobber (match_dup 1))
12487 (clobber (match_dup 2))])]
12489 operands[4] = gen_lowpart (SImode, operands[3]);
12493 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12494 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12497 operands[1] = gen_highpart (SImode, operands[3]);
12500 (define_insn_and_split "paritysi2_cmp"
12501 [(set (reg:CC FLAGS_REG)
12502 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12504 (clobber (match_scratch:SI 0 "=r"))
12505 (clobber (match_scratch:HI 1 "=&Q"))]
12508 "&& reload_completed"
12510 [(set (match_dup 1)
12511 (xor:HI (match_dup 1) (match_dup 3)))
12512 (clobber (reg:CC FLAGS_REG))])
12514 [(set (reg:CC FLAGS_REG)
12515 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12516 (clobber (match_dup 1))])]
12518 operands[3] = gen_lowpart (HImode, operands[2]);
12520 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12521 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12524 (define_insn "*parityhi2_cmp"
12525 [(set (reg:CC FLAGS_REG)
12526 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12528 (clobber (match_scratch:HI 0 "=Q"))]
12530 "xor{b}\t{%h0, %b0|%b0, %h0}"
12531 [(set_attr "length" "2")
12532 (set_attr "mode" "HI")])
12534 ;; Thread-local storage patterns for ELF.
12536 ;; Note that these code sequences must appear exactly as shown
12537 ;; in order to allow linker relaxation.
12539 (define_insn "*tls_global_dynamic_32_gnu"
12540 [(set (match_operand:SI 0 "register_operand" "=a")
12541 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12542 (match_operand:SI 2 "tls_symbolic_operand" "")
12543 (match_operand:SI 3 "call_insn_operand" "")]
12545 (clobber (match_scratch:SI 4 "=d"))
12546 (clobber (match_scratch:SI 5 "=c"))
12547 (clobber (reg:CC FLAGS_REG))]
12548 "!TARGET_64BIT && TARGET_GNU_TLS"
12549 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12550 [(set_attr "type" "multi")
12551 (set_attr "length" "12")])
12553 (define_expand "tls_global_dynamic_32"
12554 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12557 (match_operand:SI 1 "tls_symbolic_operand" "")
12560 (clobber (match_scratch:SI 4 ""))
12561 (clobber (match_scratch:SI 5 ""))
12562 (clobber (reg:CC FLAGS_REG))])]
12566 operands[2] = pic_offset_table_rtx;
12569 operands[2] = gen_reg_rtx (Pmode);
12570 emit_insn (gen_set_got (operands[2]));
12572 if (TARGET_GNU2_TLS)
12574 emit_insn (gen_tls_dynamic_gnu2_32
12575 (operands[0], operands[1], operands[2]));
12578 operands[3] = ix86_tls_get_addr ();
12581 (define_insn "*tls_global_dynamic_64"
12582 [(set (match_operand:DI 0 "register_operand" "=a")
12583 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12584 (match_operand:DI 3 "" "")))
12585 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12588 { 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"; }
12589 [(set_attr "type" "multi")
12590 (set_attr "length" "16")])
12592 (define_expand "tls_global_dynamic_64"
12593 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12594 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12595 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12599 if (TARGET_GNU2_TLS)
12601 emit_insn (gen_tls_dynamic_gnu2_64
12602 (operands[0], operands[1]));
12605 operands[2] = ix86_tls_get_addr ();
12608 (define_insn "*tls_local_dynamic_base_32_gnu"
12609 [(set (match_operand:SI 0 "register_operand" "=a")
12610 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12611 (match_operand:SI 2 "call_insn_operand" "")]
12612 UNSPEC_TLS_LD_BASE))
12613 (clobber (match_scratch:SI 3 "=d"))
12614 (clobber (match_scratch:SI 4 "=c"))
12615 (clobber (reg:CC FLAGS_REG))]
12616 "!TARGET_64BIT && TARGET_GNU_TLS"
12617 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12618 [(set_attr "type" "multi")
12619 (set_attr "length" "11")])
12621 (define_expand "tls_local_dynamic_base_32"
12622 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12623 (unspec:SI [(match_dup 1) (match_dup 2)]
12624 UNSPEC_TLS_LD_BASE))
12625 (clobber (match_scratch:SI 3 ""))
12626 (clobber (match_scratch:SI 4 ""))
12627 (clobber (reg:CC FLAGS_REG))])]
12631 operands[1] = pic_offset_table_rtx;
12634 operands[1] = gen_reg_rtx (Pmode);
12635 emit_insn (gen_set_got (operands[1]));
12637 if (TARGET_GNU2_TLS)
12639 emit_insn (gen_tls_dynamic_gnu2_32
12640 (operands[0], ix86_tls_module_base (), operands[1]));
12643 operands[2] = ix86_tls_get_addr ();
12646 (define_insn "*tls_local_dynamic_base_64"
12647 [(set (match_operand:DI 0 "register_operand" "=a")
12648 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12649 (match_operand:DI 2 "" "")))
12650 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12652 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12653 [(set_attr "type" "multi")
12654 (set_attr "length" "12")])
12656 (define_expand "tls_local_dynamic_base_64"
12657 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12658 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12659 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12662 if (TARGET_GNU2_TLS)
12664 emit_insn (gen_tls_dynamic_gnu2_64
12665 (operands[0], ix86_tls_module_base ()));
12668 operands[1] = ix86_tls_get_addr ();
12671 ;; Local dynamic of a single variable is a lose. Show combine how
12672 ;; to convert that back to global dynamic.
12674 (define_insn_and_split "*tls_local_dynamic_32_once"
12675 [(set (match_operand:SI 0 "register_operand" "=a")
12676 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12677 (match_operand:SI 2 "call_insn_operand" "")]
12678 UNSPEC_TLS_LD_BASE)
12679 (const:SI (unspec:SI
12680 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12682 (clobber (match_scratch:SI 4 "=d"))
12683 (clobber (match_scratch:SI 5 "=c"))
12684 (clobber (reg:CC FLAGS_REG))]
12688 [(parallel [(set (match_dup 0)
12689 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12691 (clobber (match_dup 4))
12692 (clobber (match_dup 5))
12693 (clobber (reg:CC FLAGS_REG))])])
12695 ;; Segment register for the thread base ptr load
12696 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12698 ;; Load and add the thread base pointer from %gs:0.
12699 (define_insn "*load_tp_<mode>"
12700 [(set (match_operand:P 0 "register_operand" "=r")
12701 (unspec:P [(const_int 0)] UNSPEC_TP))]
12703 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12704 [(set_attr "type" "imov")
12705 (set_attr "modrm" "0")
12706 (set_attr "length" "7")
12707 (set_attr "memory" "load")
12708 (set_attr "imm_disp" "false")])
12710 (define_insn "*add_tp_<mode>"
12711 [(set (match_operand:P 0 "register_operand" "=r")
12712 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12713 (match_operand:P 1 "register_operand" "0")))
12714 (clobber (reg:CC FLAGS_REG))]
12716 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12717 [(set_attr "type" "alu")
12718 (set_attr "modrm" "0")
12719 (set_attr "length" "7")
12720 (set_attr "memory" "load")
12721 (set_attr "imm_disp" "false")])
12723 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12724 ;; %rax as destination of the initial executable code sequence.
12725 (define_insn "tls_initial_exec_64_sun"
12726 [(set (match_operand:DI 0 "register_operand" "=a")
12728 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12729 UNSPEC_TLS_IE_SUN))
12730 (clobber (reg:CC FLAGS_REG))]
12731 "TARGET_64BIT && TARGET_SUN_TLS"
12732 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12733 [(set_attr "type" "multi")])
12735 ;; GNU2 TLS patterns can be split.
12737 (define_expand "tls_dynamic_gnu2_32"
12738 [(set (match_dup 3)
12739 (plus:SI (match_operand:SI 2 "register_operand" "")
12741 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12744 [(set (match_operand:SI 0 "register_operand" "")
12745 (unspec:SI [(match_dup 1) (match_dup 3)
12746 (match_dup 2) (reg:SI SP_REG)]
12748 (clobber (reg:CC FLAGS_REG))])]
12749 "!TARGET_64BIT && TARGET_GNU2_TLS"
12751 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12752 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12755 (define_insn "*tls_dynamic_lea_32"
12756 [(set (match_operand:SI 0 "register_operand" "=r")
12757 (plus:SI (match_operand:SI 1 "register_operand" "b")
12759 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12760 UNSPEC_TLSDESC))))]
12761 "!TARGET_64BIT && TARGET_GNU2_TLS"
12762 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12763 [(set_attr "type" "lea")
12764 (set_attr "mode" "SI")
12765 (set_attr "length" "6")
12766 (set_attr "length_address" "4")])
12768 (define_insn "*tls_dynamic_call_32"
12769 [(set (match_operand:SI 0 "register_operand" "=a")
12770 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12771 (match_operand:SI 2 "register_operand" "0")
12772 ;; we have to make sure %ebx still points to the GOT
12773 (match_operand:SI 3 "register_operand" "b")
12776 (clobber (reg:CC FLAGS_REG))]
12777 "!TARGET_64BIT && TARGET_GNU2_TLS"
12778 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12779 [(set_attr "type" "call")
12780 (set_attr "length" "2")
12781 (set_attr "length_address" "0")])
12783 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12784 [(set (match_operand:SI 0 "register_operand" "=&a")
12786 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12787 (match_operand:SI 4 "" "")
12788 (match_operand:SI 2 "register_operand" "b")
12791 (const:SI (unspec:SI
12792 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12794 (clobber (reg:CC FLAGS_REG))]
12795 "!TARGET_64BIT && TARGET_GNU2_TLS"
12798 [(set (match_dup 0) (match_dup 5))]
12800 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12801 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12804 (define_expand "tls_dynamic_gnu2_64"
12805 [(set (match_dup 2)
12806 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12809 [(set (match_operand:DI 0 "register_operand" "")
12810 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12812 (clobber (reg:CC FLAGS_REG))])]
12813 "TARGET_64BIT && TARGET_GNU2_TLS"
12815 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12816 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12819 (define_insn "*tls_dynamic_lea_64"
12820 [(set (match_operand:DI 0 "register_operand" "=r")
12821 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12823 "TARGET_64BIT && TARGET_GNU2_TLS"
12824 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12825 [(set_attr "type" "lea")
12826 (set_attr "mode" "DI")
12827 (set_attr "length" "7")
12828 (set_attr "length_address" "4")])
12830 (define_insn "*tls_dynamic_call_64"
12831 [(set (match_operand:DI 0 "register_operand" "=a")
12832 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12833 (match_operand:DI 2 "register_operand" "0")
12836 (clobber (reg:CC FLAGS_REG))]
12837 "TARGET_64BIT && TARGET_GNU2_TLS"
12838 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12839 [(set_attr "type" "call")
12840 (set_attr "length" "2")
12841 (set_attr "length_address" "0")])
12843 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12844 [(set (match_operand:DI 0 "register_operand" "=&a")
12846 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12847 (match_operand:DI 3 "" "")
12850 (const:DI (unspec:DI
12851 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12853 (clobber (reg:CC FLAGS_REG))]
12854 "TARGET_64BIT && TARGET_GNU2_TLS"
12857 [(set (match_dup 0) (match_dup 4))]
12859 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12860 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12863 ;; These patterns match the binary 387 instructions for addM3, subM3,
12864 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12865 ;; SFmode. The first is the normal insn, the second the same insn but
12866 ;; with one operand a conversion, and the third the same insn but with
12867 ;; the other operand a conversion. The conversion may be SFmode or
12868 ;; SImode if the target mode DFmode, but only SImode if the target mode
12871 ;; Gcc is slightly more smart about handling normal two address instructions
12872 ;; so use special patterns for add and mull.
12874 (define_insn "*fop_<mode>_comm_mixed"
12875 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12876 (match_operator:MODEF 3 "binary_fp_operator"
12877 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12878 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12879 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12880 && COMMUTATIVE_ARITH_P (operands[3])
12881 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12882 "* return output_387_binary_op (insn, operands);"
12883 [(set (attr "type")
12884 (if_then_else (eq_attr "alternative" "1,2")
12885 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12886 (const_string "ssemul")
12887 (const_string "sseadd"))
12888 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12889 (const_string "fmul")
12890 (const_string "fop"))))
12891 (set_attr "isa" "base,noavx,avx")
12892 (set_attr "prefix" "orig,orig,vex")
12893 (set_attr "mode" "<MODE>")])
12895 (define_insn "*fop_<mode>_comm_sse"
12896 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12897 (match_operator:MODEF 3 "binary_fp_operator"
12898 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12899 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12900 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12901 && COMMUTATIVE_ARITH_P (operands[3])
12902 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12903 "* return output_387_binary_op (insn, operands);"
12904 [(set (attr "type")
12905 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12906 (const_string "ssemul")
12907 (const_string "sseadd")))
12908 (set_attr "isa" "noavx,avx")
12909 (set_attr "prefix" "orig,vex")
12910 (set_attr "mode" "<MODE>")])
12912 (define_insn "*fop_<mode>_comm_i387"
12913 [(set (match_operand:MODEF 0 "register_operand" "=f")
12914 (match_operator:MODEF 3 "binary_fp_operator"
12915 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12916 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12917 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12918 && COMMUTATIVE_ARITH_P (operands[3])
12919 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12920 "* return output_387_binary_op (insn, operands);"
12921 [(set (attr "type")
12922 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12923 (const_string "fmul")
12924 (const_string "fop")))
12925 (set_attr "mode" "<MODE>")])
12927 (define_insn "*fop_<mode>_1_mixed"
12928 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12929 (match_operator:MODEF 3 "binary_fp_operator"
12930 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12931 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12932 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12933 && !COMMUTATIVE_ARITH_P (operands[3])
12934 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12935 "* return output_387_binary_op (insn, operands);"
12936 [(set (attr "type")
12937 (cond [(and (eq_attr "alternative" "2,3")
12938 (match_operand:MODEF 3 "mult_operator" ""))
12939 (const_string "ssemul")
12940 (and (eq_attr "alternative" "2,3")
12941 (match_operand:MODEF 3 "div_operator" ""))
12942 (const_string "ssediv")
12943 (eq_attr "alternative" "2,3")
12944 (const_string "sseadd")
12945 (match_operand:MODEF 3 "mult_operator" "")
12946 (const_string "fmul")
12947 (match_operand:MODEF 3 "div_operator" "")
12948 (const_string "fdiv")
12950 (const_string "fop")))
12951 (set_attr "isa" "base,base,noavx,avx")
12952 (set_attr "prefix" "orig,orig,orig,vex")
12953 (set_attr "mode" "<MODE>")])
12955 (define_insn "*rcpsf2_sse"
12956 [(set (match_operand:SF 0 "register_operand" "=x")
12957 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12960 "%vrcpss\t{%1, %d0|%d0, %1}"
12961 [(set_attr "type" "sse")
12962 (set_attr "atom_sse_attr" "rcp")
12963 (set_attr "prefix" "maybe_vex")
12964 (set_attr "mode" "SF")])
12966 (define_insn "*fop_<mode>_1_sse"
12967 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12968 (match_operator:MODEF 3 "binary_fp_operator"
12969 [(match_operand:MODEF 1 "register_operand" "0,x")
12970 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12971 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12972 && !COMMUTATIVE_ARITH_P (operands[3])"
12973 "* return output_387_binary_op (insn, operands);"
12974 [(set (attr "type")
12975 (cond [(match_operand:MODEF 3 "mult_operator" "")
12976 (const_string "ssemul")
12977 (match_operand:MODEF 3 "div_operator" "")
12978 (const_string "ssediv")
12980 (const_string "sseadd")))
12981 (set_attr "isa" "noavx,avx")
12982 (set_attr "prefix" "orig,vex")
12983 (set_attr "mode" "<MODE>")])
12985 ;; This pattern is not fully shadowed by the pattern above.
12986 (define_insn "*fop_<mode>_1_i387"
12987 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12988 (match_operator:MODEF 3 "binary_fp_operator"
12989 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12990 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12991 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12992 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12993 && !COMMUTATIVE_ARITH_P (operands[3])
12994 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12995 "* return output_387_binary_op (insn, operands);"
12996 [(set (attr "type")
12997 (cond [(match_operand:MODEF 3 "mult_operator" "")
12998 (const_string "fmul")
12999 (match_operand:MODEF 3 "div_operator" "")
13000 (const_string "fdiv")
13002 (const_string "fop")))
13003 (set_attr "mode" "<MODE>")])
13005 ;; ??? Add SSE splitters for these!
13006 (define_insn "*fop_<MODEF:mode>_2_i387"
13007 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13008 (match_operator:MODEF 3 "binary_fp_operator"
13010 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13011 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13012 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13013 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13014 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13015 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13016 [(set (attr "type")
13017 (cond [(match_operand:MODEF 3 "mult_operator" "")
13018 (const_string "fmul")
13019 (match_operand:MODEF 3 "div_operator" "")
13020 (const_string "fdiv")
13022 (const_string "fop")))
13023 (set_attr "fp_int_src" "true")
13024 (set_attr "mode" "<X87MODEI12:MODE>")])
13026 (define_insn "*fop_<MODEF:mode>_3_i387"
13027 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13028 (match_operator:MODEF 3 "binary_fp_operator"
13029 [(match_operand:MODEF 1 "register_operand" "0,0")
13031 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13032 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13033 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13034 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13035 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13036 [(set (attr "type")
13037 (cond [(match_operand:MODEF 3 "mult_operator" "")
13038 (const_string "fmul")
13039 (match_operand:MODEF 3 "div_operator" "")
13040 (const_string "fdiv")
13042 (const_string "fop")))
13043 (set_attr "fp_int_src" "true")
13044 (set_attr "mode" "<MODE>")])
13046 (define_insn "*fop_df_4_i387"
13047 [(set (match_operand:DF 0 "register_operand" "=f,f")
13048 (match_operator:DF 3 "binary_fp_operator"
13050 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13051 (match_operand:DF 2 "register_operand" "0,f")]))]
13052 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13053 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13054 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13055 "* return output_387_binary_op (insn, operands);"
13056 [(set (attr "type")
13057 (cond [(match_operand:DF 3 "mult_operator" "")
13058 (const_string "fmul")
13059 (match_operand:DF 3 "div_operator" "")
13060 (const_string "fdiv")
13062 (const_string "fop")))
13063 (set_attr "mode" "SF")])
13065 (define_insn "*fop_df_5_i387"
13066 [(set (match_operand:DF 0 "register_operand" "=f,f")
13067 (match_operator:DF 3 "binary_fp_operator"
13068 [(match_operand:DF 1 "register_operand" "0,f")
13070 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13071 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13072 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13073 "* return output_387_binary_op (insn, operands);"
13074 [(set (attr "type")
13075 (cond [(match_operand:DF 3 "mult_operator" "")
13076 (const_string "fmul")
13077 (match_operand:DF 3 "div_operator" "")
13078 (const_string "fdiv")
13080 (const_string "fop")))
13081 (set_attr "mode" "SF")])
13083 (define_insn "*fop_df_6_i387"
13084 [(set (match_operand:DF 0 "register_operand" "=f,f")
13085 (match_operator:DF 3 "binary_fp_operator"
13087 (match_operand:SF 1 "register_operand" "0,f"))
13089 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13090 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13091 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13092 "* return output_387_binary_op (insn, operands);"
13093 [(set (attr "type")
13094 (cond [(match_operand:DF 3 "mult_operator" "")
13095 (const_string "fmul")
13096 (match_operand:DF 3 "div_operator" "")
13097 (const_string "fdiv")
13099 (const_string "fop")))
13100 (set_attr "mode" "SF")])
13102 (define_insn "*fop_xf_comm_i387"
13103 [(set (match_operand:XF 0 "register_operand" "=f")
13104 (match_operator:XF 3 "binary_fp_operator"
13105 [(match_operand:XF 1 "register_operand" "%0")
13106 (match_operand:XF 2 "register_operand" "f")]))]
13108 && COMMUTATIVE_ARITH_P (operands[3])"
13109 "* return output_387_binary_op (insn, operands);"
13110 [(set (attr "type")
13111 (if_then_else (match_operand:XF 3 "mult_operator" "")
13112 (const_string "fmul")
13113 (const_string "fop")))
13114 (set_attr "mode" "XF")])
13116 (define_insn "*fop_xf_1_i387"
13117 [(set (match_operand:XF 0 "register_operand" "=f,f")
13118 (match_operator:XF 3 "binary_fp_operator"
13119 [(match_operand:XF 1 "register_operand" "0,f")
13120 (match_operand:XF 2 "register_operand" "f,0")]))]
13122 && !COMMUTATIVE_ARITH_P (operands[3])"
13123 "* return output_387_binary_op (insn, operands);"
13124 [(set (attr "type")
13125 (cond [(match_operand:XF 3 "mult_operator" "")
13126 (const_string "fmul")
13127 (match_operand:XF 3 "div_operator" "")
13128 (const_string "fdiv")
13130 (const_string "fop")))
13131 (set_attr "mode" "XF")])
13133 (define_insn "*fop_xf_2_i387"
13134 [(set (match_operand:XF 0 "register_operand" "=f,f")
13135 (match_operator:XF 3 "binary_fp_operator"
13137 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13138 (match_operand:XF 2 "register_operand" "0,0")]))]
13139 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13140 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13141 [(set (attr "type")
13142 (cond [(match_operand:XF 3 "mult_operator" "")
13143 (const_string "fmul")
13144 (match_operand:XF 3 "div_operator" "")
13145 (const_string "fdiv")
13147 (const_string "fop")))
13148 (set_attr "fp_int_src" "true")
13149 (set_attr "mode" "<MODE>")])
13151 (define_insn "*fop_xf_3_i387"
13152 [(set (match_operand:XF 0 "register_operand" "=f,f")
13153 (match_operator:XF 3 "binary_fp_operator"
13154 [(match_operand:XF 1 "register_operand" "0,0")
13156 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13157 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13158 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13159 [(set (attr "type")
13160 (cond [(match_operand:XF 3 "mult_operator" "")
13161 (const_string "fmul")
13162 (match_operand:XF 3 "div_operator" "")
13163 (const_string "fdiv")
13165 (const_string "fop")))
13166 (set_attr "fp_int_src" "true")
13167 (set_attr "mode" "<MODE>")])
13169 (define_insn "*fop_xf_4_i387"
13170 [(set (match_operand:XF 0 "register_operand" "=f,f")
13171 (match_operator:XF 3 "binary_fp_operator"
13173 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13174 (match_operand:XF 2 "register_operand" "0,f")]))]
13176 "* return output_387_binary_op (insn, operands);"
13177 [(set (attr "type")
13178 (cond [(match_operand:XF 3 "mult_operator" "")
13179 (const_string "fmul")
13180 (match_operand:XF 3 "div_operator" "")
13181 (const_string "fdiv")
13183 (const_string "fop")))
13184 (set_attr "mode" "<MODE>")])
13186 (define_insn "*fop_xf_5_i387"
13187 [(set (match_operand:XF 0 "register_operand" "=f,f")
13188 (match_operator:XF 3 "binary_fp_operator"
13189 [(match_operand:XF 1 "register_operand" "0,f")
13191 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13193 "* return output_387_binary_op (insn, operands);"
13194 [(set (attr "type")
13195 (cond [(match_operand:XF 3 "mult_operator" "")
13196 (const_string "fmul")
13197 (match_operand:XF 3 "div_operator" "")
13198 (const_string "fdiv")
13200 (const_string "fop")))
13201 (set_attr "mode" "<MODE>")])
13203 (define_insn "*fop_xf_6_i387"
13204 [(set (match_operand:XF 0 "register_operand" "=f,f")
13205 (match_operator:XF 3 "binary_fp_operator"
13207 (match_operand:MODEF 1 "register_operand" "0,f"))
13209 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13211 "* return output_387_binary_op (insn, operands);"
13212 [(set (attr "type")
13213 (cond [(match_operand:XF 3 "mult_operator" "")
13214 (const_string "fmul")
13215 (match_operand:XF 3 "div_operator" "")
13216 (const_string "fdiv")
13218 (const_string "fop")))
13219 (set_attr "mode" "<MODE>")])
13222 [(set (match_operand 0 "register_operand" "")
13223 (match_operator 3 "binary_fp_operator"
13224 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13225 (match_operand 2 "register_operand" "")]))]
13227 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13228 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13231 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13232 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13233 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13234 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13235 GET_MODE (operands[3]),
13238 ix86_free_from_memory (GET_MODE (operands[1]));
13243 [(set (match_operand 0 "register_operand" "")
13244 (match_operator 3 "binary_fp_operator"
13245 [(match_operand 1 "register_operand" "")
13246 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13248 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13249 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13252 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13253 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13254 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13255 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13256 GET_MODE (operands[3]),
13259 ix86_free_from_memory (GET_MODE (operands[2]));
13263 ;; FPU special functions.
13265 ;; This pattern implements a no-op XFmode truncation for
13266 ;; all fancy i386 XFmode math functions.
13268 (define_insn "truncxf<mode>2_i387_noop_unspec"
13269 [(set (match_operand:MODEF 0 "register_operand" "=f")
13270 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13271 UNSPEC_TRUNC_NOOP))]
13272 "TARGET_USE_FANCY_MATH_387"
13273 "* return output_387_reg_move (insn, operands);"
13274 [(set_attr "type" "fmov")
13275 (set_attr "mode" "<MODE>")])
13277 (define_insn "sqrtxf2"
13278 [(set (match_operand:XF 0 "register_operand" "=f")
13279 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13280 "TARGET_USE_FANCY_MATH_387"
13282 [(set_attr "type" "fpspc")
13283 (set_attr "mode" "XF")
13284 (set_attr "athlon_decode" "direct")
13285 (set_attr "amdfam10_decode" "direct")
13286 (set_attr "bdver1_decode" "direct")])
13288 (define_insn "sqrt_extend<mode>xf2_i387"
13289 [(set (match_operand:XF 0 "register_operand" "=f")
13292 (match_operand:MODEF 1 "register_operand" "0"))))]
13293 "TARGET_USE_FANCY_MATH_387"
13295 [(set_attr "type" "fpspc")
13296 (set_attr "mode" "XF")
13297 (set_attr "athlon_decode" "direct")
13298 (set_attr "amdfam10_decode" "direct")
13299 (set_attr "bdver1_decode" "direct")])
13301 (define_insn "*rsqrtsf2_sse"
13302 [(set (match_operand:SF 0 "register_operand" "=x")
13303 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13306 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13307 [(set_attr "type" "sse")
13308 (set_attr "atom_sse_attr" "rcp")
13309 (set_attr "prefix" "maybe_vex")
13310 (set_attr "mode" "SF")])
13312 (define_expand "rsqrtsf2"
13313 [(set (match_operand:SF 0 "register_operand" "")
13314 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13318 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13322 (define_insn "*sqrt<mode>2_sse"
13323 [(set (match_operand:MODEF 0 "register_operand" "=x")
13325 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13326 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13327 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13328 [(set_attr "type" "sse")
13329 (set_attr "atom_sse_attr" "sqrt")
13330 (set_attr "prefix" "maybe_vex")
13331 (set_attr "mode" "<MODE>")
13332 (set_attr "athlon_decode" "*")
13333 (set_attr "amdfam10_decode" "*")
13334 (set_attr "bdver1_decode" "*")])
13336 (define_expand "sqrt<mode>2"
13337 [(set (match_operand:MODEF 0 "register_operand" "")
13339 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13340 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13341 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13343 if (<MODE>mode == SFmode
13344 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13345 && flag_finite_math_only && !flag_trapping_math
13346 && flag_unsafe_math_optimizations)
13348 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13352 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13354 rtx op0 = gen_reg_rtx (XFmode);
13355 rtx op1 = force_reg (<MODE>mode, operands[1]);
13357 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13358 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13363 (define_insn "fpremxf4_i387"
13364 [(set (match_operand:XF 0 "register_operand" "=f")
13365 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13366 (match_operand:XF 3 "register_operand" "1")]
13368 (set (match_operand:XF 1 "register_operand" "=u")
13369 (unspec:XF [(match_dup 2) (match_dup 3)]
13371 (set (reg:CCFP FPSR_REG)
13372 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13374 "TARGET_USE_FANCY_MATH_387"
13376 [(set_attr "type" "fpspc")
13377 (set_attr "mode" "XF")])
13379 (define_expand "fmodxf3"
13380 [(use (match_operand:XF 0 "register_operand" ""))
13381 (use (match_operand:XF 1 "general_operand" ""))
13382 (use (match_operand:XF 2 "general_operand" ""))]
13383 "TARGET_USE_FANCY_MATH_387"
13385 rtx label = gen_label_rtx ();
13387 rtx op1 = gen_reg_rtx (XFmode);
13388 rtx op2 = gen_reg_rtx (XFmode);
13390 emit_move_insn (op2, operands[2]);
13391 emit_move_insn (op1, operands[1]);
13393 emit_label (label);
13394 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13395 ix86_emit_fp_unordered_jump (label);
13396 LABEL_NUSES (label) = 1;
13398 emit_move_insn (operands[0], op1);
13402 (define_expand "fmod<mode>3"
13403 [(use (match_operand:MODEF 0 "register_operand" ""))
13404 (use (match_operand:MODEF 1 "general_operand" ""))
13405 (use (match_operand:MODEF 2 "general_operand" ""))]
13406 "TARGET_USE_FANCY_MATH_387"
13408 rtx (*gen_truncxf) (rtx, rtx);
13410 rtx label = gen_label_rtx ();
13412 rtx op1 = gen_reg_rtx (XFmode);
13413 rtx op2 = gen_reg_rtx (XFmode);
13415 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13416 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13418 emit_label (label);
13419 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13420 ix86_emit_fp_unordered_jump (label);
13421 LABEL_NUSES (label) = 1;
13423 /* Truncate the result properly for strict SSE math. */
13424 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13425 && !TARGET_MIX_SSE_I387)
13426 gen_truncxf = gen_truncxf<mode>2;
13428 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13430 emit_insn (gen_truncxf (operands[0], op1));
13434 (define_insn "fprem1xf4_i387"
13435 [(set (match_operand:XF 0 "register_operand" "=f")
13436 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13437 (match_operand:XF 3 "register_operand" "1")]
13439 (set (match_operand:XF 1 "register_operand" "=u")
13440 (unspec:XF [(match_dup 2) (match_dup 3)]
13442 (set (reg:CCFP FPSR_REG)
13443 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13445 "TARGET_USE_FANCY_MATH_387"
13447 [(set_attr "type" "fpspc")
13448 (set_attr "mode" "XF")])
13450 (define_expand "remainderxf3"
13451 [(use (match_operand:XF 0 "register_operand" ""))
13452 (use (match_operand:XF 1 "general_operand" ""))
13453 (use (match_operand:XF 2 "general_operand" ""))]
13454 "TARGET_USE_FANCY_MATH_387"
13456 rtx label = gen_label_rtx ();
13458 rtx op1 = gen_reg_rtx (XFmode);
13459 rtx op2 = gen_reg_rtx (XFmode);
13461 emit_move_insn (op2, operands[2]);
13462 emit_move_insn (op1, operands[1]);
13464 emit_label (label);
13465 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13466 ix86_emit_fp_unordered_jump (label);
13467 LABEL_NUSES (label) = 1;
13469 emit_move_insn (operands[0], op1);
13473 (define_expand "remainder<mode>3"
13474 [(use (match_operand:MODEF 0 "register_operand" ""))
13475 (use (match_operand:MODEF 1 "general_operand" ""))
13476 (use (match_operand:MODEF 2 "general_operand" ""))]
13477 "TARGET_USE_FANCY_MATH_387"
13479 rtx (*gen_truncxf) (rtx, rtx);
13481 rtx label = gen_label_rtx ();
13483 rtx op1 = gen_reg_rtx (XFmode);
13484 rtx op2 = gen_reg_rtx (XFmode);
13486 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13487 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13489 emit_label (label);
13491 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13492 ix86_emit_fp_unordered_jump (label);
13493 LABEL_NUSES (label) = 1;
13495 /* Truncate the result properly for strict SSE math. */
13496 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13497 && !TARGET_MIX_SSE_I387)
13498 gen_truncxf = gen_truncxf<mode>2;
13500 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13502 emit_insn (gen_truncxf (operands[0], op1));
13506 (define_insn "*sinxf2_i387"
13507 [(set (match_operand:XF 0 "register_operand" "=f")
13508 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13509 "TARGET_USE_FANCY_MATH_387
13510 && flag_unsafe_math_optimizations"
13512 [(set_attr "type" "fpspc")
13513 (set_attr "mode" "XF")])
13515 (define_insn "*sin_extend<mode>xf2_i387"
13516 [(set (match_operand:XF 0 "register_operand" "=f")
13517 (unspec:XF [(float_extend:XF
13518 (match_operand:MODEF 1 "register_operand" "0"))]
13520 "TARGET_USE_FANCY_MATH_387
13521 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13522 || TARGET_MIX_SSE_I387)
13523 && flag_unsafe_math_optimizations"
13525 [(set_attr "type" "fpspc")
13526 (set_attr "mode" "XF")])
13528 (define_insn "*cosxf2_i387"
13529 [(set (match_operand:XF 0 "register_operand" "=f")
13530 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13531 "TARGET_USE_FANCY_MATH_387
13532 && flag_unsafe_math_optimizations"
13534 [(set_attr "type" "fpspc")
13535 (set_attr "mode" "XF")])
13537 (define_insn "*cos_extend<mode>xf2_i387"
13538 [(set (match_operand:XF 0 "register_operand" "=f")
13539 (unspec:XF [(float_extend:XF
13540 (match_operand:MODEF 1 "register_operand" "0"))]
13542 "TARGET_USE_FANCY_MATH_387
13543 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13544 || TARGET_MIX_SSE_I387)
13545 && flag_unsafe_math_optimizations"
13547 [(set_attr "type" "fpspc")
13548 (set_attr "mode" "XF")])
13550 ;; When sincos pattern is defined, sin and cos builtin functions will be
13551 ;; expanded to sincos pattern with one of its outputs left unused.
13552 ;; CSE pass will figure out if two sincos patterns can be combined,
13553 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13554 ;; depending on the unused output.
13556 (define_insn "sincosxf3"
13557 [(set (match_operand:XF 0 "register_operand" "=f")
13558 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13559 UNSPEC_SINCOS_COS))
13560 (set (match_operand:XF 1 "register_operand" "=u")
13561 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13562 "TARGET_USE_FANCY_MATH_387
13563 && flag_unsafe_math_optimizations"
13565 [(set_attr "type" "fpspc")
13566 (set_attr "mode" "XF")])
13569 [(set (match_operand:XF 0 "register_operand" "")
13570 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13571 UNSPEC_SINCOS_COS))
13572 (set (match_operand:XF 1 "register_operand" "")
13573 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13574 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13575 && !(reload_completed || reload_in_progress)"
13576 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13579 [(set (match_operand:XF 0 "register_operand" "")
13580 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13581 UNSPEC_SINCOS_COS))
13582 (set (match_operand:XF 1 "register_operand" "")
13583 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13584 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13585 && !(reload_completed || reload_in_progress)"
13586 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13588 (define_insn "sincos_extend<mode>xf3_i387"
13589 [(set (match_operand:XF 0 "register_operand" "=f")
13590 (unspec:XF [(float_extend:XF
13591 (match_operand:MODEF 2 "register_operand" "0"))]
13592 UNSPEC_SINCOS_COS))
13593 (set (match_operand:XF 1 "register_operand" "=u")
13594 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13595 "TARGET_USE_FANCY_MATH_387
13596 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13597 || TARGET_MIX_SSE_I387)
13598 && flag_unsafe_math_optimizations"
13600 [(set_attr "type" "fpspc")
13601 (set_attr "mode" "XF")])
13604 [(set (match_operand:XF 0 "register_operand" "")
13605 (unspec:XF [(float_extend:XF
13606 (match_operand:MODEF 2 "register_operand" ""))]
13607 UNSPEC_SINCOS_COS))
13608 (set (match_operand:XF 1 "register_operand" "")
13609 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13610 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13611 && !(reload_completed || reload_in_progress)"
13612 [(set (match_dup 1)
13613 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13616 [(set (match_operand:XF 0 "register_operand" "")
13617 (unspec:XF [(float_extend:XF
13618 (match_operand:MODEF 2 "register_operand" ""))]
13619 UNSPEC_SINCOS_COS))
13620 (set (match_operand:XF 1 "register_operand" "")
13621 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13622 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13623 && !(reload_completed || reload_in_progress)"
13624 [(set (match_dup 0)
13625 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13627 (define_expand "sincos<mode>3"
13628 [(use (match_operand:MODEF 0 "register_operand" ""))
13629 (use (match_operand:MODEF 1 "register_operand" ""))
13630 (use (match_operand:MODEF 2 "register_operand" ""))]
13631 "TARGET_USE_FANCY_MATH_387
13632 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13633 || TARGET_MIX_SSE_I387)
13634 && flag_unsafe_math_optimizations"
13636 rtx op0 = gen_reg_rtx (XFmode);
13637 rtx op1 = gen_reg_rtx (XFmode);
13639 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13640 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13641 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13645 (define_insn "fptanxf4_i387"
13646 [(set (match_operand:XF 0 "register_operand" "=f")
13647 (match_operand:XF 3 "const_double_operand" "F"))
13648 (set (match_operand:XF 1 "register_operand" "=u")
13649 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13651 "TARGET_USE_FANCY_MATH_387
13652 && flag_unsafe_math_optimizations
13653 && standard_80387_constant_p (operands[3]) == 2"
13655 [(set_attr "type" "fpspc")
13656 (set_attr "mode" "XF")])
13658 (define_insn "fptan_extend<mode>xf4_i387"
13659 [(set (match_operand:MODEF 0 "register_operand" "=f")
13660 (match_operand:MODEF 3 "const_double_operand" "F"))
13661 (set (match_operand:XF 1 "register_operand" "=u")
13662 (unspec:XF [(float_extend:XF
13663 (match_operand:MODEF 2 "register_operand" "0"))]
13665 "TARGET_USE_FANCY_MATH_387
13666 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13667 || TARGET_MIX_SSE_I387)
13668 && flag_unsafe_math_optimizations
13669 && standard_80387_constant_p (operands[3]) == 2"
13671 [(set_attr "type" "fpspc")
13672 (set_attr "mode" "XF")])
13674 (define_expand "tanxf2"
13675 [(use (match_operand:XF 0 "register_operand" ""))
13676 (use (match_operand:XF 1 "register_operand" ""))]
13677 "TARGET_USE_FANCY_MATH_387
13678 && flag_unsafe_math_optimizations"
13680 rtx one = gen_reg_rtx (XFmode);
13681 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13683 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13687 (define_expand "tan<mode>2"
13688 [(use (match_operand:MODEF 0 "register_operand" ""))
13689 (use (match_operand:MODEF 1 "register_operand" ""))]
13690 "TARGET_USE_FANCY_MATH_387
13691 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13692 || TARGET_MIX_SSE_I387)
13693 && flag_unsafe_math_optimizations"
13695 rtx op0 = gen_reg_rtx (XFmode);
13697 rtx one = gen_reg_rtx (<MODE>mode);
13698 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13700 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13701 operands[1], op2));
13702 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13706 (define_insn "*fpatanxf3_i387"
13707 [(set (match_operand:XF 0 "register_operand" "=f")
13708 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13709 (match_operand:XF 2 "register_operand" "u")]
13711 (clobber (match_scratch:XF 3 "=2"))]
13712 "TARGET_USE_FANCY_MATH_387
13713 && flag_unsafe_math_optimizations"
13715 [(set_attr "type" "fpspc")
13716 (set_attr "mode" "XF")])
13718 (define_insn "fpatan_extend<mode>xf3_i387"
13719 [(set (match_operand:XF 0 "register_operand" "=f")
13720 (unspec:XF [(float_extend:XF
13721 (match_operand:MODEF 1 "register_operand" "0"))
13723 (match_operand:MODEF 2 "register_operand" "u"))]
13725 (clobber (match_scratch:XF 3 "=2"))]
13726 "TARGET_USE_FANCY_MATH_387
13727 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13728 || TARGET_MIX_SSE_I387)
13729 && flag_unsafe_math_optimizations"
13731 [(set_attr "type" "fpspc")
13732 (set_attr "mode" "XF")])
13734 (define_expand "atan2xf3"
13735 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13736 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13737 (match_operand:XF 1 "register_operand" "")]
13739 (clobber (match_scratch:XF 3 ""))])]
13740 "TARGET_USE_FANCY_MATH_387
13741 && flag_unsafe_math_optimizations")
13743 (define_expand "atan2<mode>3"
13744 [(use (match_operand:MODEF 0 "register_operand" ""))
13745 (use (match_operand:MODEF 1 "register_operand" ""))
13746 (use (match_operand:MODEF 2 "register_operand" ""))]
13747 "TARGET_USE_FANCY_MATH_387
13748 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13749 || TARGET_MIX_SSE_I387)
13750 && flag_unsafe_math_optimizations"
13752 rtx op0 = gen_reg_rtx (XFmode);
13754 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13755 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13759 (define_expand "atanxf2"
13760 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13761 (unspec:XF [(match_dup 2)
13762 (match_operand:XF 1 "register_operand" "")]
13764 (clobber (match_scratch:XF 3 ""))])]
13765 "TARGET_USE_FANCY_MATH_387
13766 && flag_unsafe_math_optimizations"
13768 operands[2] = gen_reg_rtx (XFmode);
13769 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13772 (define_expand "atan<mode>2"
13773 [(use (match_operand:MODEF 0 "register_operand" ""))
13774 (use (match_operand:MODEF 1 "register_operand" ""))]
13775 "TARGET_USE_FANCY_MATH_387
13776 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13777 || TARGET_MIX_SSE_I387)
13778 && flag_unsafe_math_optimizations"
13780 rtx op0 = gen_reg_rtx (XFmode);
13782 rtx op2 = gen_reg_rtx (<MODE>mode);
13783 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13785 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13786 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13790 (define_expand "asinxf2"
13791 [(set (match_dup 2)
13792 (mult:XF (match_operand:XF 1 "register_operand" "")
13794 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13795 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13796 (parallel [(set (match_operand:XF 0 "register_operand" "")
13797 (unspec:XF [(match_dup 5) (match_dup 1)]
13799 (clobber (match_scratch:XF 6 ""))])]
13800 "TARGET_USE_FANCY_MATH_387
13801 && flag_unsafe_math_optimizations"
13805 if (optimize_insn_for_size_p ())
13808 for (i = 2; i < 6; i++)
13809 operands[i] = gen_reg_rtx (XFmode);
13811 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13814 (define_expand "asin<mode>2"
13815 [(use (match_operand:MODEF 0 "register_operand" ""))
13816 (use (match_operand:MODEF 1 "general_operand" ""))]
13817 "TARGET_USE_FANCY_MATH_387
13818 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13819 || TARGET_MIX_SSE_I387)
13820 && flag_unsafe_math_optimizations"
13822 rtx op0 = gen_reg_rtx (XFmode);
13823 rtx op1 = gen_reg_rtx (XFmode);
13825 if (optimize_insn_for_size_p ())
13828 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13829 emit_insn (gen_asinxf2 (op0, op1));
13830 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13834 (define_expand "acosxf2"
13835 [(set (match_dup 2)
13836 (mult:XF (match_operand:XF 1 "register_operand" "")
13838 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13839 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13840 (parallel [(set (match_operand:XF 0 "register_operand" "")
13841 (unspec:XF [(match_dup 1) (match_dup 5)]
13843 (clobber (match_scratch:XF 6 ""))])]
13844 "TARGET_USE_FANCY_MATH_387
13845 && flag_unsafe_math_optimizations"
13849 if (optimize_insn_for_size_p ())
13852 for (i = 2; i < 6; i++)
13853 operands[i] = gen_reg_rtx (XFmode);
13855 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13858 (define_expand "acos<mode>2"
13859 [(use (match_operand:MODEF 0 "register_operand" ""))
13860 (use (match_operand:MODEF 1 "general_operand" ""))]
13861 "TARGET_USE_FANCY_MATH_387
13862 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13863 || TARGET_MIX_SSE_I387)
13864 && flag_unsafe_math_optimizations"
13866 rtx op0 = gen_reg_rtx (XFmode);
13867 rtx op1 = gen_reg_rtx (XFmode);
13869 if (optimize_insn_for_size_p ())
13872 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13873 emit_insn (gen_acosxf2 (op0, op1));
13874 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13878 (define_insn "fyl2xxf3_i387"
13879 [(set (match_operand:XF 0 "register_operand" "=f")
13880 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13881 (match_operand:XF 2 "register_operand" "u")]
13883 (clobber (match_scratch:XF 3 "=2"))]
13884 "TARGET_USE_FANCY_MATH_387
13885 && flag_unsafe_math_optimizations"
13887 [(set_attr "type" "fpspc")
13888 (set_attr "mode" "XF")])
13890 (define_insn "fyl2x_extend<mode>xf3_i387"
13891 [(set (match_operand:XF 0 "register_operand" "=f")
13892 (unspec:XF [(float_extend:XF
13893 (match_operand:MODEF 1 "register_operand" "0"))
13894 (match_operand:XF 2 "register_operand" "u")]
13896 (clobber (match_scratch:XF 3 "=2"))]
13897 "TARGET_USE_FANCY_MATH_387
13898 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13899 || TARGET_MIX_SSE_I387)
13900 && flag_unsafe_math_optimizations"
13902 [(set_attr "type" "fpspc")
13903 (set_attr "mode" "XF")])
13905 (define_expand "logxf2"
13906 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13907 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13908 (match_dup 2)] UNSPEC_FYL2X))
13909 (clobber (match_scratch:XF 3 ""))])]
13910 "TARGET_USE_FANCY_MATH_387
13911 && flag_unsafe_math_optimizations"
13913 operands[2] = gen_reg_rtx (XFmode);
13914 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13917 (define_expand "log<mode>2"
13918 [(use (match_operand:MODEF 0 "register_operand" ""))
13919 (use (match_operand:MODEF 1 "register_operand" ""))]
13920 "TARGET_USE_FANCY_MATH_387
13921 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13922 || TARGET_MIX_SSE_I387)
13923 && flag_unsafe_math_optimizations"
13925 rtx op0 = gen_reg_rtx (XFmode);
13927 rtx op2 = gen_reg_rtx (XFmode);
13928 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13930 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13931 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13935 (define_expand "log10xf2"
13936 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13937 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13938 (match_dup 2)] UNSPEC_FYL2X))
13939 (clobber (match_scratch:XF 3 ""))])]
13940 "TARGET_USE_FANCY_MATH_387
13941 && flag_unsafe_math_optimizations"
13943 operands[2] = gen_reg_rtx (XFmode);
13944 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13947 (define_expand "log10<mode>2"
13948 [(use (match_operand:MODEF 0 "register_operand" ""))
13949 (use (match_operand:MODEF 1 "register_operand" ""))]
13950 "TARGET_USE_FANCY_MATH_387
13951 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13952 || TARGET_MIX_SSE_I387)
13953 && flag_unsafe_math_optimizations"
13955 rtx op0 = gen_reg_rtx (XFmode);
13957 rtx op2 = gen_reg_rtx (XFmode);
13958 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13960 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13961 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13965 (define_expand "log2xf2"
13966 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13967 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13968 (match_dup 2)] UNSPEC_FYL2X))
13969 (clobber (match_scratch:XF 3 ""))])]
13970 "TARGET_USE_FANCY_MATH_387
13971 && flag_unsafe_math_optimizations"
13973 operands[2] = gen_reg_rtx (XFmode);
13974 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13977 (define_expand "log2<mode>2"
13978 [(use (match_operand:MODEF 0 "register_operand" ""))
13979 (use (match_operand:MODEF 1 "register_operand" ""))]
13980 "TARGET_USE_FANCY_MATH_387
13981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13982 || TARGET_MIX_SSE_I387)
13983 && flag_unsafe_math_optimizations"
13985 rtx op0 = gen_reg_rtx (XFmode);
13987 rtx op2 = gen_reg_rtx (XFmode);
13988 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13990 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13991 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13995 (define_insn "fyl2xp1xf3_i387"
13996 [(set (match_operand:XF 0 "register_operand" "=f")
13997 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13998 (match_operand:XF 2 "register_operand" "u")]
14000 (clobber (match_scratch:XF 3 "=2"))]
14001 "TARGET_USE_FANCY_MATH_387
14002 && flag_unsafe_math_optimizations"
14004 [(set_attr "type" "fpspc")
14005 (set_attr "mode" "XF")])
14007 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14008 [(set (match_operand:XF 0 "register_operand" "=f")
14009 (unspec:XF [(float_extend:XF
14010 (match_operand:MODEF 1 "register_operand" "0"))
14011 (match_operand:XF 2 "register_operand" "u")]
14013 (clobber (match_scratch:XF 3 "=2"))]
14014 "TARGET_USE_FANCY_MATH_387
14015 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14016 || TARGET_MIX_SSE_I387)
14017 && flag_unsafe_math_optimizations"
14019 [(set_attr "type" "fpspc")
14020 (set_attr "mode" "XF")])
14022 (define_expand "log1pxf2"
14023 [(use (match_operand:XF 0 "register_operand" ""))
14024 (use (match_operand:XF 1 "register_operand" ""))]
14025 "TARGET_USE_FANCY_MATH_387
14026 && flag_unsafe_math_optimizations"
14028 if (optimize_insn_for_size_p ())
14031 ix86_emit_i387_log1p (operands[0], operands[1]);
14035 (define_expand "log1p<mode>2"
14036 [(use (match_operand:MODEF 0 "register_operand" ""))
14037 (use (match_operand:MODEF 1 "register_operand" ""))]
14038 "TARGET_USE_FANCY_MATH_387
14039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14040 || TARGET_MIX_SSE_I387)
14041 && flag_unsafe_math_optimizations"
14045 if (optimize_insn_for_size_p ())
14048 op0 = gen_reg_rtx (XFmode);
14050 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14052 ix86_emit_i387_log1p (op0, operands[1]);
14053 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14057 (define_insn "fxtractxf3_i387"
14058 [(set (match_operand:XF 0 "register_operand" "=f")
14059 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14060 UNSPEC_XTRACT_FRACT))
14061 (set (match_operand:XF 1 "register_operand" "=u")
14062 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14063 "TARGET_USE_FANCY_MATH_387
14064 && flag_unsafe_math_optimizations"
14066 [(set_attr "type" "fpspc")
14067 (set_attr "mode" "XF")])
14069 (define_insn "fxtract_extend<mode>xf3_i387"
14070 [(set (match_operand:XF 0 "register_operand" "=f")
14071 (unspec:XF [(float_extend:XF
14072 (match_operand:MODEF 2 "register_operand" "0"))]
14073 UNSPEC_XTRACT_FRACT))
14074 (set (match_operand:XF 1 "register_operand" "=u")
14075 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14076 "TARGET_USE_FANCY_MATH_387
14077 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14078 || TARGET_MIX_SSE_I387)
14079 && flag_unsafe_math_optimizations"
14081 [(set_attr "type" "fpspc")
14082 (set_attr "mode" "XF")])
14084 (define_expand "logbxf2"
14085 [(parallel [(set (match_dup 2)
14086 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14087 UNSPEC_XTRACT_FRACT))
14088 (set (match_operand:XF 0 "register_operand" "")
14089 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14090 "TARGET_USE_FANCY_MATH_387
14091 && flag_unsafe_math_optimizations"
14092 "operands[2] = gen_reg_rtx (XFmode);")
14094 (define_expand "logb<mode>2"
14095 [(use (match_operand:MODEF 0 "register_operand" ""))
14096 (use (match_operand:MODEF 1 "register_operand" ""))]
14097 "TARGET_USE_FANCY_MATH_387
14098 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14099 || TARGET_MIX_SSE_I387)
14100 && flag_unsafe_math_optimizations"
14102 rtx op0 = gen_reg_rtx (XFmode);
14103 rtx op1 = gen_reg_rtx (XFmode);
14105 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14106 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14110 (define_expand "ilogbxf2"
14111 [(use (match_operand:SI 0 "register_operand" ""))
14112 (use (match_operand:XF 1 "register_operand" ""))]
14113 "TARGET_USE_FANCY_MATH_387
14114 && flag_unsafe_math_optimizations"
14118 if (optimize_insn_for_size_p ())
14121 op0 = gen_reg_rtx (XFmode);
14122 op1 = gen_reg_rtx (XFmode);
14124 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14125 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14129 (define_expand "ilogb<mode>2"
14130 [(use (match_operand:SI 0 "register_operand" ""))
14131 (use (match_operand:MODEF 1 "register_operand" ""))]
14132 "TARGET_USE_FANCY_MATH_387
14133 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14134 || TARGET_MIX_SSE_I387)
14135 && flag_unsafe_math_optimizations"
14139 if (optimize_insn_for_size_p ())
14142 op0 = gen_reg_rtx (XFmode);
14143 op1 = gen_reg_rtx (XFmode);
14145 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14146 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14150 (define_insn "*f2xm1xf2_i387"
14151 [(set (match_operand:XF 0 "register_operand" "=f")
14152 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14154 "TARGET_USE_FANCY_MATH_387
14155 && flag_unsafe_math_optimizations"
14157 [(set_attr "type" "fpspc")
14158 (set_attr "mode" "XF")])
14160 (define_insn "*fscalexf4_i387"
14161 [(set (match_operand:XF 0 "register_operand" "=f")
14162 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14163 (match_operand:XF 3 "register_operand" "1")]
14164 UNSPEC_FSCALE_FRACT))
14165 (set (match_operand:XF 1 "register_operand" "=u")
14166 (unspec:XF [(match_dup 2) (match_dup 3)]
14167 UNSPEC_FSCALE_EXP))]
14168 "TARGET_USE_FANCY_MATH_387
14169 && flag_unsafe_math_optimizations"
14171 [(set_attr "type" "fpspc")
14172 (set_attr "mode" "XF")])
14174 (define_expand "expNcorexf3"
14175 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14176 (match_operand:XF 2 "register_operand" "")))
14177 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14178 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14179 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14180 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14181 (parallel [(set (match_operand:XF 0 "register_operand" "")
14182 (unspec:XF [(match_dup 8) (match_dup 4)]
14183 UNSPEC_FSCALE_FRACT))
14185 (unspec:XF [(match_dup 8) (match_dup 4)]
14186 UNSPEC_FSCALE_EXP))])]
14187 "TARGET_USE_FANCY_MATH_387
14188 && flag_unsafe_math_optimizations"
14192 if (optimize_insn_for_size_p ())
14195 for (i = 3; i < 10; i++)
14196 operands[i] = gen_reg_rtx (XFmode);
14198 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14201 (define_expand "expxf2"
14202 [(use (match_operand:XF 0 "register_operand" ""))
14203 (use (match_operand:XF 1 "register_operand" ""))]
14204 "TARGET_USE_FANCY_MATH_387
14205 && flag_unsafe_math_optimizations"
14209 if (optimize_insn_for_size_p ())
14212 op2 = gen_reg_rtx (XFmode);
14213 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14215 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14219 (define_expand "exp<mode>2"
14220 [(use (match_operand:MODEF 0 "register_operand" ""))
14221 (use (match_operand:MODEF 1 "general_operand" ""))]
14222 "TARGET_USE_FANCY_MATH_387
14223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14224 || TARGET_MIX_SSE_I387)
14225 && flag_unsafe_math_optimizations"
14229 if (optimize_insn_for_size_p ())
14232 op0 = gen_reg_rtx (XFmode);
14233 op1 = gen_reg_rtx (XFmode);
14235 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14236 emit_insn (gen_expxf2 (op0, op1));
14237 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14241 (define_expand "exp10xf2"
14242 [(use (match_operand:XF 0 "register_operand" ""))
14243 (use (match_operand:XF 1 "register_operand" ""))]
14244 "TARGET_USE_FANCY_MATH_387
14245 && flag_unsafe_math_optimizations"
14249 if (optimize_insn_for_size_p ())
14252 op2 = gen_reg_rtx (XFmode);
14253 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14255 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14259 (define_expand "exp10<mode>2"
14260 [(use (match_operand:MODEF 0 "register_operand" ""))
14261 (use (match_operand:MODEF 1 "general_operand" ""))]
14262 "TARGET_USE_FANCY_MATH_387
14263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14264 || TARGET_MIX_SSE_I387)
14265 && flag_unsafe_math_optimizations"
14269 if (optimize_insn_for_size_p ())
14272 op0 = gen_reg_rtx (XFmode);
14273 op1 = gen_reg_rtx (XFmode);
14275 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14276 emit_insn (gen_exp10xf2 (op0, op1));
14277 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14281 (define_expand "exp2xf2"
14282 [(use (match_operand:XF 0 "register_operand" ""))
14283 (use (match_operand:XF 1 "register_operand" ""))]
14284 "TARGET_USE_FANCY_MATH_387
14285 && flag_unsafe_math_optimizations"
14289 if (optimize_insn_for_size_p ())
14292 op2 = gen_reg_rtx (XFmode);
14293 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14295 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14299 (define_expand "exp2<mode>2"
14300 [(use (match_operand:MODEF 0 "register_operand" ""))
14301 (use (match_operand:MODEF 1 "general_operand" ""))]
14302 "TARGET_USE_FANCY_MATH_387
14303 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14304 || TARGET_MIX_SSE_I387)
14305 && flag_unsafe_math_optimizations"
14309 if (optimize_insn_for_size_p ())
14312 op0 = gen_reg_rtx (XFmode);
14313 op1 = gen_reg_rtx (XFmode);
14315 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14316 emit_insn (gen_exp2xf2 (op0, op1));
14317 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14321 (define_expand "expm1xf2"
14322 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14324 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14325 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14326 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14327 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14328 (parallel [(set (match_dup 7)
14329 (unspec:XF [(match_dup 6) (match_dup 4)]
14330 UNSPEC_FSCALE_FRACT))
14332 (unspec:XF [(match_dup 6) (match_dup 4)]
14333 UNSPEC_FSCALE_EXP))])
14334 (parallel [(set (match_dup 10)
14335 (unspec:XF [(match_dup 9) (match_dup 8)]
14336 UNSPEC_FSCALE_FRACT))
14337 (set (match_dup 11)
14338 (unspec:XF [(match_dup 9) (match_dup 8)]
14339 UNSPEC_FSCALE_EXP))])
14340 (set (match_dup 12) (minus:XF (match_dup 10)
14341 (float_extend:XF (match_dup 13))))
14342 (set (match_operand:XF 0 "register_operand" "")
14343 (plus:XF (match_dup 12) (match_dup 7)))]
14344 "TARGET_USE_FANCY_MATH_387
14345 && flag_unsafe_math_optimizations"
14349 if (optimize_insn_for_size_p ())
14352 for (i = 2; i < 13; i++)
14353 operands[i] = gen_reg_rtx (XFmode);
14356 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14358 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14361 (define_expand "expm1<mode>2"
14362 [(use (match_operand:MODEF 0 "register_operand" ""))
14363 (use (match_operand:MODEF 1 "general_operand" ""))]
14364 "TARGET_USE_FANCY_MATH_387
14365 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14366 || TARGET_MIX_SSE_I387)
14367 && flag_unsafe_math_optimizations"
14371 if (optimize_insn_for_size_p ())
14374 op0 = gen_reg_rtx (XFmode);
14375 op1 = gen_reg_rtx (XFmode);
14377 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14378 emit_insn (gen_expm1xf2 (op0, op1));
14379 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14383 (define_expand "ldexpxf3"
14384 [(set (match_dup 3)
14385 (float:XF (match_operand:SI 2 "register_operand" "")))
14386 (parallel [(set (match_operand:XF 0 " register_operand" "")
14387 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14389 UNSPEC_FSCALE_FRACT))
14391 (unspec:XF [(match_dup 1) (match_dup 3)]
14392 UNSPEC_FSCALE_EXP))])]
14393 "TARGET_USE_FANCY_MATH_387
14394 && flag_unsafe_math_optimizations"
14396 if (optimize_insn_for_size_p ())
14399 operands[3] = gen_reg_rtx (XFmode);
14400 operands[4] = gen_reg_rtx (XFmode);
14403 (define_expand "ldexp<mode>3"
14404 [(use (match_operand:MODEF 0 "register_operand" ""))
14405 (use (match_operand:MODEF 1 "general_operand" ""))
14406 (use (match_operand:SI 2 "register_operand" ""))]
14407 "TARGET_USE_FANCY_MATH_387
14408 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14409 || TARGET_MIX_SSE_I387)
14410 && flag_unsafe_math_optimizations"
14414 if (optimize_insn_for_size_p ())
14417 op0 = gen_reg_rtx (XFmode);
14418 op1 = gen_reg_rtx (XFmode);
14420 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14421 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14422 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14426 (define_expand "scalbxf3"
14427 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14428 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14429 (match_operand:XF 2 "register_operand" "")]
14430 UNSPEC_FSCALE_FRACT))
14432 (unspec:XF [(match_dup 1) (match_dup 2)]
14433 UNSPEC_FSCALE_EXP))])]
14434 "TARGET_USE_FANCY_MATH_387
14435 && flag_unsafe_math_optimizations"
14437 if (optimize_insn_for_size_p ())
14440 operands[3] = gen_reg_rtx (XFmode);
14443 (define_expand "scalb<mode>3"
14444 [(use (match_operand:MODEF 0 "register_operand" ""))
14445 (use (match_operand:MODEF 1 "general_operand" ""))
14446 (use (match_operand:MODEF 2 "general_operand" ""))]
14447 "TARGET_USE_FANCY_MATH_387
14448 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14449 || TARGET_MIX_SSE_I387)
14450 && flag_unsafe_math_optimizations"
14454 if (optimize_insn_for_size_p ())
14457 op0 = gen_reg_rtx (XFmode);
14458 op1 = gen_reg_rtx (XFmode);
14459 op2 = gen_reg_rtx (XFmode);
14461 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14462 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14463 emit_insn (gen_scalbxf3 (op0, op1, op2));
14464 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14468 (define_expand "significandxf2"
14469 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14470 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14471 UNSPEC_XTRACT_FRACT))
14473 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14474 "TARGET_USE_FANCY_MATH_387
14475 && flag_unsafe_math_optimizations"
14476 "operands[2] = gen_reg_rtx (XFmode);")
14478 (define_expand "significand<mode>2"
14479 [(use (match_operand:MODEF 0 "register_operand" ""))
14480 (use (match_operand:MODEF 1 "register_operand" ""))]
14481 "TARGET_USE_FANCY_MATH_387
14482 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14483 || TARGET_MIX_SSE_I387)
14484 && flag_unsafe_math_optimizations"
14486 rtx op0 = gen_reg_rtx (XFmode);
14487 rtx op1 = gen_reg_rtx (XFmode);
14489 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14490 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14495 (define_insn "sse4_1_round<mode>2"
14496 [(set (match_operand:MODEF 0 "register_operand" "=x")
14497 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14498 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14501 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14502 [(set_attr "type" "ssecvt")
14503 (set_attr "prefix_extra" "1")
14504 (set_attr "prefix" "maybe_vex")
14505 (set_attr "mode" "<MODE>")])
14507 (define_insn "rintxf2"
14508 [(set (match_operand:XF 0 "register_operand" "=f")
14509 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14511 "TARGET_USE_FANCY_MATH_387
14512 && flag_unsafe_math_optimizations"
14514 [(set_attr "type" "fpspc")
14515 (set_attr "mode" "XF")])
14517 (define_expand "rint<mode>2"
14518 [(use (match_operand:MODEF 0 "register_operand" ""))
14519 (use (match_operand:MODEF 1 "register_operand" ""))]
14520 "(TARGET_USE_FANCY_MATH_387
14521 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14522 || TARGET_MIX_SSE_I387)
14523 && flag_unsafe_math_optimizations)
14524 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14525 && !flag_trapping_math)"
14527 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14528 && !flag_trapping_math)
14530 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14533 emit_insn (gen_sse4_1_round<mode>2
14534 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14536 ix86_expand_rint (operand0, operand1);
14540 rtx op0 = gen_reg_rtx (XFmode);
14541 rtx op1 = gen_reg_rtx (XFmode);
14543 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14544 emit_insn (gen_rintxf2 (op0, op1));
14546 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14551 (define_expand "round<mode>2"
14552 [(match_operand:MODEF 0 "register_operand" "")
14553 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14554 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14555 && !flag_trapping_math && !flag_rounding_math"
14557 if (optimize_insn_for_size_p ())
14559 if (TARGET_64BIT || (<MODE>mode != DFmode))
14560 ix86_expand_round (operand0, operand1);
14562 ix86_expand_rounddf_32 (operand0, operand1);
14566 (define_insn_and_split "*fistdi2_1"
14567 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14568 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14570 "TARGET_USE_FANCY_MATH_387
14571 && can_create_pseudo_p ()"
14576 if (memory_operand (operands[0], VOIDmode))
14577 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14580 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14581 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14586 [(set_attr "type" "fpspc")
14587 (set_attr "mode" "DI")])
14589 (define_insn "fistdi2"
14590 [(set (match_operand:DI 0 "memory_operand" "=m")
14591 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14593 (clobber (match_scratch:XF 2 "=&1f"))]
14594 "TARGET_USE_FANCY_MATH_387"
14595 "* return output_fix_trunc (insn, operands, 0);"
14596 [(set_attr "type" "fpspc")
14597 (set_attr "mode" "DI")])
14599 (define_insn "fistdi2_with_temp"
14600 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14601 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14603 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14604 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14605 "TARGET_USE_FANCY_MATH_387"
14607 [(set_attr "type" "fpspc")
14608 (set_attr "mode" "DI")])
14611 [(set (match_operand:DI 0 "register_operand" "")
14612 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14614 (clobber (match_operand:DI 2 "memory_operand" ""))
14615 (clobber (match_scratch 3 ""))]
14617 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14618 (clobber (match_dup 3))])
14619 (set (match_dup 0) (match_dup 2))])
14622 [(set (match_operand:DI 0 "memory_operand" "")
14623 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14625 (clobber (match_operand:DI 2 "memory_operand" ""))
14626 (clobber (match_scratch 3 ""))]
14628 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14629 (clobber (match_dup 3))])])
14631 (define_insn_and_split "*fist<mode>2_1"
14632 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14633 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14635 "TARGET_USE_FANCY_MATH_387
14636 && can_create_pseudo_p ()"
14641 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14642 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14646 [(set_attr "type" "fpspc")
14647 (set_attr "mode" "<MODE>")])
14649 (define_insn "fist<mode>2"
14650 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14651 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14653 "TARGET_USE_FANCY_MATH_387"
14654 "* return output_fix_trunc (insn, operands, 0);"
14655 [(set_attr "type" "fpspc")
14656 (set_attr "mode" "<MODE>")])
14658 (define_insn "fist<mode>2_with_temp"
14659 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14660 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14662 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14663 "TARGET_USE_FANCY_MATH_387"
14665 [(set_attr "type" "fpspc")
14666 (set_attr "mode" "<MODE>")])
14669 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14670 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14672 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14674 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14675 (set (match_dup 0) (match_dup 2))])
14678 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14679 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14681 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14683 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14685 (define_expand "lrintxf<mode>2"
14686 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14687 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14689 "TARGET_USE_FANCY_MATH_387")
14691 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14692 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14693 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14694 UNSPEC_FIX_NOTRUNC))]
14695 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14696 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14698 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14699 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14700 (match_operand:MODEF 1 "register_operand" "")]
14701 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14702 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14703 && !flag_trapping_math && !flag_rounding_math"
14705 if (optimize_insn_for_size_p ())
14707 ix86_expand_lround (operand0, operand1);
14711 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14712 (define_insn_and_split "frndintxf2_floor"
14713 [(set (match_operand:XF 0 "register_operand" "")
14714 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14715 UNSPEC_FRNDINT_FLOOR))
14716 (clobber (reg:CC FLAGS_REG))]
14717 "TARGET_USE_FANCY_MATH_387
14718 && flag_unsafe_math_optimizations
14719 && can_create_pseudo_p ()"
14724 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14726 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14727 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14729 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14730 operands[2], operands[3]));
14733 [(set_attr "type" "frndint")
14734 (set_attr "i387_cw" "floor")
14735 (set_attr "mode" "XF")])
14737 (define_insn "frndintxf2_floor_i387"
14738 [(set (match_operand:XF 0 "register_operand" "=f")
14739 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14740 UNSPEC_FRNDINT_FLOOR))
14741 (use (match_operand:HI 2 "memory_operand" "m"))
14742 (use (match_operand:HI 3 "memory_operand" "m"))]
14743 "TARGET_USE_FANCY_MATH_387
14744 && flag_unsafe_math_optimizations"
14745 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14746 [(set_attr "type" "frndint")
14747 (set_attr "i387_cw" "floor")
14748 (set_attr "mode" "XF")])
14750 (define_expand "floorxf2"
14751 [(use (match_operand:XF 0 "register_operand" ""))
14752 (use (match_operand:XF 1 "register_operand" ""))]
14753 "TARGET_USE_FANCY_MATH_387
14754 && flag_unsafe_math_optimizations"
14756 if (optimize_insn_for_size_p ())
14758 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14762 (define_expand "floor<mode>2"
14763 [(use (match_operand:MODEF 0 "register_operand" ""))
14764 (use (match_operand:MODEF 1 "register_operand" ""))]
14765 "(TARGET_USE_FANCY_MATH_387
14766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14767 || TARGET_MIX_SSE_I387)
14768 && flag_unsafe_math_optimizations)
14769 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14770 && !flag_trapping_math)"
14772 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14773 && !flag_trapping_math
14774 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14776 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14779 emit_insn (gen_sse4_1_round<mode>2
14780 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14781 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14782 ix86_expand_floorceil (operand0, operand1, true);
14784 ix86_expand_floorceildf_32 (operand0, operand1, true);
14790 if (optimize_insn_for_size_p ())
14793 op0 = gen_reg_rtx (XFmode);
14794 op1 = gen_reg_rtx (XFmode);
14795 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14796 emit_insn (gen_frndintxf2_floor (op0, op1));
14798 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14803 (define_insn_and_split "*fist<mode>2_floor_1"
14804 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14805 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14806 UNSPEC_FIST_FLOOR))
14807 (clobber (reg:CC FLAGS_REG))]
14808 "TARGET_USE_FANCY_MATH_387
14809 && flag_unsafe_math_optimizations
14810 && can_create_pseudo_p ()"
14815 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14817 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14818 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14819 if (memory_operand (operands[0], VOIDmode))
14820 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14821 operands[2], operands[3]));
14824 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14825 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14826 operands[2], operands[3],
14831 [(set_attr "type" "fistp")
14832 (set_attr "i387_cw" "floor")
14833 (set_attr "mode" "<MODE>")])
14835 (define_insn "fistdi2_floor"
14836 [(set (match_operand:DI 0 "memory_operand" "=m")
14837 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14838 UNSPEC_FIST_FLOOR))
14839 (use (match_operand:HI 2 "memory_operand" "m"))
14840 (use (match_operand:HI 3 "memory_operand" "m"))
14841 (clobber (match_scratch:XF 4 "=&1f"))]
14842 "TARGET_USE_FANCY_MATH_387
14843 && flag_unsafe_math_optimizations"
14844 "* return output_fix_trunc (insn, operands, 0);"
14845 [(set_attr "type" "fistp")
14846 (set_attr "i387_cw" "floor")
14847 (set_attr "mode" "DI")])
14849 (define_insn "fistdi2_floor_with_temp"
14850 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14851 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14852 UNSPEC_FIST_FLOOR))
14853 (use (match_operand:HI 2 "memory_operand" "m,m"))
14854 (use (match_operand:HI 3 "memory_operand" "m,m"))
14855 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14856 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14857 "TARGET_USE_FANCY_MATH_387
14858 && flag_unsafe_math_optimizations"
14860 [(set_attr "type" "fistp")
14861 (set_attr "i387_cw" "floor")
14862 (set_attr "mode" "DI")])
14865 [(set (match_operand:DI 0 "register_operand" "")
14866 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14867 UNSPEC_FIST_FLOOR))
14868 (use (match_operand:HI 2 "memory_operand" ""))
14869 (use (match_operand:HI 3 "memory_operand" ""))
14870 (clobber (match_operand:DI 4 "memory_operand" ""))
14871 (clobber (match_scratch 5 ""))]
14873 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14874 (use (match_dup 2))
14875 (use (match_dup 3))
14876 (clobber (match_dup 5))])
14877 (set (match_dup 0) (match_dup 4))])
14880 [(set (match_operand:DI 0 "memory_operand" "")
14881 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14882 UNSPEC_FIST_FLOOR))
14883 (use (match_operand:HI 2 "memory_operand" ""))
14884 (use (match_operand:HI 3 "memory_operand" ""))
14885 (clobber (match_operand:DI 4 "memory_operand" ""))
14886 (clobber (match_scratch 5 ""))]
14888 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14889 (use (match_dup 2))
14890 (use (match_dup 3))
14891 (clobber (match_dup 5))])])
14893 (define_insn "fist<mode>2_floor"
14894 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14895 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14896 UNSPEC_FIST_FLOOR))
14897 (use (match_operand:HI 2 "memory_operand" "m"))
14898 (use (match_operand:HI 3 "memory_operand" "m"))]
14899 "TARGET_USE_FANCY_MATH_387
14900 && flag_unsafe_math_optimizations"
14901 "* return output_fix_trunc (insn, operands, 0);"
14902 [(set_attr "type" "fistp")
14903 (set_attr "i387_cw" "floor")
14904 (set_attr "mode" "<MODE>")])
14906 (define_insn "fist<mode>2_floor_with_temp"
14907 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14908 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14909 UNSPEC_FIST_FLOOR))
14910 (use (match_operand:HI 2 "memory_operand" "m,m"))
14911 (use (match_operand:HI 3 "memory_operand" "m,m"))
14912 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14913 "TARGET_USE_FANCY_MATH_387
14914 && flag_unsafe_math_optimizations"
14916 [(set_attr "type" "fistp")
14917 (set_attr "i387_cw" "floor")
14918 (set_attr "mode" "<MODE>")])
14921 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14922 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14923 UNSPEC_FIST_FLOOR))
14924 (use (match_operand:HI 2 "memory_operand" ""))
14925 (use (match_operand:HI 3 "memory_operand" ""))
14926 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14928 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14929 UNSPEC_FIST_FLOOR))
14930 (use (match_dup 2))
14931 (use (match_dup 3))])
14932 (set (match_dup 0) (match_dup 4))])
14935 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14936 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14937 UNSPEC_FIST_FLOOR))
14938 (use (match_operand:HI 2 "memory_operand" ""))
14939 (use (match_operand:HI 3 "memory_operand" ""))
14940 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14942 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14943 UNSPEC_FIST_FLOOR))
14944 (use (match_dup 2))
14945 (use (match_dup 3))])])
14947 (define_expand "lfloorxf<mode>2"
14948 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14949 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14950 UNSPEC_FIST_FLOOR))
14951 (clobber (reg:CC FLAGS_REG))])]
14952 "TARGET_USE_FANCY_MATH_387
14953 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14954 && flag_unsafe_math_optimizations")
14956 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14957 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14958 (match_operand:MODEF 1 "register_operand" "")]
14959 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14960 && !flag_trapping_math"
14962 if (TARGET_64BIT && optimize_insn_for_size_p ())
14964 ix86_expand_lfloorceil (operand0, operand1, true);
14968 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14969 (define_insn_and_split "frndintxf2_ceil"
14970 [(set (match_operand:XF 0 "register_operand" "")
14971 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14972 UNSPEC_FRNDINT_CEIL))
14973 (clobber (reg:CC FLAGS_REG))]
14974 "TARGET_USE_FANCY_MATH_387
14975 && flag_unsafe_math_optimizations
14976 && can_create_pseudo_p ()"
14981 ix86_optimize_mode_switching[I387_CEIL] = 1;
14983 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14984 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14986 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14987 operands[2], operands[3]));
14990 [(set_attr "type" "frndint")
14991 (set_attr "i387_cw" "ceil")
14992 (set_attr "mode" "XF")])
14994 (define_insn "frndintxf2_ceil_i387"
14995 [(set (match_operand:XF 0 "register_operand" "=f")
14996 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14997 UNSPEC_FRNDINT_CEIL))
14998 (use (match_operand:HI 2 "memory_operand" "m"))
14999 (use (match_operand:HI 3 "memory_operand" "m"))]
15000 "TARGET_USE_FANCY_MATH_387
15001 && flag_unsafe_math_optimizations"
15002 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15003 [(set_attr "type" "frndint")
15004 (set_attr "i387_cw" "ceil")
15005 (set_attr "mode" "XF")])
15007 (define_expand "ceilxf2"
15008 [(use (match_operand:XF 0 "register_operand" ""))
15009 (use (match_operand:XF 1 "register_operand" ""))]
15010 "TARGET_USE_FANCY_MATH_387
15011 && flag_unsafe_math_optimizations"
15013 if (optimize_insn_for_size_p ())
15015 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15019 (define_expand "ceil<mode>2"
15020 [(use (match_operand:MODEF 0 "register_operand" ""))
15021 (use (match_operand:MODEF 1 "register_operand" ""))]
15022 "(TARGET_USE_FANCY_MATH_387
15023 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15024 || TARGET_MIX_SSE_I387)
15025 && flag_unsafe_math_optimizations)
15026 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15027 && !flag_trapping_math)"
15029 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15030 && !flag_trapping_math
15031 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15034 emit_insn (gen_sse4_1_round<mode>2
15035 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15036 else if (optimize_insn_for_size_p ())
15038 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15039 ix86_expand_floorceil (operand0, operand1, false);
15041 ix86_expand_floorceildf_32 (operand0, operand1, false);
15047 if (optimize_insn_for_size_p ())
15050 op0 = gen_reg_rtx (XFmode);
15051 op1 = gen_reg_rtx (XFmode);
15052 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15053 emit_insn (gen_frndintxf2_ceil (op0, op1));
15055 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15060 (define_insn_and_split "*fist<mode>2_ceil_1"
15061 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15062 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15064 (clobber (reg:CC FLAGS_REG))]
15065 "TARGET_USE_FANCY_MATH_387
15066 && flag_unsafe_math_optimizations
15067 && can_create_pseudo_p ()"
15072 ix86_optimize_mode_switching[I387_CEIL] = 1;
15074 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15075 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15076 if (memory_operand (operands[0], VOIDmode))
15077 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15078 operands[2], operands[3]));
15081 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15082 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15083 operands[2], operands[3],
15088 [(set_attr "type" "fistp")
15089 (set_attr "i387_cw" "ceil")
15090 (set_attr "mode" "<MODE>")])
15092 (define_insn "fistdi2_ceil"
15093 [(set (match_operand:DI 0 "memory_operand" "=m")
15094 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15096 (use (match_operand:HI 2 "memory_operand" "m"))
15097 (use (match_operand:HI 3 "memory_operand" "m"))
15098 (clobber (match_scratch:XF 4 "=&1f"))]
15099 "TARGET_USE_FANCY_MATH_387
15100 && flag_unsafe_math_optimizations"
15101 "* return output_fix_trunc (insn, operands, 0);"
15102 [(set_attr "type" "fistp")
15103 (set_attr "i387_cw" "ceil")
15104 (set_attr "mode" "DI")])
15106 (define_insn "fistdi2_ceil_with_temp"
15107 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15108 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15110 (use (match_operand:HI 2 "memory_operand" "m,m"))
15111 (use (match_operand:HI 3 "memory_operand" "m,m"))
15112 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15113 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15114 "TARGET_USE_FANCY_MATH_387
15115 && flag_unsafe_math_optimizations"
15117 [(set_attr "type" "fistp")
15118 (set_attr "i387_cw" "ceil")
15119 (set_attr "mode" "DI")])
15122 [(set (match_operand:DI 0 "register_operand" "")
15123 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15125 (use (match_operand:HI 2 "memory_operand" ""))
15126 (use (match_operand:HI 3 "memory_operand" ""))
15127 (clobber (match_operand:DI 4 "memory_operand" ""))
15128 (clobber (match_scratch 5 ""))]
15130 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15131 (use (match_dup 2))
15132 (use (match_dup 3))
15133 (clobber (match_dup 5))])
15134 (set (match_dup 0) (match_dup 4))])
15137 [(set (match_operand:DI 0 "memory_operand" "")
15138 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15140 (use (match_operand:HI 2 "memory_operand" ""))
15141 (use (match_operand:HI 3 "memory_operand" ""))
15142 (clobber (match_operand:DI 4 "memory_operand" ""))
15143 (clobber (match_scratch 5 ""))]
15145 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15146 (use (match_dup 2))
15147 (use (match_dup 3))
15148 (clobber (match_dup 5))])])
15150 (define_insn "fist<mode>2_ceil"
15151 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15152 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15154 (use (match_operand:HI 2 "memory_operand" "m"))
15155 (use (match_operand:HI 3 "memory_operand" "m"))]
15156 "TARGET_USE_FANCY_MATH_387
15157 && flag_unsafe_math_optimizations"
15158 "* return output_fix_trunc (insn, operands, 0);"
15159 [(set_attr "type" "fistp")
15160 (set_attr "i387_cw" "ceil")
15161 (set_attr "mode" "<MODE>")])
15163 (define_insn "fist<mode>2_ceil_with_temp"
15164 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15165 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15167 (use (match_operand:HI 2 "memory_operand" "m,m"))
15168 (use (match_operand:HI 3 "memory_operand" "m,m"))
15169 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15170 "TARGET_USE_FANCY_MATH_387
15171 && flag_unsafe_math_optimizations"
15173 [(set_attr "type" "fistp")
15174 (set_attr "i387_cw" "ceil")
15175 (set_attr "mode" "<MODE>")])
15178 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15179 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15181 (use (match_operand:HI 2 "memory_operand" ""))
15182 (use (match_operand:HI 3 "memory_operand" ""))
15183 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15185 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15187 (use (match_dup 2))
15188 (use (match_dup 3))])
15189 (set (match_dup 0) (match_dup 4))])
15192 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15193 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15195 (use (match_operand:HI 2 "memory_operand" ""))
15196 (use (match_operand:HI 3 "memory_operand" ""))
15197 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15199 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15201 (use (match_dup 2))
15202 (use (match_dup 3))])])
15204 (define_expand "lceilxf<mode>2"
15205 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15206 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15208 (clobber (reg:CC FLAGS_REG))])]
15209 "TARGET_USE_FANCY_MATH_387
15210 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15211 && flag_unsafe_math_optimizations")
15213 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15214 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15215 (match_operand:MODEF 1 "register_operand" "")]
15216 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15217 && !flag_trapping_math"
15219 ix86_expand_lfloorceil (operand0, operand1, false);
15223 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15224 (define_insn_and_split "frndintxf2_trunc"
15225 [(set (match_operand:XF 0 "register_operand" "")
15226 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15227 UNSPEC_FRNDINT_TRUNC))
15228 (clobber (reg:CC FLAGS_REG))]
15229 "TARGET_USE_FANCY_MATH_387
15230 && flag_unsafe_math_optimizations
15231 && can_create_pseudo_p ()"
15236 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15238 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15239 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15241 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15242 operands[2], operands[3]));
15245 [(set_attr "type" "frndint")
15246 (set_attr "i387_cw" "trunc")
15247 (set_attr "mode" "XF")])
15249 (define_insn "frndintxf2_trunc_i387"
15250 [(set (match_operand:XF 0 "register_operand" "=f")
15251 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15252 UNSPEC_FRNDINT_TRUNC))
15253 (use (match_operand:HI 2 "memory_operand" "m"))
15254 (use (match_operand:HI 3 "memory_operand" "m"))]
15255 "TARGET_USE_FANCY_MATH_387
15256 && flag_unsafe_math_optimizations"
15257 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15258 [(set_attr "type" "frndint")
15259 (set_attr "i387_cw" "trunc")
15260 (set_attr "mode" "XF")])
15262 (define_expand "btruncxf2"
15263 [(use (match_operand:XF 0 "register_operand" ""))
15264 (use (match_operand:XF 1 "register_operand" ""))]
15265 "TARGET_USE_FANCY_MATH_387
15266 && flag_unsafe_math_optimizations"
15268 if (optimize_insn_for_size_p ())
15270 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15274 (define_expand "btrunc<mode>2"
15275 [(use (match_operand:MODEF 0 "register_operand" ""))
15276 (use (match_operand:MODEF 1 "register_operand" ""))]
15277 "(TARGET_USE_FANCY_MATH_387
15278 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15279 || TARGET_MIX_SSE_I387)
15280 && flag_unsafe_math_optimizations)
15281 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15282 && !flag_trapping_math)"
15284 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15285 && !flag_trapping_math
15286 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15289 emit_insn (gen_sse4_1_round<mode>2
15290 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15291 else if (optimize_insn_for_size_p ())
15293 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15294 ix86_expand_trunc (operand0, operand1);
15296 ix86_expand_truncdf_32 (operand0, operand1);
15302 if (optimize_insn_for_size_p ())
15305 op0 = gen_reg_rtx (XFmode);
15306 op1 = gen_reg_rtx (XFmode);
15307 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15308 emit_insn (gen_frndintxf2_trunc (op0, op1));
15310 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15315 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15316 (define_insn_and_split "frndintxf2_mask_pm"
15317 [(set (match_operand:XF 0 "register_operand" "")
15318 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15319 UNSPEC_FRNDINT_MASK_PM))
15320 (clobber (reg:CC FLAGS_REG))]
15321 "TARGET_USE_FANCY_MATH_387
15322 && flag_unsafe_math_optimizations
15323 && can_create_pseudo_p ()"
15328 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15330 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15331 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15333 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15334 operands[2], operands[3]));
15337 [(set_attr "type" "frndint")
15338 (set_attr "i387_cw" "mask_pm")
15339 (set_attr "mode" "XF")])
15341 (define_insn "frndintxf2_mask_pm_i387"
15342 [(set (match_operand:XF 0 "register_operand" "=f")
15343 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15344 UNSPEC_FRNDINT_MASK_PM))
15345 (use (match_operand:HI 2 "memory_operand" "m"))
15346 (use (match_operand:HI 3 "memory_operand" "m"))]
15347 "TARGET_USE_FANCY_MATH_387
15348 && flag_unsafe_math_optimizations"
15349 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15350 [(set_attr "type" "frndint")
15351 (set_attr "i387_cw" "mask_pm")
15352 (set_attr "mode" "XF")])
15354 (define_expand "nearbyintxf2"
15355 [(use (match_operand:XF 0 "register_operand" ""))
15356 (use (match_operand:XF 1 "register_operand" ""))]
15357 "TARGET_USE_FANCY_MATH_387
15358 && flag_unsafe_math_optimizations"
15360 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15364 (define_expand "nearbyint<mode>2"
15365 [(use (match_operand:MODEF 0 "register_operand" ""))
15366 (use (match_operand:MODEF 1 "register_operand" ""))]
15367 "TARGET_USE_FANCY_MATH_387
15368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15369 || TARGET_MIX_SSE_I387)
15370 && flag_unsafe_math_optimizations"
15372 rtx op0 = gen_reg_rtx (XFmode);
15373 rtx op1 = gen_reg_rtx (XFmode);
15375 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15376 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15378 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15382 (define_insn "fxam<mode>2_i387"
15383 [(set (match_operand:HI 0 "register_operand" "=a")
15385 [(match_operand:X87MODEF 1 "register_operand" "f")]
15387 "TARGET_USE_FANCY_MATH_387"
15388 "fxam\n\tfnstsw\t%0"
15389 [(set_attr "type" "multi")
15390 (set_attr "length" "4")
15391 (set_attr "unit" "i387")
15392 (set_attr "mode" "<MODE>")])
15394 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15395 [(set (match_operand:HI 0 "register_operand" "")
15397 [(match_operand:MODEF 1 "memory_operand" "")]
15399 "TARGET_USE_FANCY_MATH_387
15400 && can_create_pseudo_p ()"
15403 [(set (match_dup 2)(match_dup 1))
15405 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15407 operands[2] = gen_reg_rtx (<MODE>mode);
15409 MEM_VOLATILE_P (operands[1]) = 1;
15411 [(set_attr "type" "multi")
15412 (set_attr "unit" "i387")
15413 (set_attr "mode" "<MODE>")])
15415 (define_expand "isinfxf2"
15416 [(use (match_operand:SI 0 "register_operand" ""))
15417 (use (match_operand:XF 1 "register_operand" ""))]
15418 "TARGET_USE_FANCY_MATH_387
15419 && TARGET_C99_FUNCTIONS"
15421 rtx mask = GEN_INT (0x45);
15422 rtx val = GEN_INT (0x05);
15426 rtx scratch = gen_reg_rtx (HImode);
15427 rtx res = gen_reg_rtx (QImode);
15429 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15431 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15432 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15433 cond = gen_rtx_fmt_ee (EQ, QImode,
15434 gen_rtx_REG (CCmode, FLAGS_REG),
15436 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15437 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15441 (define_expand "isinf<mode>2"
15442 [(use (match_operand:SI 0 "register_operand" ""))
15443 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15444 "TARGET_USE_FANCY_MATH_387
15445 && TARGET_C99_FUNCTIONS
15446 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15448 rtx mask = GEN_INT (0x45);
15449 rtx val = GEN_INT (0x05);
15453 rtx scratch = gen_reg_rtx (HImode);
15454 rtx res = gen_reg_rtx (QImode);
15456 /* Remove excess precision by forcing value through memory. */
15457 if (memory_operand (operands[1], VOIDmode))
15458 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15461 enum ix86_stack_slot slot = (virtuals_instantiated
15464 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15466 emit_move_insn (temp, operands[1]);
15467 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15470 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15471 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15472 cond = gen_rtx_fmt_ee (EQ, QImode,
15473 gen_rtx_REG (CCmode, FLAGS_REG),
15475 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15476 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15480 (define_expand "signbitxf2"
15481 [(use (match_operand:SI 0 "register_operand" ""))
15482 (use (match_operand:XF 1 "register_operand" ""))]
15483 "TARGET_USE_FANCY_MATH_387"
15485 rtx scratch = gen_reg_rtx (HImode);
15487 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15488 emit_insn (gen_andsi3 (operands[0],
15489 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15493 (define_insn "movmsk_df"
15494 [(set (match_operand:SI 0 "register_operand" "=r")
15496 [(match_operand:DF 1 "register_operand" "x")]
15498 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15499 "%vmovmskpd\t{%1, %0|%0, %1}"
15500 [(set_attr "type" "ssemov")
15501 (set_attr "prefix" "maybe_vex")
15502 (set_attr "mode" "DF")])
15504 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15505 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15506 (define_expand "signbitdf2"
15507 [(use (match_operand:SI 0 "register_operand" ""))
15508 (use (match_operand:DF 1 "register_operand" ""))]
15509 "TARGET_USE_FANCY_MATH_387
15510 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15512 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15514 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15515 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15519 rtx scratch = gen_reg_rtx (HImode);
15521 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15522 emit_insn (gen_andsi3 (operands[0],
15523 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15528 (define_expand "signbitsf2"
15529 [(use (match_operand:SI 0 "register_operand" ""))
15530 (use (match_operand:SF 1 "register_operand" ""))]
15531 "TARGET_USE_FANCY_MATH_387
15532 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15534 rtx scratch = gen_reg_rtx (HImode);
15536 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15537 emit_insn (gen_andsi3 (operands[0],
15538 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15542 ;; Block operation instructions
15545 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15548 [(set_attr "length" "1")
15549 (set_attr "length_immediate" "0")
15550 (set_attr "modrm" "0")])
15552 (define_expand "movmem<mode>"
15553 [(use (match_operand:BLK 0 "memory_operand" ""))
15554 (use (match_operand:BLK 1 "memory_operand" ""))
15555 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15556 (use (match_operand:SWI48 3 "const_int_operand" ""))
15557 (use (match_operand:SI 4 "const_int_operand" ""))
15558 (use (match_operand:SI 5 "const_int_operand" ""))]
15561 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15562 operands[4], operands[5]))
15568 ;; Most CPUs don't like single string operations
15569 ;; Handle this case here to simplify previous expander.
15571 (define_expand "strmov"
15572 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15573 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15574 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15575 (clobber (reg:CC FLAGS_REG))])
15576 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15577 (clobber (reg:CC FLAGS_REG))])]
15580 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15582 /* If .md ever supports :P for Pmode, these can be directly
15583 in the pattern above. */
15584 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15585 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15587 /* Can't use this if the user has appropriated esi or edi. */
15588 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15589 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15591 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15592 operands[2], operands[3],
15593 operands[5], operands[6]));
15597 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15600 (define_expand "strmov_singleop"
15601 [(parallel [(set (match_operand 1 "memory_operand" "")
15602 (match_operand 3 "memory_operand" ""))
15603 (set (match_operand 0 "register_operand" "")
15604 (match_operand 4 "" ""))
15605 (set (match_operand 2 "register_operand" "")
15606 (match_operand 5 "" ""))])]
15608 "ix86_current_function_needs_cld = 1;")
15610 (define_insn "*strmovdi_rex_1"
15611 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15612 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15613 (set (match_operand:DI 0 "register_operand" "=D")
15614 (plus:DI (match_dup 2)
15616 (set (match_operand:DI 1 "register_operand" "=S")
15617 (plus:DI (match_dup 3)
15621 [(set_attr "type" "str")
15622 (set_attr "memory" "both")
15623 (set_attr "mode" "DI")])
15625 (define_insn "*strmovsi_1"
15626 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15627 (mem:SI (match_operand:P 3 "register_operand" "1")))
15628 (set (match_operand:P 0 "register_operand" "=D")
15629 (plus:P (match_dup 2)
15631 (set (match_operand:P 1 "register_operand" "=S")
15632 (plus:P (match_dup 3)
15636 [(set_attr "type" "str")
15637 (set_attr "memory" "both")
15638 (set_attr "mode" "SI")])
15640 (define_insn "*strmovhi_1"
15641 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15642 (mem:HI (match_operand:P 3 "register_operand" "1")))
15643 (set (match_operand:P 0 "register_operand" "=D")
15644 (plus:P (match_dup 2)
15646 (set (match_operand:P 1 "register_operand" "=S")
15647 (plus:P (match_dup 3)
15651 [(set_attr "type" "str")
15652 (set_attr "memory" "both")
15653 (set_attr "mode" "HI")])
15655 (define_insn "*strmovqi_1"
15656 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15657 (mem:QI (match_operand:P 3 "register_operand" "1")))
15658 (set (match_operand:P 0 "register_operand" "=D")
15659 (plus:P (match_dup 2)
15661 (set (match_operand:P 1 "register_operand" "=S")
15662 (plus:P (match_dup 3)
15666 [(set_attr "type" "str")
15667 (set_attr "memory" "both")
15668 (set (attr "prefix_rex")
15670 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15672 (const_string "*")))
15673 (set_attr "mode" "QI")])
15675 (define_expand "rep_mov"
15676 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15677 (set (match_operand 0 "register_operand" "")
15678 (match_operand 5 "" ""))
15679 (set (match_operand 2 "register_operand" "")
15680 (match_operand 6 "" ""))
15681 (set (match_operand 1 "memory_operand" "")
15682 (match_operand 3 "memory_operand" ""))
15683 (use (match_dup 4))])]
15685 "ix86_current_function_needs_cld = 1;")
15687 (define_insn "*rep_movdi_rex64"
15688 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15689 (set (match_operand:DI 0 "register_operand" "=D")
15690 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15692 (match_operand:DI 3 "register_operand" "0")))
15693 (set (match_operand:DI 1 "register_operand" "=S")
15694 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15695 (match_operand:DI 4 "register_operand" "1")))
15696 (set (mem:BLK (match_dup 3))
15697 (mem:BLK (match_dup 4)))
15698 (use (match_dup 5))]
15701 [(set_attr "type" "str")
15702 (set_attr "prefix_rep" "1")
15703 (set_attr "memory" "both")
15704 (set_attr "mode" "DI")])
15706 (define_insn "*rep_movsi"
15707 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15708 (set (match_operand:P 0 "register_operand" "=D")
15709 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15711 (match_operand:P 3 "register_operand" "0")))
15712 (set (match_operand:P 1 "register_operand" "=S")
15713 (plus:P (ashift:P (match_dup 5) (const_int 2))
15714 (match_operand:P 4 "register_operand" "1")))
15715 (set (mem:BLK (match_dup 3))
15716 (mem:BLK (match_dup 4)))
15717 (use (match_dup 5))]
15719 "rep{%;} movs{l|d}"
15720 [(set_attr "type" "str")
15721 (set_attr "prefix_rep" "1")
15722 (set_attr "memory" "both")
15723 (set_attr "mode" "SI")])
15725 (define_insn "*rep_movqi"
15726 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15727 (set (match_operand:P 0 "register_operand" "=D")
15728 (plus:P (match_operand:P 3 "register_operand" "0")
15729 (match_operand:P 5 "register_operand" "2")))
15730 (set (match_operand:P 1 "register_operand" "=S")
15731 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15732 (set (mem:BLK (match_dup 3))
15733 (mem:BLK (match_dup 4)))
15734 (use (match_dup 5))]
15737 [(set_attr "type" "str")
15738 (set_attr "prefix_rep" "1")
15739 (set_attr "memory" "both")
15740 (set_attr "mode" "QI")])
15742 (define_expand "setmem<mode>"
15743 [(use (match_operand:BLK 0 "memory_operand" ""))
15744 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15745 (use (match_operand:QI 2 "nonmemory_operand" ""))
15746 (use (match_operand 3 "const_int_operand" ""))
15747 (use (match_operand:SI 4 "const_int_operand" ""))
15748 (use (match_operand:SI 5 "const_int_operand" ""))]
15751 if (ix86_expand_setmem (operands[0], operands[1],
15752 operands[2], operands[3],
15753 operands[4], operands[5]))
15759 ;; Most CPUs don't like single string operations
15760 ;; Handle this case here to simplify previous expander.
15762 (define_expand "strset"
15763 [(set (match_operand 1 "memory_operand" "")
15764 (match_operand 2 "register_operand" ""))
15765 (parallel [(set (match_operand 0 "register_operand" "")
15767 (clobber (reg:CC FLAGS_REG))])]
15770 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15771 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15773 /* If .md ever supports :P for Pmode, this can be directly
15774 in the pattern above. */
15775 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15776 GEN_INT (GET_MODE_SIZE (GET_MODE
15778 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15780 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15786 (define_expand "strset_singleop"
15787 [(parallel [(set (match_operand 1 "memory_operand" "")
15788 (match_operand 2 "register_operand" ""))
15789 (set (match_operand 0 "register_operand" "")
15790 (match_operand 3 "" ""))])]
15792 "ix86_current_function_needs_cld = 1;")
15794 (define_insn "*strsetdi_rex_1"
15795 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15796 (match_operand:DI 2 "register_operand" "a"))
15797 (set (match_operand:DI 0 "register_operand" "=D")
15798 (plus:DI (match_dup 1)
15802 [(set_attr "type" "str")
15803 (set_attr "memory" "store")
15804 (set_attr "mode" "DI")])
15806 (define_insn "*strsetsi_1"
15807 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15808 (match_operand:SI 2 "register_operand" "a"))
15809 (set (match_operand:P 0 "register_operand" "=D")
15810 (plus:P (match_dup 1)
15814 [(set_attr "type" "str")
15815 (set_attr "memory" "store")
15816 (set_attr "mode" "SI")])
15818 (define_insn "*strsethi_1"
15819 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15820 (match_operand:HI 2 "register_operand" "a"))
15821 (set (match_operand:P 0 "register_operand" "=D")
15822 (plus:P (match_dup 1)
15826 [(set_attr "type" "str")
15827 (set_attr "memory" "store")
15828 (set_attr "mode" "HI")])
15830 (define_insn "*strsetqi_1"
15831 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15832 (match_operand:QI 2 "register_operand" "a"))
15833 (set (match_operand:P 0 "register_operand" "=D")
15834 (plus:P (match_dup 1)
15838 [(set_attr "type" "str")
15839 (set_attr "memory" "store")
15840 (set (attr "prefix_rex")
15842 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15844 (const_string "*")))
15845 (set_attr "mode" "QI")])
15847 (define_expand "rep_stos"
15848 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15849 (set (match_operand 0 "register_operand" "")
15850 (match_operand 4 "" ""))
15851 (set (match_operand 2 "memory_operand" "") (const_int 0))
15852 (use (match_operand 3 "register_operand" ""))
15853 (use (match_dup 1))])]
15855 "ix86_current_function_needs_cld = 1;")
15857 (define_insn "*rep_stosdi_rex64"
15858 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15859 (set (match_operand:DI 0 "register_operand" "=D")
15860 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15862 (match_operand:DI 3 "register_operand" "0")))
15863 (set (mem:BLK (match_dup 3))
15865 (use (match_operand:DI 2 "register_operand" "a"))
15866 (use (match_dup 4))]
15869 [(set_attr "type" "str")
15870 (set_attr "prefix_rep" "1")
15871 (set_attr "memory" "store")
15872 (set_attr "mode" "DI")])
15874 (define_insn "*rep_stossi"
15875 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15876 (set (match_operand:P 0 "register_operand" "=D")
15877 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15879 (match_operand:P 3 "register_operand" "0")))
15880 (set (mem:BLK (match_dup 3))
15882 (use (match_operand:SI 2 "register_operand" "a"))
15883 (use (match_dup 4))]
15885 "rep{%;} stos{l|d}"
15886 [(set_attr "type" "str")
15887 (set_attr "prefix_rep" "1")
15888 (set_attr "memory" "store")
15889 (set_attr "mode" "SI")])
15891 (define_insn "*rep_stosqi"
15892 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15893 (set (match_operand:P 0 "register_operand" "=D")
15894 (plus:P (match_operand:P 3 "register_operand" "0")
15895 (match_operand:P 4 "register_operand" "1")))
15896 (set (mem:BLK (match_dup 3))
15898 (use (match_operand:QI 2 "register_operand" "a"))
15899 (use (match_dup 4))]
15902 [(set_attr "type" "str")
15903 (set_attr "prefix_rep" "1")
15904 (set_attr "memory" "store")
15905 (set (attr "prefix_rex")
15907 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15909 (const_string "*")))
15910 (set_attr "mode" "QI")])
15912 (define_expand "cmpstrnsi"
15913 [(set (match_operand:SI 0 "register_operand" "")
15914 (compare:SI (match_operand:BLK 1 "general_operand" "")
15915 (match_operand:BLK 2 "general_operand" "")))
15916 (use (match_operand 3 "general_operand" ""))
15917 (use (match_operand 4 "immediate_operand" ""))]
15920 rtx addr1, addr2, out, outlow, count, countreg, align;
15922 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15925 /* Can't use this if the user has appropriated esi or edi. */
15926 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15931 out = gen_reg_rtx (SImode);
15933 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15934 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15935 if (addr1 != XEXP (operands[1], 0))
15936 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15937 if (addr2 != XEXP (operands[2], 0))
15938 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15940 count = operands[3];
15941 countreg = ix86_zero_extend_to_Pmode (count);
15943 /* %%% Iff we are testing strict equality, we can use known alignment
15944 to good advantage. This may be possible with combine, particularly
15945 once cc0 is dead. */
15946 align = operands[4];
15948 if (CONST_INT_P (count))
15950 if (INTVAL (count) == 0)
15952 emit_move_insn (operands[0], const0_rtx);
15955 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15956 operands[1], operands[2]));
15960 rtx (*gen_cmp) (rtx, rtx);
15962 gen_cmp = (TARGET_64BIT
15963 ? gen_cmpdi_1 : gen_cmpsi_1);
15965 emit_insn (gen_cmp (countreg, countreg));
15966 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15967 operands[1], operands[2]));
15970 outlow = gen_lowpart (QImode, out);
15971 emit_insn (gen_cmpintqi (outlow));
15972 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15974 if (operands[0] != out)
15975 emit_move_insn (operands[0], out);
15980 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15982 (define_expand "cmpintqi"
15983 [(set (match_dup 1)
15984 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15986 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15987 (parallel [(set (match_operand:QI 0 "register_operand" "")
15988 (minus:QI (match_dup 1)
15990 (clobber (reg:CC FLAGS_REG))])]
15993 operands[1] = gen_reg_rtx (QImode);
15994 operands[2] = gen_reg_rtx (QImode);
15997 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15998 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16000 (define_expand "cmpstrnqi_nz_1"
16001 [(parallel [(set (reg:CC FLAGS_REG)
16002 (compare:CC (match_operand 4 "memory_operand" "")
16003 (match_operand 5 "memory_operand" "")))
16004 (use (match_operand 2 "register_operand" ""))
16005 (use (match_operand:SI 3 "immediate_operand" ""))
16006 (clobber (match_operand 0 "register_operand" ""))
16007 (clobber (match_operand 1 "register_operand" ""))
16008 (clobber (match_dup 2))])]
16010 "ix86_current_function_needs_cld = 1;")
16012 (define_insn "*cmpstrnqi_nz_1"
16013 [(set (reg:CC FLAGS_REG)
16014 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16015 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16016 (use (match_operand:P 6 "register_operand" "2"))
16017 (use (match_operand:SI 3 "immediate_operand" "i"))
16018 (clobber (match_operand:P 0 "register_operand" "=S"))
16019 (clobber (match_operand:P 1 "register_operand" "=D"))
16020 (clobber (match_operand:P 2 "register_operand" "=c"))]
16023 [(set_attr "type" "str")
16024 (set_attr "mode" "QI")
16025 (set (attr "prefix_rex")
16027 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16029 (const_string "*")))
16030 (set_attr "prefix_rep" "1")])
16032 ;; The same, but the count is not known to not be zero.
16034 (define_expand "cmpstrnqi_1"
16035 [(parallel [(set (reg:CC FLAGS_REG)
16036 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16038 (compare:CC (match_operand 4 "memory_operand" "")
16039 (match_operand 5 "memory_operand" ""))
16041 (use (match_operand:SI 3 "immediate_operand" ""))
16042 (use (reg:CC FLAGS_REG))
16043 (clobber (match_operand 0 "register_operand" ""))
16044 (clobber (match_operand 1 "register_operand" ""))
16045 (clobber (match_dup 2))])]
16047 "ix86_current_function_needs_cld = 1;")
16049 (define_insn "*cmpstrnqi_1"
16050 [(set (reg:CC FLAGS_REG)
16051 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16053 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16054 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16056 (use (match_operand:SI 3 "immediate_operand" "i"))
16057 (use (reg:CC FLAGS_REG))
16058 (clobber (match_operand:P 0 "register_operand" "=S"))
16059 (clobber (match_operand:P 1 "register_operand" "=D"))
16060 (clobber (match_operand:P 2 "register_operand" "=c"))]
16063 [(set_attr "type" "str")
16064 (set_attr "mode" "QI")
16065 (set (attr "prefix_rex")
16067 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16069 (const_string "*")))
16070 (set_attr "prefix_rep" "1")])
16072 (define_expand "strlen<mode>"
16073 [(set (match_operand:SWI48x 0 "register_operand" "")
16074 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16075 (match_operand:QI 2 "immediate_operand" "")
16076 (match_operand 3 "immediate_operand" "")]
16080 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16086 (define_expand "strlenqi_1"
16087 [(parallel [(set (match_operand 0 "register_operand" "")
16088 (match_operand 2 "" ""))
16089 (clobber (match_operand 1 "register_operand" ""))
16090 (clobber (reg:CC FLAGS_REG))])]
16092 "ix86_current_function_needs_cld = 1;")
16094 (define_insn "*strlenqi_1"
16095 [(set (match_operand:P 0 "register_operand" "=&c")
16096 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16097 (match_operand:QI 2 "register_operand" "a")
16098 (match_operand:P 3 "immediate_operand" "i")
16099 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16100 (clobber (match_operand:P 1 "register_operand" "=D"))
16101 (clobber (reg:CC FLAGS_REG))]
16104 [(set_attr "type" "str")
16105 (set_attr "mode" "QI")
16106 (set (attr "prefix_rex")
16108 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16110 (const_string "*")))
16111 (set_attr "prefix_rep" "1")])
16113 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16114 ;; handled in combine, but it is not currently up to the task.
16115 ;; When used for their truth value, the cmpstrn* expanders generate
16124 ;; The intermediate three instructions are unnecessary.
16126 ;; This one handles cmpstrn*_nz_1...
16129 (set (reg:CC FLAGS_REG)
16130 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16131 (mem:BLK (match_operand 5 "register_operand" ""))))
16132 (use (match_operand 6 "register_operand" ""))
16133 (use (match_operand:SI 3 "immediate_operand" ""))
16134 (clobber (match_operand 0 "register_operand" ""))
16135 (clobber (match_operand 1 "register_operand" ""))
16136 (clobber (match_operand 2 "register_operand" ""))])
16137 (set (match_operand:QI 7 "register_operand" "")
16138 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16139 (set (match_operand:QI 8 "register_operand" "")
16140 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16141 (set (reg FLAGS_REG)
16142 (compare (match_dup 7) (match_dup 8)))
16144 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16146 (set (reg:CC FLAGS_REG)
16147 (compare:CC (mem:BLK (match_dup 4))
16148 (mem:BLK (match_dup 5))))
16149 (use (match_dup 6))
16150 (use (match_dup 3))
16151 (clobber (match_dup 0))
16152 (clobber (match_dup 1))
16153 (clobber (match_dup 2))])])
16155 ;; ...and this one handles cmpstrn*_1.
16158 (set (reg:CC FLAGS_REG)
16159 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16161 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16162 (mem:BLK (match_operand 5 "register_operand" "")))
16164 (use (match_operand:SI 3 "immediate_operand" ""))
16165 (use (reg:CC FLAGS_REG))
16166 (clobber (match_operand 0 "register_operand" ""))
16167 (clobber (match_operand 1 "register_operand" ""))
16168 (clobber (match_operand 2 "register_operand" ""))])
16169 (set (match_operand:QI 7 "register_operand" "")
16170 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16171 (set (match_operand:QI 8 "register_operand" "")
16172 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16173 (set (reg FLAGS_REG)
16174 (compare (match_dup 7) (match_dup 8)))
16176 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16178 (set (reg:CC FLAGS_REG)
16179 (if_then_else:CC (ne (match_dup 6)
16181 (compare:CC (mem:BLK (match_dup 4))
16182 (mem:BLK (match_dup 5)))
16184 (use (match_dup 3))
16185 (use (reg:CC FLAGS_REG))
16186 (clobber (match_dup 0))
16187 (clobber (match_dup 1))
16188 (clobber (match_dup 2))])])
16190 ;; Conditional move instructions.
16192 (define_expand "mov<mode>cc"
16193 [(set (match_operand:SWIM 0 "register_operand" "")
16194 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16195 (match_operand:SWIM 2 "general_operand" "")
16196 (match_operand:SWIM 3 "general_operand" "")))]
16198 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16200 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16201 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16202 ;; So just document what we're doing explicitly.
16204 (define_expand "x86_mov<mode>cc_0_m1"
16206 [(set (match_operand:SWI48 0 "register_operand" "")
16207 (if_then_else:SWI48
16208 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16209 [(match_operand 1 "flags_reg_operand" "")
16213 (clobber (reg:CC FLAGS_REG))])])
16215 (define_insn "*x86_mov<mode>cc_0_m1"
16216 [(set (match_operand:SWI48 0 "register_operand" "=r")
16217 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16218 [(reg FLAGS_REG) (const_int 0)])
16221 (clobber (reg:CC FLAGS_REG))]
16223 "sbb{<imodesuffix>}\t%0, %0"
16224 ; Since we don't have the proper number of operands for an alu insn,
16225 ; fill in all the blanks.
16226 [(set_attr "type" "alu")
16227 (set_attr "use_carry" "1")
16228 (set_attr "pent_pair" "pu")
16229 (set_attr "memory" "none")
16230 (set_attr "imm_disp" "false")
16231 (set_attr "mode" "<MODE>")
16232 (set_attr "length_immediate" "0")])
16234 (define_insn "*x86_mov<mode>cc_0_m1_se"
16235 [(set (match_operand:SWI48 0 "register_operand" "=r")
16236 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16237 [(reg FLAGS_REG) (const_int 0)])
16240 (clobber (reg:CC FLAGS_REG))]
16242 "sbb{<imodesuffix>}\t%0, %0"
16243 [(set_attr "type" "alu")
16244 (set_attr "use_carry" "1")
16245 (set_attr "pent_pair" "pu")
16246 (set_attr "memory" "none")
16247 (set_attr "imm_disp" "false")
16248 (set_attr "mode" "<MODE>")
16249 (set_attr "length_immediate" "0")])
16251 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16252 [(set (match_operand:SWI48 0 "register_operand" "=r")
16253 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16254 [(reg FLAGS_REG) (const_int 0)])))]
16256 "sbb{<imodesuffix>}\t%0, %0"
16257 [(set_attr "type" "alu")
16258 (set_attr "use_carry" "1")
16259 (set_attr "pent_pair" "pu")
16260 (set_attr "memory" "none")
16261 (set_attr "imm_disp" "false")
16262 (set_attr "mode" "<MODE>")
16263 (set_attr "length_immediate" "0")])
16265 (define_insn "*mov<mode>cc_noc"
16266 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16267 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16268 [(reg FLAGS_REG) (const_int 0)])
16269 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16270 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16271 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16273 cmov%O2%C1\t{%2, %0|%0, %2}
16274 cmov%O2%c1\t{%3, %0|%0, %3}"
16275 [(set_attr "type" "icmov")
16276 (set_attr "mode" "<MODE>")])
16278 (define_insn_and_split "*movqicc_noc"
16279 [(set (match_operand:QI 0 "register_operand" "=r,r")
16280 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16281 [(match_operand 4 "flags_reg_operand" "")
16283 (match_operand:QI 2 "register_operand" "r,0")
16284 (match_operand:QI 3 "register_operand" "0,r")))]
16285 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16287 "&& reload_completed"
16288 [(set (match_dup 0)
16289 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16292 "operands[0] = gen_lowpart (SImode, operands[0]);
16293 operands[2] = gen_lowpart (SImode, operands[2]);
16294 operands[3] = gen_lowpart (SImode, operands[3]);"
16295 [(set_attr "type" "icmov")
16296 (set_attr "mode" "SI")])
16298 (define_expand "mov<mode>cc"
16299 [(set (match_operand:X87MODEF 0 "register_operand" "")
16300 (if_then_else:X87MODEF
16301 (match_operand 1 "ix86_fp_comparison_operator" "")
16302 (match_operand:X87MODEF 2 "register_operand" "")
16303 (match_operand:X87MODEF 3 "register_operand" "")))]
16304 "(TARGET_80387 && TARGET_CMOVE)
16305 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16306 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16308 (define_insn "*movxfcc_1"
16309 [(set (match_operand:XF 0 "register_operand" "=f,f")
16310 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16311 [(reg FLAGS_REG) (const_int 0)])
16312 (match_operand:XF 2 "register_operand" "f,0")
16313 (match_operand:XF 3 "register_operand" "0,f")))]
16314 "TARGET_80387 && TARGET_CMOVE"
16316 fcmov%F1\t{%2, %0|%0, %2}
16317 fcmov%f1\t{%3, %0|%0, %3}"
16318 [(set_attr "type" "fcmov")
16319 (set_attr "mode" "XF")])
16321 (define_insn "*movdfcc_1_rex64"
16322 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16323 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16324 [(reg FLAGS_REG) (const_int 0)])
16325 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16326 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16327 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16328 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16330 fcmov%F1\t{%2, %0|%0, %2}
16331 fcmov%f1\t{%3, %0|%0, %3}
16332 cmov%O2%C1\t{%2, %0|%0, %2}
16333 cmov%O2%c1\t{%3, %0|%0, %3}"
16334 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16335 (set_attr "mode" "DF,DF,DI,DI")])
16337 (define_insn "*movdfcc_1"
16338 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16339 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16340 [(reg FLAGS_REG) (const_int 0)])
16341 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16342 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16343 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16344 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16346 fcmov%F1\t{%2, %0|%0, %2}
16347 fcmov%f1\t{%3, %0|%0, %3}
16350 [(set_attr "type" "fcmov,fcmov,multi,multi")
16351 (set_attr "mode" "DF,DF,DI,DI")])
16354 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16355 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16356 [(match_operand 4 "flags_reg_operand" "")
16358 (match_operand:DF 2 "nonimmediate_operand" "")
16359 (match_operand:DF 3 "nonimmediate_operand" "")))]
16360 "!TARGET_64BIT && reload_completed"
16361 [(set (match_dup 2)
16362 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16366 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16370 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16371 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16374 (define_insn "*movsfcc_1_387"
16375 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16376 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16377 [(reg FLAGS_REG) (const_int 0)])
16378 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16379 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16380 "TARGET_80387 && TARGET_CMOVE
16381 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16383 fcmov%F1\t{%2, %0|%0, %2}
16384 fcmov%f1\t{%3, %0|%0, %3}
16385 cmov%O2%C1\t{%2, %0|%0, %2}
16386 cmov%O2%c1\t{%3, %0|%0, %3}"
16387 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16388 (set_attr "mode" "SF,SF,SI,SI")])
16390 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16391 ;; the scalar versions to have only XMM registers as operands.
16393 ;; XOP conditional move
16394 (define_insn "*xop_pcmov_<mode>"
16395 [(set (match_operand:MODEF 0 "register_operand" "=x")
16396 (if_then_else:MODEF
16397 (match_operand:MODEF 1 "register_operand" "x")
16398 (match_operand:MODEF 2 "register_operand" "x")
16399 (match_operand:MODEF 3 "register_operand" "x")))]
16401 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16402 [(set_attr "type" "sse4arg")])
16404 ;; These versions of the min/max patterns are intentionally ignorant of
16405 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16406 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16407 ;; are undefined in this condition, we're certain this is correct.
16409 (define_insn "<code><mode>3"
16410 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16412 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16413 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16414 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16416 <maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}
16417 v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16418 [(set_attr "isa" "noavx,avx")
16419 (set_attr "prefix" "orig,vex")
16420 (set_attr "type" "sseadd")
16421 (set_attr "mode" "<MODE>")])
16423 ;; These versions of the min/max patterns implement exactly the operations
16424 ;; min = (op1 < op2 ? op1 : op2)
16425 ;; max = (!(op1 < op2) ? op1 : op2)
16426 ;; Their operands are not commutative, and thus they may be used in the
16427 ;; presence of -0.0 and NaN.
16429 (define_insn "*ieee_smin<mode>3"
16430 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16432 [(match_operand:MODEF 1 "register_operand" "0,x")
16433 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16435 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16437 mins<ssemodefsuffix>\t{%2, %0|%0, %2}
16438 vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16439 [(set_attr "isa" "noavx,avx")
16440 (set_attr "prefix" "orig,vex")
16441 (set_attr "type" "sseadd")
16442 (set_attr "mode" "<MODE>")])
16444 (define_insn "*ieee_smax<mode>3"
16445 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16447 [(match_operand:MODEF 1 "register_operand" "0,x")
16448 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16450 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16452 maxs<ssemodefsuffix>\t{%2, %0|%0, %2}
16453 vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16454 [(set_attr "isa" "noavx,avx")
16455 (set_attr "prefix" "orig,vex")
16456 (set_attr "type" "sseadd")
16457 (set_attr "mode" "<MODE>")])
16459 ;; Make two stack loads independent:
16461 ;; fld %st(0) -> fld bb
16462 ;; fmul bb fmul %st(1), %st
16464 ;; Actually we only match the last two instructions for simplicity.
16466 [(set (match_operand 0 "fp_register_operand" "")
16467 (match_operand 1 "fp_register_operand" ""))
16469 (match_operator 2 "binary_fp_operator"
16471 (match_operand 3 "memory_operand" "")]))]
16472 "REGNO (operands[0]) != REGNO (operands[1])"
16473 [(set (match_dup 0) (match_dup 3))
16474 (set (match_dup 0) (match_dup 4))]
16476 ;; The % modifier is not operational anymore in peephole2's, so we have to
16477 ;; swap the operands manually in the case of addition and multiplication.
16478 "if (COMMUTATIVE_ARITH_P (operands[2]))
16479 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16480 GET_MODE (operands[2]),
16481 operands[0], operands[1]);
16483 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16484 GET_MODE (operands[2]),
16485 operands[1], operands[0]);")
16487 ;; Conditional addition patterns
16488 (define_expand "add<mode>cc"
16489 [(match_operand:SWI 0 "register_operand" "")
16490 (match_operand 1 "ordered_comparison_operator" "")
16491 (match_operand:SWI 2 "register_operand" "")
16492 (match_operand:SWI 3 "const_int_operand" "")]
16494 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16496 ;; Misc patterns (?)
16498 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16499 ;; Otherwise there will be nothing to keep
16501 ;; [(set (reg ebp) (reg esp))]
16502 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16503 ;; (clobber (eflags)]
16504 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16506 ;; in proper program order.
16508 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16509 [(set (match_operand:P 0 "register_operand" "=r,r")
16510 (plus:P (match_operand:P 1 "register_operand" "0,r")
16511 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16512 (clobber (reg:CC FLAGS_REG))
16513 (clobber (mem:BLK (scratch)))]
16516 switch (get_attr_type (insn))
16519 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16522 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16523 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16524 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16526 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16529 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16530 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16533 [(set (attr "type")
16534 (cond [(and (eq_attr "alternative" "0")
16535 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16536 (const_string "alu")
16537 (match_operand:<MODE> 2 "const0_operand" "")
16538 (const_string "imov")
16540 (const_string "lea")))
16541 (set (attr "length_immediate")
16542 (cond [(eq_attr "type" "imov")
16544 (and (eq_attr "type" "alu")
16545 (match_operand 2 "const128_operand" ""))
16548 (const_string "*")))
16549 (set_attr "mode" "<MODE>")])
16551 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16552 [(set (match_operand:P 0 "register_operand" "=r")
16553 (minus:P (match_operand:P 1 "register_operand" "0")
16554 (match_operand:P 2 "register_operand" "r")))
16555 (clobber (reg:CC FLAGS_REG))
16556 (clobber (mem:BLK (scratch)))]
16558 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16559 [(set_attr "type" "alu")
16560 (set_attr "mode" "<MODE>")])
16562 (define_insn "allocate_stack_worker_probe_<mode>"
16563 [(set (match_operand:P 0 "register_operand" "=a")
16564 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16565 UNSPECV_STACK_PROBE))
16566 (clobber (reg:CC FLAGS_REG))]
16567 "ix86_target_stack_probe ()"
16568 "call\t___chkstk_ms"
16569 [(set_attr "type" "multi")
16570 (set_attr "length" "5")])
16572 (define_expand "allocate_stack"
16573 [(match_operand 0 "register_operand" "")
16574 (match_operand 1 "general_operand" "")]
16575 "ix86_target_stack_probe ()"
16579 #ifndef CHECK_STACK_LIMIT
16580 #define CHECK_STACK_LIMIT 0
16583 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16584 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16586 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16587 stack_pointer_rtx, 0, OPTAB_DIRECT);
16588 if (x != stack_pointer_rtx)
16589 emit_move_insn (stack_pointer_rtx, x);
16593 x = copy_to_mode_reg (Pmode, operands[1]);
16595 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16597 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16598 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16599 stack_pointer_rtx, 0, OPTAB_DIRECT);
16600 if (x != stack_pointer_rtx)
16601 emit_move_insn (stack_pointer_rtx, x);
16604 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16608 ;; Use IOR for stack probes, this is shorter.
16609 (define_expand "probe_stack"
16610 [(match_operand 0 "memory_operand" "")]
16613 rtx (*gen_ior3) (rtx, rtx, rtx);
16615 gen_ior3 = (GET_MODE (operands[0]) == DImode
16616 ? gen_iordi3 : gen_iorsi3);
16618 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16622 (define_insn "adjust_stack_and_probe<mode>"
16623 [(set (match_operand:P 0 "register_operand" "=r")
16624 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16625 UNSPECV_PROBE_STACK_RANGE))
16626 (set (reg:P SP_REG)
16627 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16628 (clobber (reg:CC FLAGS_REG))
16629 (clobber (mem:BLK (scratch)))]
16631 "* return output_adjust_stack_and_probe (operands[0]);"
16632 [(set_attr "type" "multi")])
16634 (define_insn "probe_stack_range<mode>"
16635 [(set (match_operand:P 0 "register_operand" "=r")
16636 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16637 (match_operand:P 2 "const_int_operand" "n")]
16638 UNSPECV_PROBE_STACK_RANGE))
16639 (clobber (reg:CC FLAGS_REG))]
16641 "* return output_probe_stack_range (operands[0], operands[2]);"
16642 [(set_attr "type" "multi")])
16644 (define_expand "builtin_setjmp_receiver"
16645 [(label_ref (match_operand 0 "" ""))]
16646 "!TARGET_64BIT && flag_pic"
16652 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16653 rtx label_rtx = gen_label_rtx ();
16654 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16655 xops[0] = xops[1] = picreg;
16656 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16657 ix86_expand_binary_operator (MINUS, SImode, xops);
16661 emit_insn (gen_set_got (pic_offset_table_rtx));
16665 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16668 [(set (match_operand 0 "register_operand" "")
16669 (match_operator 3 "promotable_binary_operator"
16670 [(match_operand 1 "register_operand" "")
16671 (match_operand 2 "aligned_operand" "")]))
16672 (clobber (reg:CC FLAGS_REG))]
16673 "! TARGET_PARTIAL_REG_STALL && reload_completed
16674 && ((GET_MODE (operands[0]) == HImode
16675 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16676 /* ??? next two lines just !satisfies_constraint_K (...) */
16677 || !CONST_INT_P (operands[2])
16678 || satisfies_constraint_K (operands[2])))
16679 || (GET_MODE (operands[0]) == QImode
16680 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16681 [(parallel [(set (match_dup 0)
16682 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16683 (clobber (reg:CC FLAGS_REG))])]
16684 "operands[0] = gen_lowpart (SImode, operands[0]);
16685 operands[1] = gen_lowpart (SImode, operands[1]);
16686 if (GET_CODE (operands[3]) != ASHIFT)
16687 operands[2] = gen_lowpart (SImode, operands[2]);
16688 PUT_MODE (operands[3], SImode);")
16690 ; Promote the QImode tests, as i386 has encoding of the AND
16691 ; instruction with 32-bit sign-extended immediate and thus the
16692 ; instruction size is unchanged, except in the %eax case for
16693 ; which it is increased by one byte, hence the ! optimize_size.
16695 [(set (match_operand 0 "flags_reg_operand" "")
16696 (match_operator 2 "compare_operator"
16697 [(and (match_operand 3 "aligned_operand" "")
16698 (match_operand 4 "const_int_operand" ""))
16700 (set (match_operand 1 "register_operand" "")
16701 (and (match_dup 3) (match_dup 4)))]
16702 "! TARGET_PARTIAL_REG_STALL && reload_completed
16703 && optimize_insn_for_speed_p ()
16704 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16705 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16706 /* Ensure that the operand will remain sign-extended immediate. */
16707 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16708 [(parallel [(set (match_dup 0)
16709 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16712 (and:SI (match_dup 3) (match_dup 4)))])]
16715 = gen_int_mode (INTVAL (operands[4])
16716 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16717 operands[1] = gen_lowpart (SImode, operands[1]);
16718 operands[3] = gen_lowpart (SImode, operands[3]);
16721 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16722 ; the TEST instruction with 32-bit sign-extended immediate and thus
16723 ; the instruction size would at least double, which is not what we
16724 ; want even with ! optimize_size.
16726 [(set (match_operand 0 "flags_reg_operand" "")
16727 (match_operator 1 "compare_operator"
16728 [(and (match_operand:HI 2 "aligned_operand" "")
16729 (match_operand:HI 3 "const_int_operand" ""))
16731 "! TARGET_PARTIAL_REG_STALL && reload_completed
16732 && ! TARGET_FAST_PREFIX
16733 && optimize_insn_for_speed_p ()
16734 /* Ensure that the operand will remain sign-extended immediate. */
16735 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16736 [(set (match_dup 0)
16737 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16741 = gen_int_mode (INTVAL (operands[3])
16742 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16743 operands[2] = gen_lowpart (SImode, operands[2]);
16747 [(set (match_operand 0 "register_operand" "")
16748 (neg (match_operand 1 "register_operand" "")))
16749 (clobber (reg:CC FLAGS_REG))]
16750 "! TARGET_PARTIAL_REG_STALL && reload_completed
16751 && (GET_MODE (operands[0]) == HImode
16752 || (GET_MODE (operands[0]) == QImode
16753 && (TARGET_PROMOTE_QImode
16754 || optimize_insn_for_size_p ())))"
16755 [(parallel [(set (match_dup 0)
16756 (neg:SI (match_dup 1)))
16757 (clobber (reg:CC FLAGS_REG))])]
16758 "operands[0] = gen_lowpart (SImode, operands[0]);
16759 operands[1] = gen_lowpart (SImode, operands[1]);")
16762 [(set (match_operand 0 "register_operand" "")
16763 (not (match_operand 1 "register_operand" "")))]
16764 "! TARGET_PARTIAL_REG_STALL && reload_completed
16765 && (GET_MODE (operands[0]) == HImode
16766 || (GET_MODE (operands[0]) == QImode
16767 && (TARGET_PROMOTE_QImode
16768 || optimize_insn_for_size_p ())))"
16769 [(set (match_dup 0)
16770 (not:SI (match_dup 1)))]
16771 "operands[0] = gen_lowpart (SImode, operands[0]);
16772 operands[1] = gen_lowpart (SImode, operands[1]);")
16775 [(set (match_operand 0 "register_operand" "")
16776 (if_then_else (match_operator 1 "ordered_comparison_operator"
16777 [(reg FLAGS_REG) (const_int 0)])
16778 (match_operand 2 "register_operand" "")
16779 (match_operand 3 "register_operand" "")))]
16780 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16781 && (GET_MODE (operands[0]) == HImode
16782 || (GET_MODE (operands[0]) == QImode
16783 && (TARGET_PROMOTE_QImode
16784 || optimize_insn_for_size_p ())))"
16785 [(set (match_dup 0)
16786 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16787 "operands[0] = gen_lowpart (SImode, operands[0]);
16788 operands[2] = gen_lowpart (SImode, operands[2]);
16789 operands[3] = gen_lowpart (SImode, operands[3]);")
16791 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16792 ;; transform a complex memory operation into two memory to register operations.
16794 ;; Don't push memory operands
16796 [(set (match_operand:SWI 0 "push_operand" "")
16797 (match_operand:SWI 1 "memory_operand" ""))
16798 (match_scratch:SWI 2 "<r>")]
16799 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16800 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16801 [(set (match_dup 2) (match_dup 1))
16802 (set (match_dup 0) (match_dup 2))])
16804 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16807 [(set (match_operand:SF 0 "push_operand" "")
16808 (match_operand:SF 1 "memory_operand" ""))
16809 (match_scratch:SF 2 "r")]
16810 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16811 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16812 [(set (match_dup 2) (match_dup 1))
16813 (set (match_dup 0) (match_dup 2))])
16815 ;; Don't move an immediate directly to memory when the instruction
16818 [(match_scratch:SWI124 1 "<r>")
16819 (set (match_operand:SWI124 0 "memory_operand" "")
16821 "optimize_insn_for_speed_p ()
16822 && !TARGET_USE_MOV0
16823 && TARGET_SPLIT_LONG_MOVES
16824 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16825 && peep2_regno_dead_p (0, FLAGS_REG)"
16826 [(parallel [(set (match_dup 2) (const_int 0))
16827 (clobber (reg:CC FLAGS_REG))])
16828 (set (match_dup 0) (match_dup 1))]
16829 "operands[2] = gen_lowpart (SImode, operands[1]);")
16832 [(match_scratch:SWI124 2 "<r>")
16833 (set (match_operand:SWI124 0 "memory_operand" "")
16834 (match_operand:SWI124 1 "immediate_operand" ""))]
16835 "optimize_insn_for_speed_p ()
16836 && TARGET_SPLIT_LONG_MOVES
16837 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16838 [(set (match_dup 2) (match_dup 1))
16839 (set (match_dup 0) (match_dup 2))])
16841 ;; Don't compare memory with zero, load and use a test instead.
16843 [(set (match_operand 0 "flags_reg_operand" "")
16844 (match_operator 1 "compare_operator"
16845 [(match_operand:SI 2 "memory_operand" "")
16847 (match_scratch:SI 3 "r")]
16848 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16849 [(set (match_dup 3) (match_dup 2))
16850 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16852 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16853 ;; Don't split NOTs with a displacement operand, because resulting XOR
16854 ;; will not be pairable anyway.
16856 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16857 ;; represented using a modRM byte. The XOR replacement is long decoded,
16858 ;; so this split helps here as well.
16860 ;; Note: Can't do this as a regular split because we can't get proper
16861 ;; lifetime information then.
16864 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16865 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16866 "optimize_insn_for_speed_p ()
16867 && ((TARGET_NOT_UNPAIRABLE
16868 && (!MEM_P (operands[0])
16869 || !memory_displacement_operand (operands[0], <MODE>mode)))
16870 || (TARGET_NOT_VECTORMODE
16871 && long_memory_operand (operands[0], <MODE>mode)))
16872 && peep2_regno_dead_p (0, FLAGS_REG)"
16873 [(parallel [(set (match_dup 0)
16874 (xor:SWI124 (match_dup 1) (const_int -1)))
16875 (clobber (reg:CC FLAGS_REG))])])
16877 ;; Non pairable "test imm, reg" instructions can be translated to
16878 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16879 ;; byte opcode instead of two, have a short form for byte operands),
16880 ;; so do it for other CPUs as well. Given that the value was dead,
16881 ;; this should not create any new dependencies. Pass on the sub-word
16882 ;; versions if we're concerned about partial register stalls.
16885 [(set (match_operand 0 "flags_reg_operand" "")
16886 (match_operator 1 "compare_operator"
16887 [(and:SI (match_operand:SI 2 "register_operand" "")
16888 (match_operand:SI 3 "immediate_operand" ""))
16890 "ix86_match_ccmode (insn, CCNOmode)
16891 && (true_regnum (operands[2]) != AX_REG
16892 || satisfies_constraint_K (operands[3]))
16893 && peep2_reg_dead_p (1, operands[2])"
16895 [(set (match_dup 0)
16896 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16899 (and:SI (match_dup 2) (match_dup 3)))])])
16901 ;; We don't need to handle HImode case, because it will be promoted to SImode
16902 ;; on ! TARGET_PARTIAL_REG_STALL
16905 [(set (match_operand 0 "flags_reg_operand" "")
16906 (match_operator 1 "compare_operator"
16907 [(and:QI (match_operand:QI 2 "register_operand" "")
16908 (match_operand:QI 3 "immediate_operand" ""))
16910 "! TARGET_PARTIAL_REG_STALL
16911 && ix86_match_ccmode (insn, CCNOmode)
16912 && true_regnum (operands[2]) != AX_REG
16913 && peep2_reg_dead_p (1, operands[2])"
16915 [(set (match_dup 0)
16916 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16919 (and:QI (match_dup 2) (match_dup 3)))])])
16922 [(set (match_operand 0 "flags_reg_operand" "")
16923 (match_operator 1 "compare_operator"
16926 (match_operand 2 "ext_register_operand" "")
16929 (match_operand 3 "const_int_operand" ""))
16931 "! TARGET_PARTIAL_REG_STALL
16932 && ix86_match_ccmode (insn, CCNOmode)
16933 && true_regnum (operands[2]) != AX_REG
16934 && peep2_reg_dead_p (1, operands[2])"
16935 [(parallel [(set (match_dup 0)
16944 (set (zero_extract:SI (match_dup 2)
16952 (match_dup 3)))])])
16954 ;; Don't do logical operations with memory inputs.
16956 [(match_scratch:SI 2 "r")
16957 (parallel [(set (match_operand:SI 0 "register_operand" "")
16958 (match_operator:SI 3 "arith_or_logical_operator"
16960 (match_operand:SI 1 "memory_operand" "")]))
16961 (clobber (reg:CC FLAGS_REG))])]
16962 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16963 [(set (match_dup 2) (match_dup 1))
16964 (parallel [(set (match_dup 0)
16965 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16966 (clobber (reg:CC FLAGS_REG))])])
16969 [(match_scratch:SI 2 "r")
16970 (parallel [(set (match_operand:SI 0 "register_operand" "")
16971 (match_operator:SI 3 "arith_or_logical_operator"
16972 [(match_operand:SI 1 "memory_operand" "")
16974 (clobber (reg:CC FLAGS_REG))])]
16975 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16976 [(set (match_dup 2) (match_dup 1))
16977 (parallel [(set (match_dup 0)
16978 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16979 (clobber (reg:CC FLAGS_REG))])])
16981 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16982 ;; refers to the destination of the load!
16985 [(set (match_operand:SI 0 "register_operand" "")
16986 (match_operand:SI 1 "register_operand" ""))
16987 (parallel [(set (match_dup 0)
16988 (match_operator:SI 3 "commutative_operator"
16990 (match_operand:SI 2 "memory_operand" "")]))
16991 (clobber (reg:CC FLAGS_REG))])]
16992 "REGNO (operands[0]) != REGNO (operands[1])
16993 && GENERAL_REGNO_P (REGNO (operands[0]))
16994 && GENERAL_REGNO_P (REGNO (operands[1]))"
16995 [(set (match_dup 0) (match_dup 4))
16996 (parallel [(set (match_dup 0)
16997 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16998 (clobber (reg:CC FLAGS_REG))])]
16999 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17002 [(set (match_operand 0 "register_operand" "")
17003 (match_operand 1 "register_operand" ""))
17005 (match_operator 3 "commutative_operator"
17007 (match_operand 2 "memory_operand" "")]))]
17008 "REGNO (operands[0]) != REGNO (operands[1])
17009 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17010 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17011 [(set (match_dup 0) (match_dup 2))
17013 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17015 ; Don't do logical operations with memory outputs
17017 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17018 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17019 ; the same decoder scheduling characteristics as the original.
17022 [(match_scratch:SI 2 "r")
17023 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17024 (match_operator:SI 3 "arith_or_logical_operator"
17026 (match_operand:SI 1 "nonmemory_operand" "")]))
17027 (clobber (reg:CC FLAGS_REG))])]
17028 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17029 /* Do not split stack checking probes. */
17030 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17031 [(set (match_dup 2) (match_dup 0))
17032 (parallel [(set (match_dup 2)
17033 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17034 (clobber (reg:CC FLAGS_REG))])
17035 (set (match_dup 0) (match_dup 2))])
17038 [(match_scratch:SI 2 "r")
17039 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17040 (match_operator:SI 3 "arith_or_logical_operator"
17041 [(match_operand:SI 1 "nonmemory_operand" "")
17043 (clobber (reg:CC FLAGS_REG))])]
17044 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17045 /* Do not split stack checking probes. */
17046 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17047 [(set (match_dup 2) (match_dup 0))
17048 (parallel [(set (match_dup 2)
17049 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17050 (clobber (reg:CC FLAGS_REG))])
17051 (set (match_dup 0) (match_dup 2))])
17053 ;; Attempt to always use XOR for zeroing registers.
17055 [(set (match_operand 0 "register_operand" "")
17056 (match_operand 1 "const0_operand" ""))]
17057 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17058 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17059 && GENERAL_REG_P (operands[0])
17060 && peep2_regno_dead_p (0, FLAGS_REG)"
17061 [(parallel [(set (match_dup 0) (const_int 0))
17062 (clobber (reg:CC FLAGS_REG))])]
17063 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17066 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17068 "(GET_MODE (operands[0]) == QImode
17069 || GET_MODE (operands[0]) == HImode)
17070 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17071 && peep2_regno_dead_p (0, FLAGS_REG)"
17072 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17073 (clobber (reg:CC FLAGS_REG))])])
17075 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17077 [(set (match_operand:SWI248 0 "register_operand" "")
17079 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17080 && peep2_regno_dead_p (0, FLAGS_REG)"
17081 [(parallel [(set (match_dup 0) (const_int -1))
17082 (clobber (reg:CC FLAGS_REG))])]
17084 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17085 operands[0] = gen_lowpart (SImode, operands[0]);
17088 ;; Attempt to convert simple lea to add/shift.
17089 ;; These can be created by move expanders.
17092 [(set (match_operand:SWI48 0 "register_operand" "")
17093 (plus:SWI48 (match_dup 0)
17094 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17095 "peep2_regno_dead_p (0, FLAGS_REG)"
17096 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17097 (clobber (reg:CC FLAGS_REG))])])
17100 [(set (match_operand:SI 0 "register_operand" "")
17101 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17102 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17104 && peep2_regno_dead_p (0, FLAGS_REG)
17105 && REGNO (operands[0]) == REGNO (operands[1])"
17106 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17107 (clobber (reg:CC FLAGS_REG))])]
17108 "operands[2] = gen_lowpart (SImode, operands[2]);")
17111 [(set (match_operand:SWI48 0 "register_operand" "")
17112 (mult:SWI48 (match_dup 0)
17113 (match_operand:SWI48 1 "const_int_operand" "")))]
17114 "exact_log2 (INTVAL (operands[1])) >= 0
17115 && peep2_regno_dead_p (0, FLAGS_REG)"
17116 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17117 (clobber (reg:CC FLAGS_REG))])]
17118 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17121 [(set (match_operand:SI 0 "register_operand" "")
17122 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17123 (match_operand:DI 2 "const_int_operand" "")) 0))]
17125 && exact_log2 (INTVAL (operands[2])) >= 0
17126 && REGNO (operands[0]) == REGNO (operands[1])
17127 && peep2_regno_dead_p (0, FLAGS_REG)"
17128 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17129 (clobber (reg:CC FLAGS_REG))])]
17130 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17132 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17133 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17134 ;; On many CPUs it is also faster, since special hardware to avoid esp
17135 ;; dependencies is present.
17137 ;; While some of these conversions may be done using splitters, we use
17138 ;; peepholes in order to allow combine_stack_adjustments pass to see
17139 ;; nonobfuscated RTL.
17141 ;; Convert prologue esp subtractions to push.
17142 ;; We need register to push. In order to keep verify_flow_info happy we have
17144 ;; - use scratch and clobber it in order to avoid dependencies
17145 ;; - use already live register
17146 ;; We can't use the second way right now, since there is no reliable way how to
17147 ;; verify that given register is live. First choice will also most likely in
17148 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17149 ;; call clobbered registers are dead. We may want to use base pointer as an
17150 ;; alternative when no register is available later.
17153 [(match_scratch:P 1 "r")
17154 (parallel [(set (reg:P SP_REG)
17155 (plus:P (reg:P SP_REG)
17156 (match_operand:P 0 "const_int_operand" "")))
17157 (clobber (reg:CC FLAGS_REG))
17158 (clobber (mem:BLK (scratch)))])]
17159 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17160 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17161 [(clobber (match_dup 1))
17162 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17163 (clobber (mem:BLK (scratch)))])])
17166 [(match_scratch:P 1 "r")
17167 (parallel [(set (reg:P SP_REG)
17168 (plus:P (reg:P SP_REG)
17169 (match_operand:P 0 "const_int_operand" "")))
17170 (clobber (reg:CC FLAGS_REG))
17171 (clobber (mem:BLK (scratch)))])]
17172 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17173 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17174 [(clobber (match_dup 1))
17175 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17176 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17177 (clobber (mem:BLK (scratch)))])])
17179 ;; Convert esp subtractions to push.
17181 [(match_scratch:P 1 "r")
17182 (parallel [(set (reg:P SP_REG)
17183 (plus:P (reg:P SP_REG)
17184 (match_operand:P 0 "const_int_operand" "")))
17185 (clobber (reg:CC FLAGS_REG))])]
17186 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17187 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17188 [(clobber (match_dup 1))
17189 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17192 [(match_scratch:P 1 "r")
17193 (parallel [(set (reg:P SP_REG)
17194 (plus:P (reg:P SP_REG)
17195 (match_operand:P 0 "const_int_operand" "")))
17196 (clobber (reg:CC FLAGS_REG))])]
17197 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17198 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17199 [(clobber (match_dup 1))
17200 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17201 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17203 ;; Convert epilogue deallocator to pop.
17205 [(match_scratch:P 1 "r")
17206 (parallel [(set (reg:P SP_REG)
17207 (plus:P (reg:P SP_REG)
17208 (match_operand:P 0 "const_int_operand" "")))
17209 (clobber (reg:CC FLAGS_REG))
17210 (clobber (mem:BLK (scratch)))])]
17211 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17212 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17213 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17214 (clobber (mem:BLK (scratch)))])])
17216 ;; Two pops case is tricky, since pop causes dependency
17217 ;; on destination register. We use two registers if available.
17219 [(match_scratch:P 1 "r")
17220 (match_scratch:P 2 "r")
17221 (parallel [(set (reg:P SP_REG)
17222 (plus:P (reg:P SP_REG)
17223 (match_operand:P 0 "const_int_operand" "")))
17224 (clobber (reg:CC FLAGS_REG))
17225 (clobber (mem:BLK (scratch)))])]
17226 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17227 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17228 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17229 (clobber (mem:BLK (scratch)))])
17230 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17233 [(match_scratch:P 1 "r")
17234 (parallel [(set (reg:P SP_REG)
17235 (plus:P (reg:P SP_REG)
17236 (match_operand:P 0 "const_int_operand" "")))
17237 (clobber (reg:CC FLAGS_REG))
17238 (clobber (mem:BLK (scratch)))])]
17239 "optimize_insn_for_size_p ()
17240 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17241 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17242 (clobber (mem:BLK (scratch)))])
17243 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17245 ;; Convert esp additions to pop.
17247 [(match_scratch:P 1 "r")
17248 (parallel [(set (reg:P SP_REG)
17249 (plus:P (reg:P SP_REG)
17250 (match_operand:P 0 "const_int_operand" "")))
17251 (clobber (reg:CC FLAGS_REG))])]
17252 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17253 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17255 ;; Two pops case is tricky, since pop causes dependency
17256 ;; on destination register. We use two registers if available.
17258 [(match_scratch:P 1 "r")
17259 (match_scratch:P 2 "r")
17260 (parallel [(set (reg:P SP_REG)
17261 (plus:P (reg:P SP_REG)
17262 (match_operand:P 0 "const_int_operand" "")))
17263 (clobber (reg:CC FLAGS_REG))])]
17264 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17265 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17266 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17269 [(match_scratch:P 1 "r")
17270 (parallel [(set (reg:P SP_REG)
17271 (plus:P (reg:P SP_REG)
17272 (match_operand:P 0 "const_int_operand" "")))
17273 (clobber (reg:CC FLAGS_REG))])]
17274 "optimize_insn_for_size_p ()
17275 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17276 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17277 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17279 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17280 ;; required and register dies. Similarly for 128 to -128.
17282 [(set (match_operand 0 "flags_reg_operand" "")
17283 (match_operator 1 "compare_operator"
17284 [(match_operand 2 "register_operand" "")
17285 (match_operand 3 "const_int_operand" "")]))]
17286 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17287 && incdec_operand (operands[3], GET_MODE (operands[3])))
17288 || (!TARGET_FUSE_CMP_AND_BRANCH
17289 && INTVAL (operands[3]) == 128))
17290 && ix86_match_ccmode (insn, CCGCmode)
17291 && peep2_reg_dead_p (1, operands[2])"
17292 [(parallel [(set (match_dup 0)
17293 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17294 (clobber (match_dup 2))])])
17296 ;; Convert imul by three, five and nine into lea
17299 [(set (match_operand:SWI48 0 "register_operand" "")
17300 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17301 (match_operand:SWI48 2 "const_int_operand" "")))
17302 (clobber (reg:CC FLAGS_REG))])]
17303 "INTVAL (operands[2]) == 3
17304 || INTVAL (operands[2]) == 5
17305 || INTVAL (operands[2]) == 9"
17306 [(set (match_dup 0)
17307 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17309 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17313 [(set (match_operand:SWI48 0 "register_operand" "")
17314 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17315 (match_operand:SWI48 2 "const_int_operand" "")))
17316 (clobber (reg:CC FLAGS_REG))])]
17317 "optimize_insn_for_speed_p ()
17318 && (INTVAL (operands[2]) == 3
17319 || INTVAL (operands[2]) == 5
17320 || INTVAL (operands[2]) == 9)"
17321 [(set (match_dup 0) (match_dup 1))
17323 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17325 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17327 ;; imul $32bit_imm, mem, reg is vector decoded, while
17328 ;; imul $32bit_imm, reg, reg is direct decoded.
17330 [(match_scratch:SWI48 3 "r")
17331 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17332 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17333 (match_operand:SWI48 2 "immediate_operand" "")))
17334 (clobber (reg:CC FLAGS_REG))])]
17335 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17336 && !satisfies_constraint_K (operands[2])"
17337 [(set (match_dup 3) (match_dup 1))
17338 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17339 (clobber (reg:CC FLAGS_REG))])])
17342 [(match_scratch:SI 3 "r")
17343 (parallel [(set (match_operand:DI 0 "register_operand" "")
17345 (mult:SI (match_operand:SI 1 "memory_operand" "")
17346 (match_operand:SI 2 "immediate_operand" ""))))
17347 (clobber (reg:CC FLAGS_REG))])]
17349 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17350 && !satisfies_constraint_K (operands[2])"
17351 [(set (match_dup 3) (match_dup 1))
17352 (parallel [(set (match_dup 0)
17353 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17354 (clobber (reg:CC FLAGS_REG))])])
17356 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17357 ;; Convert it into imul reg, reg
17358 ;; It would be better to force assembler to encode instruction using long
17359 ;; immediate, but there is apparently no way to do so.
17361 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17363 (match_operand:SWI248 1 "nonimmediate_operand" "")
17364 (match_operand:SWI248 2 "const_int_operand" "")))
17365 (clobber (reg:CC FLAGS_REG))])
17366 (match_scratch:SWI248 3 "r")]
17367 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17368 && satisfies_constraint_K (operands[2])"
17369 [(set (match_dup 3) (match_dup 2))
17370 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17371 (clobber (reg:CC FLAGS_REG))])]
17373 if (!rtx_equal_p (operands[0], operands[1]))
17374 emit_move_insn (operands[0], operands[1]);
17377 ;; After splitting up read-modify operations, array accesses with memory
17378 ;; operands might end up in form:
17380 ;; movl 4(%esp), %edx
17382 ;; instead of pre-splitting:
17384 ;; addl 4(%esp), %eax
17386 ;; movl 4(%esp), %edx
17387 ;; leal (%edx,%eax,4), %eax
17390 [(match_scratch:P 5 "r")
17391 (parallel [(set (match_operand 0 "register_operand" "")
17392 (ashift (match_operand 1 "register_operand" "")
17393 (match_operand 2 "const_int_operand" "")))
17394 (clobber (reg:CC FLAGS_REG))])
17395 (parallel [(set (match_operand 3 "register_operand" "")
17396 (plus (match_dup 0)
17397 (match_operand 4 "x86_64_general_operand" "")))
17398 (clobber (reg:CC FLAGS_REG))])]
17399 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17400 /* Validate MODE for lea. */
17401 && ((!TARGET_PARTIAL_REG_STALL
17402 && (GET_MODE (operands[0]) == QImode
17403 || GET_MODE (operands[0]) == HImode))
17404 || GET_MODE (operands[0]) == SImode
17405 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17406 && (rtx_equal_p (operands[0], operands[3])
17407 || peep2_reg_dead_p (2, operands[0]))
17408 /* We reorder load and the shift. */
17409 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17410 [(set (match_dup 5) (match_dup 4))
17411 (set (match_dup 0) (match_dup 1))]
17413 enum machine_mode op1mode = GET_MODE (operands[1]);
17414 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17415 int scale = 1 << INTVAL (operands[2]);
17416 rtx index = gen_lowpart (Pmode, operands[1]);
17417 rtx base = gen_lowpart (Pmode, operands[5]);
17418 rtx dest = gen_lowpart (mode, operands[3]);
17420 operands[1] = gen_rtx_PLUS (Pmode, base,
17421 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17422 operands[5] = base;
17424 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17425 if (op1mode != Pmode)
17426 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17427 operands[0] = dest;
17430 ;; Call-value patterns last so that the wildcard operand does not
17431 ;; disrupt insn-recog's switch tables.
17433 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17435 [(set (match_operand 0 "" "")
17436 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17437 (match_operand:SI 2 "" "")))
17438 (set (reg:SI SP_REG)
17439 (plus:SI (reg:SI SP_REG)
17440 (match_operand:SI 3 "immediate_operand" "")))])
17441 (unspec [(match_operand 4 "const_int_operand" "")]
17442 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17443 "TARGET_VZEROUPPER && !TARGET_64BIT"
17445 "&& reload_completed"
17447 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17448 [(set_attr "type" "callv")])
17450 (define_insn "*call_value_pop_0"
17451 [(set (match_operand 0 "" "")
17452 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17453 (match_operand:SI 2 "" "")))
17454 (set (reg:SI SP_REG)
17455 (plus:SI (reg:SI SP_REG)
17456 (match_operand:SI 3 "immediate_operand" "")))]
17458 { return ix86_output_call_insn (insn, operands[1], 1); }
17459 [(set_attr "type" "callv")])
17461 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17463 [(set (match_operand 0 "" "")
17464 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17465 (match_operand:SI 2 "" "")))
17466 (set (reg:SI SP_REG)
17467 (plus:SI (reg:SI SP_REG)
17468 (match_operand:SI 3 "immediate_operand" "i")))])
17469 (unspec [(match_operand 4 "const_int_operand" "")]
17470 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17471 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17473 "&& reload_completed"
17475 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17476 [(set_attr "type" "callv")])
17478 (define_insn "*call_value_pop_1"
17479 [(set (match_operand 0 "" "")
17480 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17481 (match_operand:SI 2 "" "")))
17482 (set (reg:SI SP_REG)
17483 (plus:SI (reg:SI SP_REG)
17484 (match_operand:SI 3 "immediate_operand" "i")))]
17485 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17486 { return ix86_output_call_insn (insn, operands[1], 1); }
17487 [(set_attr "type" "callv")])
17489 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17491 [(set (match_operand 0 "" "")
17492 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17493 (match_operand:SI 2 "" "")))
17494 (set (reg:SI SP_REG)
17495 (plus:SI (reg:SI SP_REG)
17496 (match_operand:SI 3 "immediate_operand" "i,i")))])
17497 (unspec [(match_operand 4 "const_int_operand" "")]
17498 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17499 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17501 "&& reload_completed"
17503 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17504 [(set_attr "type" "callv")])
17506 (define_insn "*sibcall_value_pop_1"
17507 [(set (match_operand 0 "" "")
17508 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17509 (match_operand:SI 2 "" "")))
17510 (set (reg:SI SP_REG)
17511 (plus:SI (reg:SI SP_REG)
17512 (match_operand:SI 3 "immediate_operand" "i,i")))]
17513 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17514 { return ix86_output_call_insn (insn, operands[1], 1); }
17515 [(set_attr "type" "callv")])
17517 (define_insn_and_split "*call_value_0_vzeroupper"
17518 [(set (match_operand 0 "" "")
17519 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17520 (match_operand:SI 2 "" "")))
17521 (unspec [(match_operand 3 "const_int_operand" "")]
17522 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17523 "TARGET_VZEROUPPER && !TARGET_64BIT"
17525 "&& reload_completed"
17527 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17528 [(set_attr "type" "callv")])
17530 (define_insn "*call_value_0"
17531 [(set (match_operand 0 "" "")
17532 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17533 (match_operand:SI 2 "" "")))]
17535 { return ix86_output_call_insn (insn, operands[1], 1); }
17536 [(set_attr "type" "callv")])
17538 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17539 [(set (match_operand 0 "" "")
17540 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17541 (match_operand:DI 2 "const_int_operand" "")))
17542 (unspec [(match_operand 3 "const_int_operand" "")]
17543 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17544 "TARGET_VZEROUPPER && TARGET_64BIT"
17546 "&& reload_completed"
17548 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17549 [(set_attr "type" "callv")])
17551 (define_insn "*call_value_0_rex64"
17552 [(set (match_operand 0 "" "")
17553 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17554 (match_operand:DI 2 "const_int_operand" "")))]
17556 { return ix86_output_call_insn (insn, operands[1], 1); }
17557 [(set_attr "type" "callv")])
17559 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17561 [(set (match_operand 0 "" "")
17562 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17563 (match_operand:DI 2 "const_int_operand" "")))
17564 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17565 (clobber (reg:TI XMM6_REG))
17566 (clobber (reg:TI XMM7_REG))
17567 (clobber (reg:TI XMM8_REG))
17568 (clobber (reg:TI XMM9_REG))
17569 (clobber (reg:TI XMM10_REG))
17570 (clobber (reg:TI XMM11_REG))
17571 (clobber (reg:TI XMM12_REG))
17572 (clobber (reg:TI XMM13_REG))
17573 (clobber (reg:TI XMM14_REG))
17574 (clobber (reg:TI XMM15_REG))
17575 (clobber (reg:DI SI_REG))
17576 (clobber (reg:DI DI_REG))])
17577 (unspec [(match_operand 3 "const_int_operand" "")]
17578 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17579 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17581 "&& reload_completed"
17583 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17584 [(set_attr "type" "callv")])
17586 (define_insn "*call_value_0_rex64_ms_sysv"
17587 [(set (match_operand 0 "" "")
17588 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17589 (match_operand:DI 2 "const_int_operand" "")))
17590 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17591 (clobber (reg:TI XMM6_REG))
17592 (clobber (reg:TI XMM7_REG))
17593 (clobber (reg:TI XMM8_REG))
17594 (clobber (reg:TI XMM9_REG))
17595 (clobber (reg:TI XMM10_REG))
17596 (clobber (reg:TI XMM11_REG))
17597 (clobber (reg:TI XMM12_REG))
17598 (clobber (reg:TI XMM13_REG))
17599 (clobber (reg:TI XMM14_REG))
17600 (clobber (reg:TI XMM15_REG))
17601 (clobber (reg:DI SI_REG))
17602 (clobber (reg:DI DI_REG))]
17603 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17604 { return ix86_output_call_insn (insn, operands[1], 1); }
17605 [(set_attr "type" "callv")])
17607 (define_insn_and_split "*call_value_1_vzeroupper"
17608 [(set (match_operand 0 "" "")
17609 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17610 (match_operand:SI 2 "" "")))
17611 (unspec [(match_operand 3 "const_int_operand" "")]
17612 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17613 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17615 "&& reload_completed"
17617 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17618 [(set_attr "type" "callv")])
17620 (define_insn "*call_value_1"
17621 [(set (match_operand 0 "" "")
17622 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17623 (match_operand:SI 2 "" "")))]
17624 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17625 { return ix86_output_call_insn (insn, operands[1], 1); }
17626 [(set_attr "type" "callv")])
17628 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17629 [(set (match_operand 0 "" "")
17630 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17631 (match_operand:SI 2 "" "")))
17632 (unspec [(match_operand 3 "const_int_operand" "")]
17633 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17634 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17636 "&& reload_completed"
17638 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17639 [(set_attr "type" "callv")])
17641 (define_insn "*sibcall_value_1"
17642 [(set (match_operand 0 "" "")
17643 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17644 (match_operand:SI 2 "" "")))]
17645 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17646 { return ix86_output_call_insn (insn, operands[1], 1); }
17647 [(set_attr "type" "callv")])
17649 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17650 [(set (match_operand 0 "" "")
17651 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17652 (match_operand:DI 2 "" "")))
17653 (unspec [(match_operand 3 "const_int_operand" "")]
17654 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17655 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17656 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17658 "&& reload_completed"
17660 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17661 [(set_attr "type" "callv")])
17663 (define_insn "*call_value_1_rex64"
17664 [(set (match_operand 0 "" "")
17665 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17666 (match_operand:DI 2 "" "")))]
17667 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17668 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17669 { return ix86_output_call_insn (insn, operands[1], 1); }
17670 [(set_attr "type" "callv")])
17672 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17674 [(set (match_operand 0 "" "")
17675 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17676 (match_operand:DI 2 "" "")))
17677 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17678 (clobber (reg:TI XMM6_REG))
17679 (clobber (reg:TI XMM7_REG))
17680 (clobber (reg:TI XMM8_REG))
17681 (clobber (reg:TI XMM9_REG))
17682 (clobber (reg:TI XMM10_REG))
17683 (clobber (reg:TI XMM11_REG))
17684 (clobber (reg:TI XMM12_REG))
17685 (clobber (reg:TI XMM13_REG))
17686 (clobber (reg:TI XMM14_REG))
17687 (clobber (reg:TI XMM15_REG))
17688 (clobber (reg:DI SI_REG))
17689 (clobber (reg:DI DI_REG))])
17690 (unspec [(match_operand 3 "const_int_operand" "")]
17691 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17692 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17694 "&& reload_completed"
17696 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17697 [(set_attr "type" "callv")])
17699 (define_insn "*call_value_1_rex64_ms_sysv"
17700 [(set (match_operand 0 "" "")
17701 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17702 (match_operand:DI 2 "" "")))
17703 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17704 (clobber (reg:TI XMM6_REG))
17705 (clobber (reg:TI XMM7_REG))
17706 (clobber (reg:TI XMM8_REG))
17707 (clobber (reg:TI XMM9_REG))
17708 (clobber (reg:TI XMM10_REG))
17709 (clobber (reg:TI XMM11_REG))
17710 (clobber (reg:TI XMM12_REG))
17711 (clobber (reg:TI XMM13_REG))
17712 (clobber (reg:TI XMM14_REG))
17713 (clobber (reg:TI XMM15_REG))
17714 (clobber (reg:DI SI_REG))
17715 (clobber (reg:DI DI_REG))]
17716 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17717 { return ix86_output_call_insn (insn, operands[1], 1); }
17718 [(set_attr "type" "callv")])
17720 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17721 [(set (match_operand 0 "" "")
17722 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17723 (match_operand:DI 2 "" "")))
17724 (unspec [(match_operand 3 "const_int_operand" "")]
17725 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17726 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17728 "&& reload_completed"
17730 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17731 [(set_attr "type" "callv")])
17733 (define_insn "*call_value_1_rex64_large"
17734 [(set (match_operand 0 "" "")
17735 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17736 (match_operand:DI 2 "" "")))]
17737 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17738 { return ix86_output_call_insn (insn, operands[1], 1); }
17739 [(set_attr "type" "callv")])
17741 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17742 [(set (match_operand 0 "" "")
17743 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17744 (match_operand:DI 2 "" "")))
17745 (unspec [(match_operand 3 "const_int_operand" "")]
17746 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17747 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17749 "&& reload_completed"
17751 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17752 [(set_attr "type" "callv")])
17754 (define_insn "*sibcall_value_1_rex64"
17755 [(set (match_operand 0 "" "")
17756 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17757 (match_operand:DI 2 "" "")))]
17758 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17759 { return ix86_output_call_insn (insn, operands[1], 1); }
17760 [(set_attr "type" "callv")])
17762 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17763 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17764 ;; caught for use by garbage collectors and the like. Using an insn that
17765 ;; maps to SIGILL makes it more likely the program will rightfully die.
17766 ;; Keeping with tradition, "6" is in honor of #UD.
17767 (define_insn "trap"
17768 [(trap_if (const_int 1) (const_int 6))]
17770 { return ASM_SHORT "0x0b0f"; }
17771 [(set_attr "length" "2")])
17773 (define_expand "prefetch"
17774 [(prefetch (match_operand 0 "address_operand" "")
17775 (match_operand:SI 1 "const_int_operand" "")
17776 (match_operand:SI 2 "const_int_operand" ""))]
17777 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17779 int rw = INTVAL (operands[1]);
17780 int locality = INTVAL (operands[2]);
17782 gcc_assert (rw == 0 || rw == 1);
17783 gcc_assert (locality >= 0 && locality <= 3);
17784 gcc_assert (GET_MODE (operands[0]) == Pmode
17785 || GET_MODE (operands[0]) == VOIDmode);
17787 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17788 supported by SSE counterpart or the SSE prefetch is not available
17789 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17791 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17792 operands[2] = GEN_INT (3);
17794 operands[1] = const0_rtx;
17797 (define_insn "*prefetch_sse_<mode>"
17798 [(prefetch (match_operand:P 0 "address_operand" "p")
17800 (match_operand:SI 1 "const_int_operand" ""))]
17801 "TARGET_PREFETCH_SSE"
17803 static const char * const patterns[4] = {
17804 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17807 int locality = INTVAL (operands[1]);
17808 gcc_assert (locality >= 0 && locality <= 3);
17810 return patterns[locality];
17812 [(set_attr "type" "sse")
17813 (set_attr "atom_sse_attr" "prefetch")
17814 (set (attr "length_address")
17815 (symbol_ref "memory_address_length (operands[0])"))
17816 (set_attr "memory" "none")])
17818 (define_insn "*prefetch_3dnow_<mode>"
17819 [(prefetch (match_operand:P 0 "address_operand" "p")
17820 (match_operand:SI 1 "const_int_operand" "n")
17824 if (INTVAL (operands[1]) == 0)
17825 return "prefetch\t%a0";
17827 return "prefetchw\t%a0";
17829 [(set_attr "type" "mmx")
17830 (set (attr "length_address")
17831 (symbol_ref "memory_address_length (operands[0])"))
17832 (set_attr "memory" "none")])
17834 (define_expand "stack_protect_set"
17835 [(match_operand 0 "memory_operand" "")
17836 (match_operand 1 "memory_operand" "")]
17839 rtx (*insn)(rtx, rtx);
17841 #ifdef TARGET_THREAD_SSP_OFFSET
17842 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17843 insn = (TARGET_64BIT
17844 ? gen_stack_tls_protect_set_di
17845 : gen_stack_tls_protect_set_si);
17847 insn = (TARGET_64BIT
17848 ? gen_stack_protect_set_di
17849 : gen_stack_protect_set_si);
17852 emit_insn (insn (operands[0], operands[1]));
17856 (define_insn "stack_protect_set_<mode>"
17857 [(set (match_operand:P 0 "memory_operand" "=m")
17858 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17859 (set (match_scratch:P 2 "=&r") (const_int 0))
17860 (clobber (reg:CC FLAGS_REG))]
17862 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17863 [(set_attr "type" "multi")])
17865 (define_insn "stack_tls_protect_set_<mode>"
17866 [(set (match_operand:P 0 "memory_operand" "=m")
17867 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17868 UNSPEC_SP_TLS_SET))
17869 (set (match_scratch:P 2 "=&r") (const_int 0))
17870 (clobber (reg:CC FLAGS_REG))]
17872 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17873 [(set_attr "type" "multi")])
17875 (define_expand "stack_protect_test"
17876 [(match_operand 0 "memory_operand" "")
17877 (match_operand 1 "memory_operand" "")
17878 (match_operand 2 "" "")]
17881 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17883 rtx (*insn)(rtx, rtx, rtx);
17885 #ifdef TARGET_THREAD_SSP_OFFSET
17886 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17887 insn = (TARGET_64BIT
17888 ? gen_stack_tls_protect_test_di
17889 : gen_stack_tls_protect_test_si);
17891 insn = (TARGET_64BIT
17892 ? gen_stack_protect_test_di
17893 : gen_stack_protect_test_si);
17896 emit_insn (insn (flags, operands[0], operands[1]));
17898 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17899 flags, const0_rtx, operands[2]));
17903 (define_insn "stack_protect_test_<mode>"
17904 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17905 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17906 (match_operand:P 2 "memory_operand" "m")]
17908 (clobber (match_scratch:P 3 "=&r"))]
17910 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17911 [(set_attr "type" "multi")])
17913 (define_insn "stack_tls_protect_test_<mode>"
17914 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17915 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17916 (match_operand:P 2 "const_int_operand" "i")]
17917 UNSPEC_SP_TLS_TEST))
17918 (clobber (match_scratch:P 3 "=r"))]
17920 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17921 [(set_attr "type" "multi")])
17923 (define_insn "sse4_2_crc32<mode>"
17924 [(set (match_operand:SI 0 "register_operand" "=r")
17926 [(match_operand:SI 1 "register_operand" "0")
17927 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17929 "TARGET_SSE4_2 || TARGET_CRC32"
17930 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17931 [(set_attr "type" "sselog1")
17932 (set_attr "prefix_rep" "1")
17933 (set_attr "prefix_extra" "1")
17934 (set (attr "prefix_data16")
17935 (if_then_else (match_operand:HI 2 "" "")
17937 (const_string "*")))
17938 (set (attr "prefix_rex")
17939 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17941 (const_string "*")))
17942 (set_attr "mode" "SI")])
17944 (define_insn "sse4_2_crc32di"
17945 [(set (match_operand:DI 0 "register_operand" "=r")
17947 [(match_operand:DI 1 "register_operand" "0")
17948 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17950 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17951 "crc32{q}\t{%2, %0|%0, %2}"
17952 [(set_attr "type" "sselog1")
17953 (set_attr "prefix_rep" "1")
17954 (set_attr "prefix_extra" "1")
17955 (set_attr "mode" "DI")])
17957 (define_expand "rdpmc"
17958 [(match_operand:DI 0 "register_operand" "")
17959 (match_operand:SI 1 "register_operand" "")]
17962 rtx reg = gen_reg_rtx (DImode);
17965 /* Force operand 1 into ECX. */
17966 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17967 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17968 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17973 rtvec vec = rtvec_alloc (2);
17974 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17975 rtx upper = gen_reg_rtx (DImode);
17976 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17977 gen_rtvec (1, const0_rtx),
17979 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17980 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17982 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17983 NULL, 1, OPTAB_DIRECT);
17984 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17988 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17989 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17993 (define_insn "*rdpmc"
17994 [(set (match_operand:DI 0 "register_operand" "=A")
17995 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17999 [(set_attr "type" "other")
18000 (set_attr "length" "2")])
18002 (define_insn "*rdpmc_rex64"
18003 [(set (match_operand:DI 0 "register_operand" "=a")
18004 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18006 (set (match_operand:DI 1 "register_operand" "=d")
18007 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18010 [(set_attr "type" "other")
18011 (set_attr "length" "2")])
18013 (define_expand "rdtsc"
18014 [(set (match_operand:DI 0 "register_operand" "")
18015 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18020 rtvec vec = rtvec_alloc (2);
18021 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18022 rtx upper = gen_reg_rtx (DImode);
18023 rtx lower = gen_reg_rtx (DImode);
18024 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18025 gen_rtvec (1, const0_rtx),
18027 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18028 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18030 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18031 NULL, 1, OPTAB_DIRECT);
18032 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18034 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18039 (define_insn "*rdtsc"
18040 [(set (match_operand:DI 0 "register_operand" "=A")
18041 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18044 [(set_attr "type" "other")
18045 (set_attr "length" "2")])
18047 (define_insn "*rdtsc_rex64"
18048 [(set (match_operand:DI 0 "register_operand" "=a")
18049 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18050 (set (match_operand:DI 1 "register_operand" "=d")
18051 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18054 [(set_attr "type" "other")
18055 (set_attr "length" "2")])
18057 (define_expand "rdtscp"
18058 [(match_operand:DI 0 "register_operand" "")
18059 (match_operand:SI 1 "memory_operand" "")]
18062 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18063 gen_rtvec (1, const0_rtx),
18065 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18066 gen_rtvec (1, const0_rtx),
18068 rtx reg = gen_reg_rtx (DImode);
18069 rtx tmp = gen_reg_rtx (SImode);
18073 rtvec vec = rtvec_alloc (3);
18074 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18075 rtx upper = gen_reg_rtx (DImode);
18076 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18077 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18078 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18080 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18081 NULL, 1, OPTAB_DIRECT);
18082 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18087 rtvec vec = rtvec_alloc (2);
18088 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18089 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18090 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18093 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18094 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18098 (define_insn "*rdtscp"
18099 [(set (match_operand:DI 0 "register_operand" "=A")
18100 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18101 (set (match_operand:SI 1 "register_operand" "=c")
18102 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18105 [(set_attr "type" "other")
18106 (set_attr "length" "3")])
18108 (define_insn "*rdtscp_rex64"
18109 [(set (match_operand:DI 0 "register_operand" "=a")
18110 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18111 (set (match_operand:DI 1 "register_operand" "=d")
18112 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18113 (set (match_operand:SI 2 "register_operand" "=c")
18114 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18117 [(set_attr "type" "other")
18118 (set_attr "length" "3")])
18120 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18122 ;; LWP instructions
18124 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18126 (define_expand "lwp_llwpcb"
18127 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18128 UNSPECV_LLWP_INTRINSIC)]
18131 (define_insn "*lwp_llwpcb<mode>1"
18132 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18133 UNSPECV_LLWP_INTRINSIC)]
18136 [(set_attr "type" "lwp")
18137 (set_attr "mode" "<MODE>")
18138 (set_attr "length" "5")])
18140 (define_expand "lwp_slwpcb"
18141 [(set (match_operand 0 "register_operand" "=r")
18142 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18147 insn = (TARGET_64BIT
18149 : gen_lwp_slwpcbsi);
18151 emit_insn (insn (operands[0]));
18155 (define_insn "lwp_slwpcb<mode>"
18156 [(set (match_operand:P 0 "register_operand" "=r")
18157 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18160 [(set_attr "type" "lwp")
18161 (set_attr "mode" "<MODE>")
18162 (set_attr "length" "5")])
18164 (define_expand "lwp_lwpval<mode>3"
18165 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18166 (match_operand:SI 2 "nonimmediate_operand" "rm")
18167 (match_operand:SI 3 "const_int_operand" "i")]
18168 UNSPECV_LWPVAL_INTRINSIC)]
18170 "/* Avoid unused variable warning. */
18173 (define_insn "*lwp_lwpval<mode>3_1"
18174 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18175 (match_operand:SI 1 "nonimmediate_operand" "rm")
18176 (match_operand:SI 2 "const_int_operand" "i")]
18177 UNSPECV_LWPVAL_INTRINSIC)]
18179 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18180 [(set_attr "type" "lwp")
18181 (set_attr "mode" "<MODE>")
18182 (set (attr "length")
18183 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18185 (define_expand "lwp_lwpins<mode>3"
18186 [(set (reg:CCC FLAGS_REG)
18187 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18188 (match_operand:SI 2 "nonimmediate_operand" "rm")
18189 (match_operand:SI 3 "const_int_operand" "i")]
18190 UNSPECV_LWPINS_INTRINSIC))
18191 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18192 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18195 (define_insn "*lwp_lwpins<mode>3_1"
18196 [(set (reg:CCC FLAGS_REG)
18197 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18198 (match_operand:SI 1 "nonimmediate_operand" "rm")
18199 (match_operand:SI 2 "const_int_operand" "i")]
18200 UNSPECV_LWPINS_INTRINSIC))]
18202 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18203 [(set_attr "type" "lwp")
18204 (set_attr "mode" "<MODE>")
18205 (set (attr "length")
18206 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18208 (define_insn "rdfsbase<mode>"
18209 [(set (match_operand:SWI48 0 "register_operand" "=r")
18210 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18211 "TARGET_64BIT && TARGET_FSGSBASE"
18213 [(set_attr "type" "other")
18214 (set_attr "prefix_extra" "2")])
18216 (define_insn "rdgsbase<mode>"
18217 [(set (match_operand:SWI48 0 "register_operand" "=r")
18218 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18219 "TARGET_64BIT && TARGET_FSGSBASE"
18221 [(set_attr "type" "other")
18222 (set_attr "prefix_extra" "2")])
18224 (define_insn "wrfsbase<mode>"
18225 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18227 "TARGET_64BIT && TARGET_FSGSBASE"
18229 [(set_attr "type" "other")
18230 (set_attr "prefix_extra" "2")])
18232 (define_insn "wrgsbase<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 "rdrand<mode>_1"
18241 [(set (match_operand:SWI248 0 "register_operand" "=r")
18242 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18243 (set (reg:CCC FLAGS_REG)
18244 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18247 [(set_attr "type" "other")
18248 (set_attr "prefix_extra" "1")])
18252 (include "sync.md")