1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
110 UNSPEC_CALL_NEEDS_VZEROUPPER
112 ;; For SSE/MMX support:
130 UNSPEC_MS_TO_SYSV_CALL
132 ;; Generic math support
134 UNSPEC_IEEE_MIN ; not commutative
135 UNSPEC_IEEE_MAX ; not commutative
137 ;; x87 Floating point
153 UNSPEC_FRNDINT_MASK_PM
157 ;; x87 Double output FP
189 ;; For SSE4.1 support
199 ;; For SSE4.2 support
206 UNSPEC_XOP_UNSIGNED_CMP
217 UNSPEC_AESKEYGENASSIST
219 ;; For PCLMUL support
235 ;; For RDRAND support
239 (define_c_enum "unspecv" [
242 UNSPECV_PROBE_STACK_RANGE
262 UNSPECV_LLWP_INTRINSIC
263 UNSPECV_SLWP_INTRINSIC
264 UNSPECV_LWPVAL_INTRINSIC
265 UNSPECV_LWPINS_INTRINSIC
270 UNSPECV_SPLIT_STACK_RETURN
273 ;; Constants to represent rounding modes in the ROUND instruction
282 ;; Constants to represent pcomtrue/pcomfalse variants
292 ;; Constants used in the XOP pperm instruction
294 [(PPERM_SRC 0x00) /* copy source */
295 (PPERM_INVERT 0x20) /* invert source */
296 (PPERM_REVERSE 0x40) /* bit reverse source */
297 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
298 (PPERM_ZERO 0x80) /* all 0's */
299 (PPERM_ONES 0xa0) /* all 1's */
300 (PPERM_SIGN 0xc0) /* propagate sign bit */
301 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
302 (PPERM_SRC1 0x00) /* use first source byte */
303 (PPERM_SRC2 0x10) /* use second source byte */
306 ;; Registers by name.
359 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
362 ;; In C guard expressions, put expressions which may be compile-time
363 ;; constants first. This allows for better optimization. For
364 ;; example, write "TARGET_64BIT && reload_completed", not
365 ;; "reload_completed && TARGET_64BIT".
369 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
370 atom,generic64,amdfam10,bdver1,btver1"
371 (const (symbol_ref "ix86_schedule")))
373 ;; A basic instruction type. Refinements due to arguments to be
374 ;; provided in other attributes.
377 alu,alu1,negnot,imov,imovx,lea,
378 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
379 icmp,test,ibr,setcc,icmov,
380 push,pop,call,callv,leave,
382 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
383 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
384 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
385 ssemuladd,sse4arg,lwp,
386 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
387 (const_string "other"))
389 ;; Main data type used by the insn
391 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
392 (const_string "unknown"))
394 ;; The CPU unit operations uses.
395 (define_attr "unit" "integer,i387,sse,mmx,unknown"
396 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
397 (const_string "i387")
398 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
399 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
400 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
402 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
404 (eq_attr "type" "other")
405 (const_string "unknown")]
406 (const_string "integer")))
408 ;; The (bounding maximum) length of an instruction immediate.
409 (define_attr "length_immediate" ""
410 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
413 (eq_attr "unit" "i387,sse,mmx")
415 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
417 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
418 (eq_attr "type" "imov,test")
419 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
420 (eq_attr "type" "call")
421 (if_then_else (match_operand 0 "constant_call_address_operand" "")
424 (eq_attr "type" "callv")
425 (if_then_else (match_operand 1 "constant_call_address_operand" "")
428 ;; We don't know the size before shorten_branches. Expect
429 ;; the instruction to fit for better scheduling.
430 (eq_attr "type" "ibr")
433 (symbol_ref "/* Update immediate_length and other attributes! */
434 gcc_unreachable (),1")))
436 ;; The (bounding maximum) length of an instruction address.
437 (define_attr "length_address" ""
438 (cond [(eq_attr "type" "str,other,multi,fxch")
440 (and (eq_attr "type" "call")
441 (match_operand 0 "constant_call_address_operand" ""))
443 (and (eq_attr "type" "callv")
444 (match_operand 1 "constant_call_address_operand" ""))
447 (symbol_ref "ix86_attr_length_address_default (insn)")))
449 ;; Set when length prefix is used.
450 (define_attr "prefix_data16" ""
451 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
453 (eq_attr "mode" "HI")
455 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
460 ;; Set when string REP prefix is used.
461 (define_attr "prefix_rep" ""
462 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
464 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
469 ;; Set when 0f opcode prefix is used.
470 (define_attr "prefix_0f" ""
472 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
473 (eq_attr "unit" "sse,mmx"))
477 ;; Set when REX opcode prefix is used.
478 (define_attr "prefix_rex" ""
479 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
481 (and (eq_attr "mode" "DI")
482 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
483 (eq_attr "unit" "!mmx")))
485 (and (eq_attr "mode" "QI")
486 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
489 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
492 (and (eq_attr "type" "imovx")
493 (match_operand:QI 1 "ext_QIreg_operand" ""))
498 ;; There are also additional prefixes in 3DNOW, SSSE3.
499 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
500 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
501 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
502 (define_attr "prefix_extra" ""
503 (cond [(eq_attr "type" "ssemuladd,sse4arg")
505 (eq_attr "type" "sseiadd1,ssecvt1")
510 ;; Prefix used: original, VEX or maybe VEX.
511 (define_attr "prefix" "orig,vex,maybe_vex"
512 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
514 (const_string "orig")))
516 ;; VEX W bit is used.
517 (define_attr "prefix_vex_w" "" (const_int 0))
519 ;; The length of VEX prefix
520 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
521 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
522 ;; still prefix_0f 1, with prefix_extra 1.
523 (define_attr "length_vex" ""
524 (if_then_else (and (eq_attr "prefix_0f" "1")
525 (eq_attr "prefix_extra" "0"))
526 (if_then_else (eq_attr "prefix_vex_w" "1")
527 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
528 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
529 (if_then_else (eq_attr "prefix_vex_w" "1")
530 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
531 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
533 ;; Set when modrm byte is used.
534 (define_attr "modrm" ""
535 (cond [(eq_attr "type" "str,leave")
537 (eq_attr "unit" "i387")
539 (and (eq_attr "type" "incdec")
540 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
541 (ior (match_operand:SI 1 "register_operand" "")
542 (match_operand:HI 1 "register_operand" ""))))
544 (and (eq_attr "type" "push")
545 (not (match_operand 1 "memory_operand" "")))
547 (and (eq_attr "type" "pop")
548 (not (match_operand 0 "memory_operand" "")))
550 (and (eq_attr "type" "imov")
551 (and (not (eq_attr "mode" "DI"))
552 (ior (and (match_operand 0 "register_operand" "")
553 (match_operand 1 "immediate_operand" ""))
554 (ior (and (match_operand 0 "ax_reg_operand" "")
555 (match_operand 1 "memory_displacement_only_operand" ""))
556 (and (match_operand 0 "memory_displacement_only_operand" "")
557 (match_operand 1 "ax_reg_operand" ""))))))
559 (and (eq_attr "type" "call")
560 (match_operand 0 "constant_call_address_operand" ""))
562 (and (eq_attr "type" "callv")
563 (match_operand 1 "constant_call_address_operand" ""))
565 (and (eq_attr "type" "alu,alu1,icmp,test")
566 (match_operand 0 "ax_reg_operand" ""))
567 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
571 ;; The (bounding maximum) length of an instruction in bytes.
572 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
573 ;; Later we may want to split them and compute proper length as for
575 (define_attr "length" ""
576 (cond [(eq_attr "type" "other,multi,fistp,frndint")
578 (eq_attr "type" "fcmp")
580 (eq_attr "unit" "i387")
582 (plus (attr "prefix_data16")
583 (attr "length_address")))
584 (ior (eq_attr "prefix" "vex")
585 (and (eq_attr "prefix" "maybe_vex")
586 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
587 (plus (attr "length_vex")
588 (plus (attr "length_immediate")
590 (attr "length_address"))))]
591 (plus (plus (attr "modrm")
592 (plus (attr "prefix_0f")
593 (plus (attr "prefix_rex")
594 (plus (attr "prefix_extra")
596 (plus (attr "prefix_rep")
597 (plus (attr "prefix_data16")
598 (plus (attr "length_immediate")
599 (attr "length_address")))))))
601 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
602 ;; `store' if there is a simple memory reference therein, or `unknown'
603 ;; if the instruction is complex.
605 (define_attr "memory" "none,load,store,both,unknown"
606 (cond [(eq_attr "type" "other,multi,str,lwp")
607 (const_string "unknown")
608 (eq_attr "type" "lea,fcmov,fpspc")
609 (const_string "none")
610 (eq_attr "type" "fistp,leave")
611 (const_string "both")
612 (eq_attr "type" "frndint")
613 (const_string "load")
614 (eq_attr "type" "push")
615 (if_then_else (match_operand 1 "memory_operand" "")
616 (const_string "both")
617 (const_string "store"))
618 (eq_attr "type" "pop")
619 (if_then_else (match_operand 0 "memory_operand" "")
620 (const_string "both")
621 (const_string "load"))
622 (eq_attr "type" "setcc")
623 (if_then_else (match_operand 0 "memory_operand" "")
624 (const_string "store")
625 (const_string "none"))
626 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
627 (if_then_else (ior (match_operand 0 "memory_operand" "")
628 (match_operand 1 "memory_operand" ""))
629 (const_string "load")
630 (const_string "none"))
631 (eq_attr "type" "ibr")
632 (if_then_else (match_operand 0 "memory_operand" "")
633 (const_string "load")
634 (const_string "none"))
635 (eq_attr "type" "call")
636 (if_then_else (match_operand 0 "constant_call_address_operand" "")
637 (const_string "none")
638 (const_string "load"))
639 (eq_attr "type" "callv")
640 (if_then_else (match_operand 1 "constant_call_address_operand" "")
641 (const_string "none")
642 (const_string "load"))
643 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
644 (match_operand 1 "memory_operand" ""))
645 (const_string "both")
646 (and (match_operand 0 "memory_operand" "")
647 (match_operand 1 "memory_operand" ""))
648 (const_string "both")
649 (match_operand 0 "memory_operand" "")
650 (const_string "store")
651 (match_operand 1 "memory_operand" "")
652 (const_string "load")
654 "!alu1,negnot,ishift1,
655 imov,imovx,icmp,test,bitmanip,
657 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
658 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
659 (match_operand 2 "memory_operand" ""))
660 (const_string "load")
661 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
662 (match_operand 3 "memory_operand" ""))
663 (const_string "load")
665 (const_string "none")))
667 ;; Indicates if an instruction has both an immediate and a displacement.
669 (define_attr "imm_disp" "false,true,unknown"
670 (cond [(eq_attr "type" "other,multi")
671 (const_string "unknown")
672 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
673 (and (match_operand 0 "memory_displacement_operand" "")
674 (match_operand 1 "immediate_operand" "")))
675 (const_string "true")
676 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
677 (and (match_operand 0 "memory_displacement_operand" "")
678 (match_operand 2 "immediate_operand" "")))
679 (const_string "true")
681 (const_string "false")))
683 ;; Indicates if an FP operation has an integer source.
685 (define_attr "fp_int_src" "false,true"
686 (const_string "false"))
688 ;; Defines rounding mode of an FP operation.
690 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
691 (const_string "any"))
693 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
694 (define_attr "use_carry" "0,1" (const_string "0"))
696 ;; Define attribute to indicate unaligned ssemov insns
697 (define_attr "movu" "0,1" (const_string "0"))
699 ;; Used to control the "enabled" attribute on a per-instruction basis.
700 (define_attr "isa" "base,noavx,avx"
701 (const_string "base"))
703 (define_attr "enabled" ""
704 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
705 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
709 ;; Describe a user's asm statement.
710 (define_asm_attributes
711 [(set_attr "length" "128")
712 (set_attr "type" "multi")])
714 (define_code_iterator plusminus [plus minus])
716 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
718 ;; Base name for define_insn
719 (define_code_attr plusminus_insn
720 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
721 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
723 ;; Base name for insn mnemonic.
724 (define_code_attr plusminus_mnemonic
725 [(plus "add") (ss_plus "adds") (us_plus "addus")
726 (minus "sub") (ss_minus "subs") (us_minus "subus")])
727 (define_code_attr plusminus_carry_mnemonic
728 [(plus "adc") (minus "sbb")])
730 ;; Mark commutative operators as such in constraints.
731 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
732 (minus "") (ss_minus "") (us_minus "")])
734 ;; Mapping of signed max and min
735 (define_code_iterator smaxmin [smax smin])
737 ;; Mapping of unsigned max and min
738 (define_code_iterator umaxmin [umax umin])
740 ;; Base name for integer and FP insn mnemonic
741 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
742 (umax "maxu") (umin "minu")])
743 (define_code_attr maxmin_float [(smax "max") (smin "min")])
745 ;; Mapping of logic operators
746 (define_code_iterator any_logic [and ior xor])
747 (define_code_iterator any_or [ior xor])
749 ;; Base name for insn mnemonic.
750 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
752 ;; Mapping of shift-right operators
753 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
755 ;; Base name for define_insn
756 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
758 ;; Base name for insn mnemonic.
759 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
761 ;; Mapping of rotate operators
762 (define_code_iterator any_rotate [rotate rotatert])
764 ;; Base name for define_insn
765 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
767 ;; Base name for insn mnemonic.
768 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
770 ;; Mapping of abs neg operators
771 (define_code_iterator absneg [abs neg])
773 ;; Base name for x87 insn mnemonic.
774 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
776 ;; Used in signed and unsigned widening multiplications.
777 (define_code_iterator any_extend [sign_extend zero_extend])
779 ;; Various insn prefixes for signed and unsigned operations.
780 (define_code_attr u [(sign_extend "") (zero_extend "u")
781 (div "") (udiv "u")])
782 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
784 ;; Used in signed and unsigned divisions.
785 (define_code_iterator any_div [div udiv])
787 ;; Instruction prefix for signed and unsigned operations.
788 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
789 (div "i") (udiv "")])
791 ;; 64bit single word integer modes.
792 (define_mode_iterator SWI1248x [QI HI SI DI])
794 ;; 64bit single word integer modes without QImode and HImode.
795 (define_mode_iterator SWI48x [SI DI])
797 ;; Single word integer modes.
798 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
800 ;; Single word integer modes without SImode and DImode.
801 (define_mode_iterator SWI12 [QI HI])
803 ;; Single word integer modes without DImode.
804 (define_mode_iterator SWI124 [QI HI SI])
806 ;; Single word integer modes without QImode and DImode.
807 (define_mode_iterator SWI24 [HI SI])
809 ;; Single word integer modes without QImode.
810 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
812 ;; Single word integer modes without QImode and HImode.
813 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
815 ;; All math-dependant single and double word integer modes.
816 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
817 (HI "TARGET_HIMODE_MATH")
818 SI DI (TI "TARGET_64BIT")])
820 ;; Math-dependant single word integer modes.
821 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
822 (HI "TARGET_HIMODE_MATH")
823 SI (DI "TARGET_64BIT")])
825 ;; Math-dependant single word integer modes without DImode.
826 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
827 (HI "TARGET_HIMODE_MATH")
830 ;; Math-dependant single word integer modes without QImode.
831 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
832 SI (DI "TARGET_64BIT")])
834 ;; Double word integer modes.
835 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
836 (TI "TARGET_64BIT")])
838 ;; Double word integer modes as mode attribute.
839 (define_mode_attr DWI [(SI "DI") (DI "TI")])
840 (define_mode_attr dwi [(SI "di") (DI "ti")])
842 ;; Half mode for double word integer modes.
843 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
844 (DI "TARGET_64BIT")])
846 ;; Instruction suffix for integer modes.
847 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
849 ;; Pointer size prefix for integer modes (Intel asm dialect)
850 (define_mode_attr iptrsize [(QI "BYTE")
855 ;; Register class for integer modes.
856 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
858 ;; Immediate operand constraint for integer modes.
859 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
861 ;; General operand constraint for word modes.
862 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
864 ;; Immediate operand constraint for double integer modes.
865 (define_mode_attr di [(SI "iF") (DI "e")])
867 ;; Immediate operand constraint for shifts.
868 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
870 ;; General operand predicate for integer modes.
871 (define_mode_attr general_operand
872 [(QI "general_operand")
873 (HI "general_operand")
874 (SI "general_operand")
875 (DI "x86_64_general_operand")
876 (TI "x86_64_general_operand")])
878 ;; General sign/zero extend operand predicate for integer modes.
879 (define_mode_attr general_szext_operand
880 [(QI "general_operand")
881 (HI "general_operand")
882 (SI "general_operand")
883 (DI "x86_64_szext_general_operand")])
885 ;; Immediate operand predicate for integer modes.
886 (define_mode_attr immediate_operand
887 [(QI "immediate_operand")
888 (HI "immediate_operand")
889 (SI "immediate_operand")
890 (DI "x86_64_immediate_operand")])
892 ;; Nonmemory operand predicate for integer modes.
893 (define_mode_attr nonmemory_operand
894 [(QI "nonmemory_operand")
895 (HI "nonmemory_operand")
896 (SI "nonmemory_operand")
897 (DI "x86_64_nonmemory_operand")])
899 ;; Operand predicate for shifts.
900 (define_mode_attr shift_operand
901 [(QI "nonimmediate_operand")
902 (HI "nonimmediate_operand")
903 (SI "nonimmediate_operand")
904 (DI "shiftdi_operand")
905 (TI "register_operand")])
907 ;; Operand predicate for shift argument.
908 (define_mode_attr shift_immediate_operand
909 [(QI "const_1_to_31_operand")
910 (HI "const_1_to_31_operand")
911 (SI "const_1_to_31_operand")
912 (DI "const_1_to_63_operand")])
914 ;; Input operand predicate for arithmetic left shifts.
915 (define_mode_attr ashl_input_operand
916 [(QI "nonimmediate_operand")
917 (HI "nonimmediate_operand")
918 (SI "nonimmediate_operand")
919 (DI "ashldi_input_operand")
920 (TI "reg_or_pm1_operand")])
922 ;; SSE and x87 SFmode and DFmode floating point modes
923 (define_mode_iterator MODEF [SF DF])
925 ;; All x87 floating point modes
926 (define_mode_iterator X87MODEF [SF DF XF])
928 ;; All integer modes handled by x87 fisttp operator.
929 (define_mode_iterator X87MODEI [HI SI DI])
931 ;; All integer modes handled by integer x87 operators.
932 (define_mode_iterator X87MODEI12 [HI SI])
934 ;; All integer modes handled by SSE cvtts?2si* operators.
935 (define_mode_iterator SSEMODEI24 [SI DI])
937 ;; SSE instruction suffix for various modes
938 (define_mode_attr ssemodesuffix
940 (V8SF "ps") (V4DF "pd")
941 (V4SF "ps") (V2DF "pd")
942 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
945 ;; SSE vector suffix for floating point modes
946 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
948 ;; SSE vector mode corresponding to a scalar mode
949 (define_mode_attr ssevecmode
950 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
952 ;; Instruction suffix for REX 64bit operators.
953 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
955 ;; This mode iterator allows :P to be used for patterns that operate on
956 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
957 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
959 ;; Scheduling descriptions
961 (include "pentium.md")
964 (include "athlon.md")
965 (include "bdver1.md")
971 ;; Operand and operator predicates and constraints
973 (include "predicates.md")
974 (include "constraints.md")
977 ;; Compare and branch/compare and store instructions.
979 (define_expand "cbranch<mode>4"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
982 (match_operand:SDWIM 2 "<general_operand>" "")))
983 (set (pc) (if_then_else
984 (match_operator 0 "ordered_comparison_operator"
985 [(reg:CC FLAGS_REG) (const_int 0)])
986 (label_ref (match_operand 3 "" ""))
990 if (MEM_P (operands[1]) && MEM_P (operands[2]))
991 operands[1] = force_reg (<MODE>mode, operands[1]);
992 ix86_expand_branch (GET_CODE (operands[0]),
993 operands[1], operands[2], operands[3]);
997 (define_expand "cstore<mode>4"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1000 (match_operand:SWIM 3 "<general_operand>" "")))
1001 (set (match_operand:QI 0 "register_operand" "")
1002 (match_operator 1 "ordered_comparison_operator"
1003 [(reg:CC FLAGS_REG) (const_int 0)]))]
1006 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1007 operands[2] = force_reg (<MODE>mode, operands[2]);
1008 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1009 operands[2], operands[3]);
1013 (define_expand "cmp<mode>_1"
1014 [(set (reg:CC FLAGS_REG)
1015 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1016 (match_operand:SWI48 1 "<general_operand>" "")))])
1018 (define_insn "*cmp<mode>_ccno_1"
1019 [(set (reg FLAGS_REG)
1020 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1021 (match_operand:SWI 1 "const0_operand" "")))]
1022 "ix86_match_ccmode (insn, CCNOmode)"
1024 test{<imodesuffix>}\t%0, %0
1025 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1026 [(set_attr "type" "test,icmp")
1027 (set_attr "length_immediate" "0,1")
1028 (set_attr "mode" "<MODE>")])
1030 (define_insn "*cmp<mode>_1"
1031 [(set (reg FLAGS_REG)
1032 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1033 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1034 "ix86_match_ccmode (insn, CCmode)"
1035 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "<MODE>")])
1039 (define_insn "*cmp<mode>_minus_1"
1040 [(set (reg FLAGS_REG)
1042 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1043 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1045 "ix86_match_ccmode (insn, CCGOCmode)"
1046 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1047 [(set_attr "type" "icmp")
1048 (set_attr "mode" "<MODE>")])
1050 (define_insn "*cmpqi_ext_1"
1051 [(set (reg FLAGS_REG)
1053 (match_operand:QI 0 "general_operand" "Qm")
1056 (match_operand 1 "ext_register_operand" "Q")
1058 (const_int 8)) 0)))]
1059 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1060 "cmp{b}\t{%h1, %0|%0, %h1}"
1061 [(set_attr "type" "icmp")
1062 (set_attr "mode" "QI")])
1064 (define_insn "*cmpqi_ext_1_rex64"
1065 [(set (reg FLAGS_REG)
1067 (match_operand:QI 0 "register_operand" "Q")
1070 (match_operand 1 "ext_register_operand" "Q")
1072 (const_int 8)) 0)))]
1073 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1074 "cmp{b}\t{%h1, %0|%0, %h1}"
1075 [(set_attr "type" "icmp")
1076 (set_attr "mode" "QI")])
1078 (define_insn "*cmpqi_ext_2"
1079 [(set (reg FLAGS_REG)
1083 (match_operand 0 "ext_register_operand" "Q")
1086 (match_operand:QI 1 "const0_operand" "")))]
1087 "ix86_match_ccmode (insn, CCNOmode)"
1089 [(set_attr "type" "test")
1090 (set_attr "length_immediate" "0")
1091 (set_attr "mode" "QI")])
1093 (define_expand "cmpqi_ext_3"
1094 [(set (reg:CC FLAGS_REG)
1098 (match_operand 0 "ext_register_operand" "")
1101 (match_operand:QI 1 "immediate_operand" "")))])
1103 (define_insn "*cmpqi_ext_3_insn"
1104 [(set (reg FLAGS_REG)
1108 (match_operand 0 "ext_register_operand" "Q")
1111 (match_operand:QI 1 "general_operand" "Qmn")))]
1112 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1113 "cmp{b}\t{%1, %h0|%h0, %1}"
1114 [(set_attr "type" "icmp")
1115 (set_attr "modrm" "1")
1116 (set_attr "mode" "QI")])
1118 (define_insn "*cmpqi_ext_3_insn_rex64"
1119 [(set (reg FLAGS_REG)
1123 (match_operand 0 "ext_register_operand" "Q")
1126 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1127 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1128 "cmp{b}\t{%1, %h0|%h0, %1}"
1129 [(set_attr "type" "icmp")
1130 (set_attr "modrm" "1")
1131 (set_attr "mode" "QI")])
1133 (define_insn "*cmpqi_ext_4"
1134 [(set (reg FLAGS_REG)
1138 (match_operand 0 "ext_register_operand" "Q")
1143 (match_operand 1 "ext_register_operand" "Q")
1145 (const_int 8)) 0)))]
1146 "ix86_match_ccmode (insn, CCmode)"
1147 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1148 [(set_attr "type" "icmp")
1149 (set_attr "mode" "QI")])
1151 ;; These implement float point compares.
1152 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1153 ;; which would allow mix and match FP modes on the compares. Which is what
1154 ;; the old patterns did, but with many more of them.
1156 (define_expand "cbranchxf4"
1157 [(set (reg:CC FLAGS_REG)
1158 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1159 (match_operand:XF 2 "nonmemory_operand" "")))
1160 (set (pc) (if_then_else
1161 (match_operator 0 "ix86_fp_comparison_operator"
1164 (label_ref (match_operand 3 "" ""))
1168 ix86_expand_branch (GET_CODE (operands[0]),
1169 operands[1], operands[2], operands[3]);
1173 (define_expand "cstorexf4"
1174 [(set (reg:CC FLAGS_REG)
1175 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1176 (match_operand:XF 3 "nonmemory_operand" "")))
1177 (set (match_operand:QI 0 "register_operand" "")
1178 (match_operator 1 "ix86_fp_comparison_operator"
1183 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1184 operands[2], operands[3]);
1188 (define_expand "cbranch<mode>4"
1189 [(set (reg:CC FLAGS_REG)
1190 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1191 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1192 (set (pc) (if_then_else
1193 (match_operator 0 "ix86_fp_comparison_operator"
1196 (label_ref (match_operand 3 "" ""))
1198 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1200 ix86_expand_branch (GET_CODE (operands[0]),
1201 operands[1], operands[2], operands[3]);
1205 (define_expand "cstore<mode>4"
1206 [(set (reg:CC FLAGS_REG)
1207 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1208 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1209 (set (match_operand:QI 0 "register_operand" "")
1210 (match_operator 1 "ix86_fp_comparison_operator"
1213 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1215 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1216 operands[2], operands[3]);
1220 (define_expand "cbranchcc4"
1221 [(set (pc) (if_then_else
1222 (match_operator 0 "comparison_operator"
1223 [(match_operand 1 "flags_reg_operand" "")
1224 (match_operand 2 "const0_operand" "")])
1225 (label_ref (match_operand 3 "" ""))
1229 ix86_expand_branch (GET_CODE (operands[0]),
1230 operands[1], operands[2], operands[3]);
1234 (define_expand "cstorecc4"
1235 [(set (match_operand:QI 0 "register_operand" "")
1236 (match_operator 1 "comparison_operator"
1237 [(match_operand 2 "flags_reg_operand" "")
1238 (match_operand 3 "const0_operand" "")]))]
1241 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1242 operands[2], operands[3]);
1247 ;; FP compares, step 1:
1248 ;; Set the FP condition codes.
1250 ;; CCFPmode compare with exceptions
1251 ;; CCFPUmode compare with no exceptions
1253 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1254 ;; used to manage the reg stack popping would not be preserved.
1256 (define_insn "*cmpfp_0"
1257 [(set (match_operand:HI 0 "register_operand" "=a")
1260 (match_operand 1 "register_operand" "f")
1261 (match_operand 2 "const0_operand" ""))]
1263 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1264 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1265 "* return output_fp_compare (insn, operands, 0, 0);"
1266 [(set_attr "type" "multi")
1267 (set_attr "unit" "i387")
1269 (cond [(match_operand:SF 1 "" "")
1271 (match_operand:DF 1 "" "")
1274 (const_string "XF")))])
1276 (define_insn_and_split "*cmpfp_0_cc"
1277 [(set (reg:CCFP FLAGS_REG)
1279 (match_operand 1 "register_operand" "f")
1280 (match_operand 2 "const0_operand" "")))
1281 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1282 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1283 && TARGET_SAHF && !TARGET_CMOVE
1284 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1286 "&& reload_completed"
1289 [(compare:CCFP (match_dup 1)(match_dup 2))]
1291 (set (reg:CC FLAGS_REG)
1292 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1294 [(set_attr "type" "multi")
1295 (set_attr "unit" "i387")
1297 (cond [(match_operand:SF 1 "" "")
1299 (match_operand:DF 1 "" "")
1302 (const_string "XF")))])
1304 (define_insn "*cmpfp_xf"
1305 [(set (match_operand:HI 0 "register_operand" "=a")
1308 (match_operand:XF 1 "register_operand" "f")
1309 (match_operand:XF 2 "register_operand" "f"))]
1312 "* return output_fp_compare (insn, operands, 0, 0);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "XF")])
1317 (define_insn_and_split "*cmpfp_xf_cc"
1318 [(set (reg:CCFP FLAGS_REG)
1320 (match_operand:XF 1 "register_operand" "f")
1321 (match_operand:XF 2 "register_operand" "f")))
1322 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1324 && TARGET_SAHF && !TARGET_CMOVE"
1326 "&& reload_completed"
1329 [(compare:CCFP (match_dup 1)(match_dup 2))]
1331 (set (reg:CC FLAGS_REG)
1332 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1334 [(set_attr "type" "multi")
1335 (set_attr "unit" "i387")
1336 (set_attr "mode" "XF")])
1338 (define_insn "*cmpfp_<mode>"
1339 [(set (match_operand:HI 0 "register_operand" "=a")
1342 (match_operand:MODEF 1 "register_operand" "f")
1343 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1346 "* return output_fp_compare (insn, operands, 0, 0);"
1347 [(set_attr "type" "multi")
1348 (set_attr "unit" "i387")
1349 (set_attr "mode" "<MODE>")])
1351 (define_insn_and_split "*cmpfp_<mode>_cc"
1352 [(set (reg:CCFP FLAGS_REG)
1354 (match_operand:MODEF 1 "register_operand" "f")
1355 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1356 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1358 && TARGET_SAHF && !TARGET_CMOVE"
1360 "&& reload_completed"
1363 [(compare:CCFP (match_dup 1)(match_dup 2))]
1365 (set (reg:CC FLAGS_REG)
1366 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1368 [(set_attr "type" "multi")
1369 (set_attr "unit" "i387")
1370 (set_attr "mode" "<MODE>")])
1372 (define_insn "*cmpfp_u"
1373 [(set (match_operand:HI 0 "register_operand" "=a")
1376 (match_operand 1 "register_operand" "f")
1377 (match_operand 2 "register_operand" "f"))]
1379 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1380 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1381 "* return output_fp_compare (insn, operands, 0, 1);"
1382 [(set_attr "type" "multi")
1383 (set_attr "unit" "i387")
1385 (cond [(match_operand:SF 1 "" "")
1387 (match_operand:DF 1 "" "")
1390 (const_string "XF")))])
1392 (define_insn_and_split "*cmpfp_u_cc"
1393 [(set (reg:CCFPU FLAGS_REG)
1395 (match_operand 1 "register_operand" "f")
1396 (match_operand 2 "register_operand" "f")))
1397 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1398 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1399 && TARGET_SAHF && !TARGET_CMOVE
1400 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1402 "&& reload_completed"
1405 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1407 (set (reg:CC FLAGS_REG)
1408 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1410 [(set_attr "type" "multi")
1411 (set_attr "unit" "i387")
1413 (cond [(match_operand:SF 1 "" "")
1415 (match_operand:DF 1 "" "")
1418 (const_string "XF")))])
1420 (define_insn "*cmpfp_<mode>"
1421 [(set (match_operand:HI 0 "register_operand" "=a")
1424 (match_operand 1 "register_operand" "f")
1425 (match_operator 3 "float_operator"
1426 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1428 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1430 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1431 "* return output_fp_compare (insn, operands, 0, 0);"
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set_attr "fp_int_src" "true")
1435 (set_attr "mode" "<MODE>")])
1437 (define_insn_and_split "*cmpfp_<mode>_cc"
1438 [(set (reg:CCFP FLAGS_REG)
1440 (match_operand 1 "register_operand" "f")
1441 (match_operator 3 "float_operator"
1442 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1443 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1444 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1445 && TARGET_SAHF && !TARGET_CMOVE
1446 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1447 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1449 "&& reload_completed"
1454 (match_op_dup 3 [(match_dup 2)]))]
1456 (set (reg:CC FLAGS_REG)
1457 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1459 [(set_attr "type" "multi")
1460 (set_attr "unit" "i387")
1461 (set_attr "fp_int_src" "true")
1462 (set_attr "mode" "<MODE>")])
1464 ;; FP compares, step 2
1465 ;; Move the fpsw to ax.
1467 (define_insn "x86_fnstsw_1"
1468 [(set (match_operand:HI 0 "register_operand" "=a")
1469 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1472 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1473 (set_attr "mode" "SI")
1474 (set_attr "unit" "i387")])
1476 ;; FP compares, step 3
1477 ;; Get ax into flags, general case.
1479 (define_insn "x86_sahf_1"
1480 [(set (reg:CC FLAGS_REG)
1481 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1485 #ifndef HAVE_AS_IX86_SAHF
1487 return ASM_BYTE "0x9e";
1492 [(set_attr "length" "1")
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")
1495 (set_attr "bdver1_decode" "direct")
1496 (set_attr "mode" "SI")])
1498 ;; Pentium Pro can do steps 1 through 3 in one go.
1499 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1500 (define_insn "*cmpfp_i_mixed"
1501 [(set (reg:CCFP FLAGS_REG)
1502 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1503 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1504 "TARGET_MIX_SSE_I387
1505 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1506 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507 "* return output_fp_compare (insn, operands, 1, 0);"
1508 [(set_attr "type" "fcmp,ssecomi")
1509 (set_attr "prefix" "orig,maybe_vex")
1511 (if_then_else (match_operand:SF 1 "" "")
1513 (const_string "DF")))
1514 (set (attr "prefix_rep")
1515 (if_then_else (eq_attr "type" "ssecomi")
1517 (const_string "*")))
1518 (set (attr "prefix_data16")
1519 (cond [(eq_attr "type" "fcmp")
1521 (eq_attr "mode" "DF")
1524 (const_string "0")))
1525 (set_attr "athlon_decode" "vector")
1526 (set_attr "amdfam10_decode" "direct")
1527 (set_attr "bdver1_decode" "double")])
1529 (define_insn "*cmpfp_i_sse"
1530 [(set (reg:CCFP FLAGS_REG)
1531 (compare:CCFP (match_operand 0 "register_operand" "x")
1532 (match_operand 1 "nonimmediate_operand" "xm")))]
1534 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1535 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1536 "* return output_fp_compare (insn, operands, 1, 0);"
1537 [(set_attr "type" "ssecomi")
1538 (set_attr "prefix" "maybe_vex")
1540 (if_then_else (match_operand:SF 1 "" "")
1542 (const_string "DF")))
1543 (set_attr "prefix_rep" "0")
1544 (set (attr "prefix_data16")
1545 (if_then_else (eq_attr "mode" "DF")
1547 (const_string "0")))
1548 (set_attr "athlon_decode" "vector")
1549 (set_attr "amdfam10_decode" "direct")
1550 (set_attr "bdver1_decode" "double")])
1552 (define_insn "*cmpfp_i_i387"
1553 [(set (reg:CCFP FLAGS_REG)
1554 (compare:CCFP (match_operand 0 "register_operand" "f")
1555 (match_operand 1 "register_operand" "f")))]
1556 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1558 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1559 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560 "* return output_fp_compare (insn, operands, 1, 0);"
1561 [(set_attr "type" "fcmp")
1563 (cond [(match_operand:SF 1 "" "")
1565 (match_operand:DF 1 "" "")
1568 (const_string "XF")))
1569 (set_attr "athlon_decode" "vector")
1570 (set_attr "amdfam10_decode" "direct")
1571 (set_attr "bdver1_decode" "double")])
1573 (define_insn "*cmpfp_iu_mixed"
1574 [(set (reg:CCFPU FLAGS_REG)
1575 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1576 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1577 "TARGET_MIX_SSE_I387
1578 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1579 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580 "* return output_fp_compare (insn, operands, 1, 1);"
1581 [(set_attr "type" "fcmp,ssecomi")
1582 (set_attr "prefix" "orig,maybe_vex")
1584 (if_then_else (match_operand:SF 1 "" "")
1586 (const_string "DF")))
1587 (set (attr "prefix_rep")
1588 (if_then_else (eq_attr "type" "ssecomi")
1590 (const_string "*")))
1591 (set (attr "prefix_data16")
1592 (cond [(eq_attr "type" "fcmp")
1594 (eq_attr "mode" "DF")
1597 (const_string "0")))
1598 (set_attr "athlon_decode" "vector")
1599 (set_attr "amdfam10_decode" "direct")
1600 (set_attr "bdver1_decode" "double")])
1602 (define_insn "*cmpfp_iu_sse"
1603 [(set (reg:CCFPU FLAGS_REG)
1604 (compare:CCFPU (match_operand 0 "register_operand" "x")
1605 (match_operand 1 "nonimmediate_operand" "xm")))]
1607 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1608 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1609 "* return output_fp_compare (insn, operands, 1, 1);"
1610 [(set_attr "type" "ssecomi")
1611 (set_attr "prefix" "maybe_vex")
1613 (if_then_else (match_operand:SF 1 "" "")
1615 (const_string "DF")))
1616 (set_attr "prefix_rep" "0")
1617 (set (attr "prefix_data16")
1618 (if_then_else (eq_attr "mode" "DF")
1620 (const_string "0")))
1621 (set_attr "athlon_decode" "vector")
1622 (set_attr "amdfam10_decode" "direct")
1623 (set_attr "bdver1_decode" "double")])
1625 (define_insn "*cmpfp_iu_387"
1626 [(set (reg:CCFPU FLAGS_REG)
1627 (compare:CCFPU (match_operand 0 "register_operand" "f")
1628 (match_operand 1 "register_operand" "f")))]
1629 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1631 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1632 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1633 "* return output_fp_compare (insn, operands, 1, 1);"
1634 [(set_attr "type" "fcmp")
1636 (cond [(match_operand:SF 1 "" "")
1638 (match_operand:DF 1 "" "")
1641 (const_string "XF")))
1642 (set_attr "athlon_decode" "vector")
1643 (set_attr "amdfam10_decode" "direct")
1644 (set_attr "bdver1_decode" "direct")])
1646 ;; Push/pop instructions.
1648 (define_insn "*push<mode>2"
1649 [(set (match_operand:DWI 0 "push_operand" "=<")
1650 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1655 [(set (match_operand:TI 0 "push_operand" "")
1656 (match_operand:TI 1 "general_operand" ""))]
1657 "TARGET_64BIT && reload_completed
1658 && !SSE_REG_P (operands[1])"
1660 "ix86_split_long_move (operands); DONE;")
1662 (define_insn "*pushdi2_rex64"
1663 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1664 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1669 [(set_attr "type" "push,multi")
1670 (set_attr "mode" "DI")])
1672 ;; Convert impossible pushes of immediate to existing instructions.
1673 ;; First try to get scratch register and go through it. In case this
1674 ;; fails, push sign extended lower part first and then overwrite
1675 ;; upper part by 32bit move.
1677 [(match_scratch:DI 2 "r")
1678 (set (match_operand:DI 0 "push_operand" "")
1679 (match_operand:DI 1 "immediate_operand" ""))]
1680 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1681 && !x86_64_immediate_operand (operands[1], DImode)"
1682 [(set (match_dup 2) (match_dup 1))
1683 (set (match_dup 0) (match_dup 2))])
1685 ;; We need to define this as both peepholer and splitter for case
1686 ;; peephole2 pass is not run.
1687 ;; "&& 1" is needed to keep it from matching the previous pattern.
1689 [(set (match_operand:DI 0 "push_operand" "")
1690 (match_operand:DI 1 "immediate_operand" ""))]
1691 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1692 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1693 [(set (match_dup 0) (match_dup 1))
1694 (set (match_dup 2) (match_dup 3))]
1696 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1698 operands[1] = gen_lowpart (DImode, operands[2]);
1699 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1704 [(set (match_operand:DI 0 "push_operand" "")
1705 (match_operand:DI 1 "immediate_operand" ""))]
1706 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1707 ? epilogue_completed : reload_completed)
1708 && !symbolic_operand (operands[1], DImode)
1709 && !x86_64_immediate_operand (operands[1], DImode)"
1710 [(set (match_dup 0) (match_dup 1))
1711 (set (match_dup 2) (match_dup 3))]
1713 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1715 operands[1] = gen_lowpart (DImode, operands[2]);
1716 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1721 [(set (match_operand:DI 0 "push_operand" "")
1722 (match_operand:DI 1 "general_operand" ""))]
1723 "!TARGET_64BIT && reload_completed
1724 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1726 "ix86_split_long_move (operands); DONE;")
1728 (define_insn "*pushsi2"
1729 [(set (match_operand:SI 0 "push_operand" "=<")
1730 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1733 [(set_attr "type" "push")
1734 (set_attr "mode" "SI")])
1736 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1737 ;; "push a byte/word". But actually we use pushl, which has the effect
1738 ;; of rounding the amount pushed up to a word.
1740 ;; For TARGET_64BIT we always round up to 8 bytes.
1741 (define_insn "*push<mode>2_rex64"
1742 [(set (match_operand:SWI124 0 "push_operand" "=X")
1743 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1746 [(set_attr "type" "push")
1747 (set_attr "mode" "DI")])
1749 (define_insn "*push<mode>2"
1750 [(set (match_operand:SWI12 0 "push_operand" "=X")
1751 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1754 [(set_attr "type" "push")
1755 (set_attr "mode" "SI")])
1757 (define_insn "*push<mode>2_prologue"
1758 [(set (match_operand:P 0 "push_operand" "=<")
1759 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1760 (clobber (mem:BLK (scratch)))]
1762 "push{<imodesuffix>}\t%1"
1763 [(set_attr "type" "push")
1764 (set_attr "mode" "<MODE>")])
1766 (define_insn "*pop<mode>1"
1767 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1768 (match_operand:P 1 "pop_operand" ">"))]
1770 "pop{<imodesuffix>}\t%0"
1771 [(set_attr "type" "pop")
1772 (set_attr "mode" "<MODE>")])
1774 (define_insn "*pop<mode>1_epilogue"
1775 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1776 (match_operand:P 1 "pop_operand" ">"))
1777 (clobber (mem:BLK (scratch)))]
1779 "pop{<imodesuffix>}\t%0"
1780 [(set_attr "type" "pop")
1781 (set_attr "mode" "<MODE>")])
1783 ;; Move instructions.
1785 (define_expand "movoi"
1786 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1787 (match_operand:OI 1 "general_operand" ""))]
1789 "ix86_expand_move (OImode, operands); DONE;")
1791 (define_expand "movti"
1792 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1793 (match_operand:TI 1 "nonimmediate_operand" ""))]
1794 "TARGET_64BIT || TARGET_SSE"
1797 ix86_expand_move (TImode, operands);
1798 else if (push_operand (operands[0], TImode))
1799 ix86_expand_push (TImode, operands[1]);
1801 ix86_expand_vector_move (TImode, operands);
1805 ;; This expands to what emit_move_complex would generate if we didn't
1806 ;; have a movti pattern. Having this avoids problems with reload on
1807 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1808 ;; to have around all the time.
1809 (define_expand "movcdi"
1810 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1811 (match_operand:CDI 1 "general_operand" ""))]
1814 if (push_operand (operands[0], CDImode))
1815 emit_move_complex_push (CDImode, operands[0], operands[1]);
1817 emit_move_complex_parts (operands[0], operands[1]);
1821 (define_expand "mov<mode>"
1822 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1823 (match_operand:SWI1248x 1 "general_operand" ""))]
1825 "ix86_expand_move (<MODE>mode, operands); DONE;")
1827 (define_insn "*mov<mode>_xor"
1828 [(set (match_operand:SWI48 0 "register_operand" "=r")
1829 (match_operand:SWI48 1 "const0_operand" ""))
1830 (clobber (reg:CC FLAGS_REG))]
1833 [(set_attr "type" "alu1")
1834 (set_attr "mode" "SI")
1835 (set_attr "length_immediate" "0")])
1837 (define_insn "*mov<mode>_or"
1838 [(set (match_operand:SWI48 0 "register_operand" "=r")
1839 (match_operand:SWI48 1 "const_int_operand" ""))
1840 (clobber (reg:CC FLAGS_REG))]
1842 && operands[1] == constm1_rtx"
1843 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1844 [(set_attr "type" "alu1")
1845 (set_attr "mode" "<MODE>")
1846 (set_attr "length_immediate" "1")])
1848 (define_insn "*movoi_internal_avx"
1849 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1850 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1851 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1853 switch (which_alternative)
1856 return "vxorps\t%0, %0, %0";
1859 if (misaligned_operand (operands[0], OImode)
1860 || misaligned_operand (operands[1], OImode))
1861 return "vmovdqu\t{%1, %0|%0, %1}";
1863 return "vmovdqa\t{%1, %0|%0, %1}";
1868 [(set_attr "type" "sselog1,ssemov,ssemov")
1869 (set_attr "prefix" "vex")
1870 (set_attr "mode" "OI")])
1872 (define_insn "*movti_internal_rex64"
1873 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1874 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1875 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1877 switch (which_alternative)
1883 if (get_attr_mode (insn) == MODE_V4SF)
1884 return "%vxorps\t%0, %d0";
1886 return "%vpxor\t%0, %d0";
1889 /* TDmode values are passed as TImode on the stack. Moving them
1890 to stack may result in unaligned memory access. */
1891 if (misaligned_operand (operands[0], TImode)
1892 || misaligned_operand (operands[1], TImode))
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovups\t{%1, %0|%0, %1}";
1897 return "%vmovdqu\t{%1, %0|%0, %1}";
1901 if (get_attr_mode (insn) == MODE_V4SF)
1902 return "%vmovaps\t{%1, %0|%0, %1}";
1904 return "%vmovdqa\t{%1, %0|%0, %1}";
1910 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1911 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1913 (cond [(eq_attr "alternative" "2,3")
1915 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1917 (const_string "V4SF")
1918 (const_string "TI"))
1919 (eq_attr "alternative" "4")
1921 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1923 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1925 (const_string "V4SF")
1926 (const_string "TI"))]
1927 (const_string "DI")))])
1930 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1931 (match_operand:TI 1 "general_operand" ""))]
1933 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1935 "ix86_split_long_move (operands); DONE;")
1937 (define_insn "*movti_internal_sse"
1938 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1939 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1940 "TARGET_SSE && !TARGET_64BIT
1941 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943 switch (which_alternative)
1946 if (get_attr_mode (insn) == MODE_V4SF)
1947 return "%vxorps\t%0, %d0";
1949 return "%vpxor\t%0, %d0";
1952 /* TDmode values are passed as TImode on the stack. Moving them
1953 to stack may result in unaligned memory access. */
1954 if (misaligned_operand (operands[0], TImode)
1955 || misaligned_operand (operands[1], TImode))
1957 if (get_attr_mode (insn) == MODE_V4SF)
1958 return "%vmovups\t{%1, %0|%0, %1}";
1960 return "%vmovdqu\t{%1, %0|%0, %1}";
1964 if (get_attr_mode (insn) == MODE_V4SF)
1965 return "%vmovaps\t{%1, %0|%0, %1}";
1967 return "%vmovdqa\t{%1, %0|%0, %1}";
1973 [(set_attr "type" "sselog1,ssemov,ssemov")
1974 (set_attr "prefix" "maybe_vex")
1976 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1977 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1979 (const_string "V4SF")
1980 (and (eq_attr "alternative" "2")
1981 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1983 (const_string "V4SF")]
1984 (const_string "TI")))])
1986 (define_insn "*movdi_internal_rex64"
1987 [(set (match_operand:DI 0 "nonimmediate_operand"
1988 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1989 (match_operand:DI 1 "general_operand"
1990 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1991 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1993 switch (get_attr_type (insn))
1996 if (SSE_REG_P (operands[0]))
1997 return "movq2dq\t{%1, %0|%0, %1}";
1999 return "movdq2q\t{%1, %0|%0, %1}";
2002 if (get_attr_mode (insn) == MODE_TI)
2003 return "%vmovdqa\t{%1, %0|%0, %1}";
2004 /* Handle broken assemblers that reqire movd instead of movq. */
2005 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2006 return "%vmovd\t{%1, %0|%0, %1}";
2007 return "%vmovq\t{%1, %0|%0, %1}";
2010 /* Handle broken assemblers that reqire movd instead of movq. */
2011 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2012 return "movd\t{%1, %0|%0, %1}";
2013 return "movq\t{%1, %0|%0, %1}";
2016 return "%vpxor\t%0, %d0";
2019 return "pxor\t%0, %0";
2025 return "lea{q}\t{%a1, %0|%0, %a1}";
2028 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2029 if (get_attr_mode (insn) == MODE_SI)
2030 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2031 else if (which_alternative == 2)
2032 return "movabs{q}\t{%1, %0|%0, %1}";
2034 return "mov{q}\t{%1, %0|%0, %1}";
2038 (cond [(eq_attr "alternative" "5")
2039 (const_string "mmx")
2040 (eq_attr "alternative" "6,7,8,9,10")
2041 (const_string "mmxmov")
2042 (eq_attr "alternative" "11")
2043 (const_string "sselog1")
2044 (eq_attr "alternative" "12,13,14,15,16")
2045 (const_string "ssemov")
2046 (eq_attr "alternative" "17,18")
2047 (const_string "ssecvt")
2048 (eq_attr "alternative" "4")
2049 (const_string "multi")
2050 (match_operand:DI 1 "pic_32bit_operand" "")
2051 (const_string "lea")
2053 (const_string "imov")))
2056 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2058 (const_string "*")))
2059 (set (attr "length_immediate")
2061 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2063 (const_string "*")))
2064 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2065 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2066 (set (attr "prefix")
2067 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2068 (const_string "maybe_vex")
2069 (const_string "orig")))
2070 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2072 ;; Convert impossible stores of immediate to existing instructions.
2073 ;; First try to get scratch register and go through it. In case this
2074 ;; fails, move by 32bit parts.
2076 [(match_scratch:DI 2 "r")
2077 (set (match_operand:DI 0 "memory_operand" "")
2078 (match_operand:DI 1 "immediate_operand" ""))]
2079 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2080 && !x86_64_immediate_operand (operands[1], DImode)"
2081 [(set (match_dup 2) (match_dup 1))
2082 (set (match_dup 0) (match_dup 2))])
2084 ;; We need to define this as both peepholer and splitter for case
2085 ;; peephole2 pass is not run.
2086 ;; "&& 1" is needed to keep it from matching the previous pattern.
2088 [(set (match_operand:DI 0 "memory_operand" "")
2089 (match_operand:DI 1 "immediate_operand" ""))]
2090 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2092 [(set (match_dup 2) (match_dup 3))
2093 (set (match_dup 4) (match_dup 5))]
2094 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2097 [(set (match_operand:DI 0 "memory_operand" "")
2098 (match_operand:DI 1 "immediate_operand" ""))]
2099 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2100 ? epilogue_completed : reload_completed)
2101 && !symbolic_operand (operands[1], DImode)
2102 && !x86_64_immediate_operand (operands[1], DImode)"
2103 [(set (match_dup 2) (match_dup 3))
2104 (set (match_dup 4) (match_dup 5))]
2105 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2107 (define_insn "*movdi_internal"
2108 [(set (match_operand:DI 0 "nonimmediate_operand"
2109 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2110 (match_operand:DI 1 "general_operand"
2111 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2112 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2117 movq\t{%1, %0|%0, %1}
2118 movq\t{%1, %0|%0, %1}
2120 %vmovq\t{%1, %0|%0, %1}
2121 %vmovdqa\t{%1, %0|%0, %1}
2122 %vmovq\t{%1, %0|%0, %1}
2124 movlps\t{%1, %0|%0, %1}
2125 movaps\t{%1, %0|%0, %1}
2126 movlps\t{%1, %0|%0, %1}"
2128 (if_then_else (eq_attr "alternative" "9,10,11,12")
2129 (const_string "noavx")
2130 (const_string "base")))
2131 (set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2132 (set (attr "prefix")
2133 (if_then_else (eq_attr "alternative" "5,6,7,8")
2134 (const_string "maybe_vex")
2135 (const_string "orig")))
2136 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2139 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2140 (match_operand:DI 1 "general_operand" ""))]
2141 "!TARGET_64BIT && reload_completed
2142 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2143 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2145 "ix86_split_long_move (operands); DONE;")
2147 (define_insn "*movsi_internal"
2148 [(set (match_operand:SI 0 "nonimmediate_operand"
2149 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2150 (match_operand:SI 1 "general_operand"
2151 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2152 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2154 switch (get_attr_type (insn))
2157 if (get_attr_mode (insn) == MODE_TI)
2158 return "%vpxor\t%0, %d0";
2159 return "%vxorps\t%0, %d0";
2162 switch (get_attr_mode (insn))
2165 return "%vmovdqa\t{%1, %0|%0, %1}";
2167 return "%vmovaps\t{%1, %0|%0, %1}";
2169 return "%vmovd\t{%1, %0|%0, %1}";
2171 return "%vmovss\t{%1, %0|%0, %1}";
2177 return "pxor\t%0, %0";
2180 if (get_attr_mode (insn) == MODE_DI)
2181 return "movq\t{%1, %0|%0, %1}";
2182 return "movd\t{%1, %0|%0, %1}";
2185 return "lea{l}\t{%a1, %0|%0, %a1}";
2188 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2189 return "mov{l}\t{%1, %0|%0, %1}";
2193 (cond [(eq_attr "alternative" "2")
2194 (const_string "mmx")
2195 (eq_attr "alternative" "3,4,5")
2196 (const_string "mmxmov")
2197 (eq_attr "alternative" "6")
2198 (const_string "sselog1")
2199 (eq_attr "alternative" "7,8,9,10,11")
2200 (const_string "ssemov")
2201 (match_operand:DI 1 "pic_32bit_operand" "")
2202 (const_string "lea")
2204 (const_string "imov")))
2205 (set (attr "prefix")
2206 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2207 (const_string "orig")
2208 (const_string "maybe_vex")))
2209 (set (attr "prefix_data16")
2210 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2212 (const_string "*")))
2214 (cond [(eq_attr "alternative" "2,3")
2216 (eq_attr "alternative" "6,7")
2218 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2219 (const_string "V4SF")
2220 (const_string "TI"))
2221 (and (eq_attr "alternative" "8,9,10,11")
2222 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2225 (const_string "SI")))])
2227 (define_insn "*movhi_internal"
2228 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2229 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2230 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2232 switch (get_attr_type (insn))
2235 /* movzwl is faster than movw on p2 due to partial word stalls,
2236 though not as fast as an aligned movl. */
2237 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2239 if (get_attr_mode (insn) == MODE_SI)
2240 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2242 return "mov{w}\t{%1, %0|%0, %1}";
2246 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2248 (const_string "imov")
2249 (and (eq_attr "alternative" "0")
2250 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2252 (eq (symbol_ref "TARGET_HIMODE_MATH")
2254 (const_string "imov")
2255 (and (eq_attr "alternative" "1,2")
2256 (match_operand:HI 1 "aligned_operand" ""))
2257 (const_string "imov")
2258 (and (ne (symbol_ref "TARGET_MOVX")
2260 (eq_attr "alternative" "0,2"))
2261 (const_string "imovx")
2263 (const_string "imov")))
2265 (cond [(eq_attr "type" "imovx")
2267 (and (eq_attr "alternative" "1,2")
2268 (match_operand:HI 1 "aligned_operand" ""))
2270 (and (eq_attr "alternative" "0")
2271 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2273 (eq (symbol_ref "TARGET_HIMODE_MATH")
2277 (const_string "HI")))])
2279 ;; Situation is quite tricky about when to choose full sized (SImode) move
2280 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2281 ;; partial register dependency machines (such as AMD Athlon), where QImode
2282 ;; moves issue extra dependency and for partial register stalls machines
2283 ;; that don't use QImode patterns (and QImode move cause stall on the next
2286 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2287 ;; register stall machines with, where we use QImode instructions, since
2288 ;; partial register stall can be caused there. Then we use movzx.
2289 (define_insn "*movqi_internal"
2290 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2291 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2292 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2294 switch (get_attr_type (insn))
2297 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2298 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2300 if (get_attr_mode (insn) == MODE_SI)
2301 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2303 return "mov{b}\t{%1, %0|%0, %1}";
2307 (cond [(and (eq_attr "alternative" "5")
2308 (not (match_operand:QI 1 "aligned_operand" "")))
2309 (const_string "imovx")
2310 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2312 (const_string "imov")
2313 (and (eq_attr "alternative" "3")
2314 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2316 (eq (symbol_ref "TARGET_QIMODE_MATH")
2318 (const_string "imov")
2319 (eq_attr "alternative" "3,5")
2320 (const_string "imovx")
2321 (and (ne (symbol_ref "TARGET_MOVX")
2323 (eq_attr "alternative" "2"))
2324 (const_string "imovx")
2326 (const_string "imov")))
2328 (cond [(eq_attr "alternative" "3,4,5")
2330 (eq_attr "alternative" "6")
2332 (eq_attr "type" "imovx")
2334 (and (eq_attr "type" "imov")
2335 (and (eq_attr "alternative" "0,1")
2336 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2338 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2340 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2343 ;; Avoid partial register stalls when not using QImode arithmetic
2344 (and (eq_attr "type" "imov")
2345 (and (eq_attr "alternative" "0,1")
2346 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2348 (eq (symbol_ref "TARGET_QIMODE_MATH")
2352 (const_string "QI")))])
2354 ;; Stores and loads of ax to arbitrary constant address.
2355 ;; We fake an second form of instruction to force reload to load address
2356 ;; into register when rax is not available
2357 (define_insn "*movabs<mode>_1"
2358 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2359 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2360 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2362 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2363 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2364 [(set_attr "type" "imov")
2365 (set_attr "modrm" "0,*")
2366 (set_attr "length_address" "8,0")
2367 (set_attr "length_immediate" "0,*")
2368 (set_attr "memory" "store")
2369 (set_attr "mode" "<MODE>")])
2371 (define_insn "*movabs<mode>_2"
2372 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2373 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2374 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2376 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2377 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2378 [(set_attr "type" "imov")
2379 (set_attr "modrm" "0,*")
2380 (set_attr "length_address" "8,0")
2381 (set_attr "length_immediate" "0")
2382 (set_attr "memory" "load")
2383 (set_attr "mode" "<MODE>")])
2385 (define_insn "*swap<mode>"
2386 [(set (match_operand:SWI48 0 "register_operand" "+r")
2387 (match_operand:SWI48 1 "register_operand" "+r"))
2391 "xchg{<imodesuffix>}\t%1, %0"
2392 [(set_attr "type" "imov")
2393 (set_attr "mode" "<MODE>")
2394 (set_attr "pent_pair" "np")
2395 (set_attr "athlon_decode" "vector")
2396 (set_attr "amdfam10_decode" "double")
2397 (set_attr "bdver1_decode" "double")])
2399 (define_insn "*swap<mode>_1"
2400 [(set (match_operand:SWI12 0 "register_operand" "+r")
2401 (match_operand:SWI12 1 "register_operand" "+r"))
2404 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2406 [(set_attr "type" "imov")
2407 (set_attr "mode" "SI")
2408 (set_attr "pent_pair" "np")
2409 (set_attr "athlon_decode" "vector")
2410 (set_attr "amdfam10_decode" "double")
2411 (set_attr "bdver1_decode" "double")])
2413 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2414 ;; is disabled for AMDFAM10
2415 (define_insn "*swap<mode>_2"
2416 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2417 (match_operand:SWI12 1 "register_operand" "+<r>"))
2420 "TARGET_PARTIAL_REG_STALL"
2421 "xchg{<imodesuffix>}\t%1, %0"
2422 [(set_attr "type" "imov")
2423 (set_attr "mode" "<MODE>")
2424 (set_attr "pent_pair" "np")
2425 (set_attr "athlon_decode" "vector")])
2427 (define_expand "movstrict<mode>"
2428 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2429 (match_operand:SWI12 1 "general_operand" ""))]
2432 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2434 if (GET_CODE (operands[0]) == SUBREG
2435 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2437 /* Don't generate memory->memory moves, go through a register */
2438 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2439 operands[1] = force_reg (<MODE>mode, operands[1]);
2442 (define_insn "*movstrict<mode>_1"
2443 [(set (strict_low_part
2444 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2445 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2446 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2447 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2448 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2449 [(set_attr "type" "imov")
2450 (set_attr "mode" "<MODE>")])
2452 (define_insn "*movstrict<mode>_xor"
2453 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2454 (match_operand:SWI12 1 "const0_operand" ""))
2455 (clobber (reg:CC FLAGS_REG))]
2457 "xor{<imodesuffix>}\t%0, %0"
2458 [(set_attr "type" "alu1")
2459 (set_attr "mode" "<MODE>")
2460 (set_attr "length_immediate" "0")])
2462 (define_insn "*mov<mode>_extv_1"
2463 [(set (match_operand:SWI24 0 "register_operand" "=R")
2464 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2468 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2469 [(set_attr "type" "imovx")
2470 (set_attr "mode" "SI")])
2472 (define_insn "*movqi_extv_1_rex64"
2473 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2474 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2479 switch (get_attr_type (insn))
2482 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2484 return "mov{b}\t{%h1, %0|%0, %h1}";
2488 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2489 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2490 (ne (symbol_ref "TARGET_MOVX")
2492 (const_string "imovx")
2493 (const_string "imov")))
2495 (if_then_else (eq_attr "type" "imovx")
2497 (const_string "QI")))])
2499 (define_insn "*movqi_extv_1"
2500 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2501 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2506 switch (get_attr_type (insn))
2509 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2511 return "mov{b}\t{%h1, %0|%0, %h1}";
2515 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2516 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2517 (ne (symbol_ref "TARGET_MOVX")
2519 (const_string "imovx")
2520 (const_string "imov")))
2522 (if_then_else (eq_attr "type" "imovx")
2524 (const_string "QI")))])
2526 (define_insn "*mov<mode>_extzv_1"
2527 [(set (match_operand:SWI48 0 "register_operand" "=R")
2528 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2532 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2533 [(set_attr "type" "imovx")
2534 (set_attr "mode" "SI")])
2536 (define_insn "*movqi_extzv_2_rex64"
2537 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2539 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2544 switch (get_attr_type (insn))
2547 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2549 return "mov{b}\t{%h1, %0|%0, %h1}";
2553 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2554 (ne (symbol_ref "TARGET_MOVX")
2556 (const_string "imovx")
2557 (const_string "imov")))
2559 (if_then_else (eq_attr "type" "imovx")
2561 (const_string "QI")))])
2563 (define_insn "*movqi_extzv_2"
2564 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2566 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2571 switch (get_attr_type (insn))
2574 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2576 return "mov{b}\t{%h1, %0|%0, %h1}";
2580 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2581 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2582 (ne (symbol_ref "TARGET_MOVX")
2584 (const_string "imovx")
2585 (const_string "imov")))
2587 (if_then_else (eq_attr "type" "imovx")
2589 (const_string "QI")))])
2591 (define_expand "mov<mode>_insv_1"
2592 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2595 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2597 (define_insn "*mov<mode>_insv_1_rex64"
2598 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2601 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2603 "mov{b}\t{%b1, %h0|%h0, %b1}"
2604 [(set_attr "type" "imov")
2605 (set_attr "mode" "QI")])
2607 (define_insn "*movsi_insv_1"
2608 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2611 (match_operand:SI 1 "general_operand" "Qmn"))]
2613 "mov{b}\t{%b1, %h0|%h0, %b1}"
2614 [(set_attr "type" "imov")
2615 (set_attr "mode" "QI")])
2617 (define_insn "*movqi_insv_2"
2618 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2621 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2624 "mov{b}\t{%h1, %h0|%h0, %h1}"
2625 [(set_attr "type" "imov")
2626 (set_attr "mode" "QI")])
2628 ;; Floating point push instructions.
2630 (define_insn "*pushtf"
2631 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2632 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2635 /* This insn should be already split before reg-stack. */
2638 [(set_attr "type" "multi")
2639 (set_attr "unit" "sse,*,*")
2640 (set_attr "mode" "TF,SI,SI")])
2643 [(set (match_operand:TF 0 "push_operand" "")
2644 (match_operand:TF 1 "sse_reg_operand" ""))]
2645 "TARGET_SSE2 && reload_completed"
2646 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2647 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2650 [(set (match_operand:TF 0 "push_operand" "")
2651 (match_operand:TF 1 "general_operand" ""))]
2652 "TARGET_SSE2 && reload_completed
2653 && !SSE_REG_P (operands[1])"
2655 "ix86_split_long_move (operands); DONE;")
2657 (define_insn "*pushxf"
2658 [(set (match_operand:XF 0 "push_operand" "=<,<")
2659 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2660 "optimize_function_for_speed_p (cfun)"
2662 /* This insn should be already split before reg-stack. */
2665 [(set_attr "type" "multi")
2666 (set_attr "unit" "i387,*")
2667 (set_attr "mode" "XF,SI")])
2669 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2670 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2671 ;; Pushing using integer instructions is longer except for constants
2672 ;; and direct memory references (assuming that any given constant is pushed
2673 ;; only once, but this ought to be handled elsewhere).
2675 (define_insn "*pushxf_nointeger"
2676 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2677 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2678 "optimize_function_for_size_p (cfun)"
2680 /* This insn should be already split before reg-stack. */
2683 [(set_attr "type" "multi")
2684 (set_attr "unit" "i387,*,*")
2685 (set_attr "mode" "XF,SI,SI")])
2688 [(set (match_operand:XF 0 "push_operand" "")
2689 (match_operand:XF 1 "fp_register_operand" ""))]
2691 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2692 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2693 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2696 [(set (match_operand:XF 0 "push_operand" "")
2697 (match_operand:XF 1 "general_operand" ""))]
2699 && !FP_REG_P (operands[1])"
2701 "ix86_split_long_move (operands); DONE;")
2703 (define_insn "*pushdf"
2704 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2705 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2706 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2708 /* This insn should be already split before reg-stack. */
2711 [(set_attr "type" "multi")
2712 (set_attr "unit" "i387,*,*")
2713 (set_attr "mode" "DF,SI,DF")])
2715 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2716 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2717 ;; On the average, pushdf using integers can be still shorter. Allow this
2718 ;; pattern for optimize_size too.
2720 (define_insn "*pushdf_nointeger"
2721 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2722 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2723 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2725 /* This insn should be already split before reg-stack. */
2728 [(set_attr "type" "multi")
2729 (set_attr "unit" "i387,*,*,*")
2730 (set_attr "mode" "DF,SI,SI,DF")])
2732 ;; %%% Kill this when call knows how to work this out.
2734 [(set (match_operand:DF 0 "push_operand" "")
2735 (match_operand:DF 1 "any_fp_register_operand" ""))]
2737 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2738 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2741 [(set (match_operand:DF 0 "push_operand" "")
2742 (match_operand:DF 1 "general_operand" ""))]
2744 && !ANY_FP_REG_P (operands[1])"
2746 "ix86_split_long_move (operands); DONE;")
2748 (define_insn "*pushsf_rex64"
2749 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2750 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2753 /* Anything else should be already split before reg-stack. */
2754 gcc_assert (which_alternative == 1);
2755 return "push{q}\t%q1";
2757 [(set_attr "type" "multi,push,multi")
2758 (set_attr "unit" "i387,*,*")
2759 (set_attr "mode" "SF,DI,SF")])
2761 (define_insn "*pushsf"
2762 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2763 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2766 /* Anything else should be already split before reg-stack. */
2767 gcc_assert (which_alternative == 1);
2768 return "push{l}\t%1";
2770 [(set_attr "type" "multi,push,multi")
2771 (set_attr "unit" "i387,*,*")
2772 (set_attr "mode" "SF,SI,SF")])
2775 [(set (match_operand:SF 0 "push_operand" "")
2776 (match_operand:SF 1 "memory_operand" ""))]
2778 && MEM_P (operands[1])
2779 && (operands[2] = find_constant_src (insn))"
2783 ;; %%% Kill this when call knows how to work this out.
2785 [(set (match_operand:SF 0 "push_operand" "")
2786 (match_operand:SF 1 "any_fp_register_operand" ""))]
2788 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2789 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2790 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2792 ;; Floating point move instructions.
2794 (define_expand "movtf"
2795 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2796 (match_operand:TF 1 "nonimmediate_operand" ""))]
2799 ix86_expand_move (TFmode, operands);
2803 (define_expand "mov<mode>"
2804 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2805 (match_operand:X87MODEF 1 "general_operand" ""))]
2807 "ix86_expand_move (<MODE>mode, operands); DONE;")
2809 (define_insn "*movtf_internal"
2810 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2811 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2813 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2815 switch (which_alternative)
2819 if (get_attr_mode (insn) == MODE_V4SF)
2820 return "%vmovaps\t{%1, %0|%0, %1}";
2822 return "%vmovdqa\t{%1, %0|%0, %1}";
2824 if (get_attr_mode (insn) == MODE_V4SF)
2825 return "%vxorps\t%0, %d0";
2827 return "%vpxor\t%0, %d0";
2835 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2836 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2838 (cond [(eq_attr "alternative" "0,2")
2840 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2842 (const_string "V4SF")
2843 (const_string "TI"))
2844 (eq_attr "alternative" "1")
2846 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2848 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2850 (const_string "V4SF")
2851 (const_string "TI"))]
2852 (const_string "DI")))])
2855 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2856 (match_operand:TF 1 "general_operand" ""))]
2858 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2860 "ix86_split_long_move (operands); DONE;")
2862 (define_insn "*movxf_internal"
2863 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2864 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2865 "optimize_function_for_speed_p (cfun)
2866 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2867 && (reload_in_progress || reload_completed
2868 || GET_CODE (operands[1]) != CONST_DOUBLE
2869 || memory_operand (operands[0], XFmode))"
2871 switch (which_alternative)
2875 return output_387_reg_move (insn, operands);
2878 return standard_80387_constant_opcode (operands[1]);
2887 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2888 (set_attr "mode" "XF,XF,XF,SI,SI")])
2890 ;; Do not use integer registers when optimizing for size
2891 (define_insn "*movxf_internal_nointeger"
2892 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2893 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2894 "optimize_function_for_size_p (cfun)
2895 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2896 && (reload_in_progress || reload_completed
2897 || standard_80387_constant_p (operands[1])
2898 || GET_CODE (operands[1]) != CONST_DOUBLE
2899 || memory_operand (operands[0], XFmode))"
2901 switch (which_alternative)
2905 return output_387_reg_move (insn, operands);
2908 return standard_80387_constant_opcode (operands[1]);
2916 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2917 (set_attr "mode" "XF,XF,XF,SI,SI")])
2920 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2921 (match_operand:XF 1 "general_operand" ""))]
2923 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2924 && ! (FP_REG_P (operands[0]) ||
2925 (GET_CODE (operands[0]) == SUBREG
2926 && FP_REG_P (SUBREG_REG (operands[0]))))
2927 && ! (FP_REG_P (operands[1]) ||
2928 (GET_CODE (operands[1]) == SUBREG
2929 && FP_REG_P (SUBREG_REG (operands[1]))))"
2931 "ix86_split_long_move (operands); DONE;")
2933 (define_insn "*movdf_internal_rex64"
2934 [(set (match_operand:DF 0 "nonimmediate_operand"
2935 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2936 (match_operand:DF 1 "general_operand"
2937 "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2938 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2939 && (reload_in_progress || reload_completed
2940 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2941 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2942 && optimize_function_for_size_p (cfun)
2943 && standard_80387_constant_p (operands[1]))
2944 || GET_CODE (operands[1]) != CONST_DOUBLE
2945 || memory_operand (operands[0], DFmode))"
2947 switch (which_alternative)
2951 return output_387_reg_move (insn, operands);
2954 return standard_80387_constant_opcode (operands[1]);
2958 return "mov{q}\t{%1, %0|%0, %1}";
2961 return "movabs{q}\t{%1, %0|%0, %1}";
2967 switch (get_attr_mode (insn))
2970 return "%vxorps\t%0, %d0";
2972 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2973 return "%vxorps\t%0, %d0";
2975 return "%vxorpd\t%0, %d0";
2977 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2978 return "%vxorps\t%0, %d0";
2980 return "%vpxor\t%0, %d0";
2987 switch (get_attr_mode (insn))
2990 return "%vmovaps\t{%1, %0|%0, %1}";
2992 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2993 return "%vmovaps\t{%1, %0|%0, %1}";
2995 return "%vmovapd\t{%1, %0|%0, %1}";
2997 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2998 return "%vmovaps\t{%1, %0|%0, %1}";
3000 return "%vmovdqa\t{%1, %0|%0, %1}";
3002 return "%vmovq\t{%1, %0|%0, %1}";
3006 if (REG_P (operands[0]) && REG_P (operands[1]))
3007 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3009 return "vmovsd\t{%1, %0|%0, %1}";
3012 return "movsd\t{%1, %0|%0, %1}";
3014 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3016 return "%vmovlps\t{%1, %d0|%d0, %1}";
3023 /* Handle broken assemblers that reqire movd instead of movq. */
3024 return "%vmovd\t{%1, %0|%0, %1}";
3030 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3033 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3035 (const_string "*")))
3036 (set (attr "length_immediate")
3038 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3040 (const_string "*")))
3041 (set (attr "prefix")
3042 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3043 (const_string "orig")
3044 (const_string "maybe_vex")))
3045 (set (attr "prefix_data16")
3046 (if_then_else (eq_attr "mode" "V1DF")
3048 (const_string "*")))
3050 (cond [(eq_attr "alternative" "0,1,2")
3052 (eq_attr "alternative" "3,4,5,6,11,12")
3055 /* For SSE1, we have many fewer alternatives. */
3056 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3057 (cond [(eq_attr "alternative" "7,8")
3058 (const_string "V4SF")
3060 (const_string "V2SF"))
3062 /* xorps is one byte shorter. */
3063 (eq_attr "alternative" "7")
3064 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3066 (const_string "V4SF")
3067 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3071 (const_string "V2DF"))
3073 /* For architectures resolving dependencies on
3074 whole SSE registers use APD move to break dependency
3075 chains, otherwise use short move to avoid extra work.
3077 movaps encodes one byte shorter. */
3078 (eq_attr "alternative" "8")
3080 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3082 (const_string "V4SF")
3083 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3085 (const_string "V2DF")
3087 (const_string "DF"))
3088 /* For architectures resolving dependencies on register
3089 parts we may avoid extra work to zero out upper part
3091 (eq_attr "alternative" "9")
3093 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3095 (const_string "V1DF")
3096 (const_string "DF"))
3098 (const_string "DF")))])
3100 (define_insn "*movdf_internal"
3101 [(set (match_operand:DF 0 "nonimmediate_operand"
3102 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3103 (match_operand:DF 1 "general_operand"
3104 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3105 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3106 && optimize_function_for_speed_p (cfun)
3107 && TARGET_INTEGER_DFMODE_MOVES
3108 && (reload_in_progress || reload_completed
3109 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3110 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3111 && optimize_function_for_size_p (cfun)
3112 && standard_80387_constant_p (operands[1]))
3113 || GET_CODE (operands[1]) != CONST_DOUBLE
3114 || memory_operand (operands[0], DFmode))"
3116 switch (which_alternative)
3120 return output_387_reg_move (insn, operands);
3123 return standard_80387_constant_opcode (operands[1]);
3130 switch (get_attr_mode (insn))
3133 return "%vxorps\t%0, %d0";
3135 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3136 return "%vxorps\t%0, %d0";
3138 return "%vxorpd\t%0, %d0";
3140 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3141 return "%vxorps\t%0, %d0";
3143 return "%vpxor\t%0, %d0";
3150 switch (get_attr_mode (insn))
3153 return "%vmovaps\t{%1, %0|%0, %1}";
3155 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3156 return "%vmovaps\t{%1, %0|%0, %1}";
3158 return "%vmovapd\t{%1, %0|%0, %1}";
3160 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3161 return "%vmovaps\t{%1, %0|%0, %1}";
3163 return "%vmovdqa\t{%1, %0|%0, %1}";
3165 return "%vmovq\t{%1, %0|%0, %1}";
3169 if (REG_P (operands[0]) && REG_P (operands[1]))
3170 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3172 return "vmovsd\t{%1, %0|%0, %1}";
3175 return "movsd\t{%1, %0|%0, %1}";
3179 if (REG_P (operands[0]))
3180 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3182 return "vmovlpd\t{%1, %0|%0, %1}";
3185 return "movlpd\t{%1, %0|%0, %1}";
3189 if (REG_P (operands[0]))
3190 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3192 return "vmovlps\t{%1, %0|%0, %1}";
3195 return "movlps\t{%1, %0|%0, %1}";
3204 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3205 (set (attr "prefix")
3206 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3207 (const_string "orig")
3208 (const_string "maybe_vex")))
3209 (set (attr "prefix_data16")
3210 (if_then_else (eq_attr "mode" "V1DF")
3212 (const_string "*")))
3214 (cond [(eq_attr "alternative" "0,1,2")
3216 (eq_attr "alternative" "3,4")
3219 /* For SSE1, we have many fewer alternatives. */
3220 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3221 (cond [(eq_attr "alternative" "5,6")
3222 (const_string "V4SF")
3224 (const_string "V2SF"))
3226 /* xorps is one byte shorter. */
3227 (eq_attr "alternative" "5")
3228 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3230 (const_string "V4SF")
3231 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3235 (const_string "V2DF"))
3237 /* For architectures resolving dependencies on
3238 whole SSE registers use APD move to break dependency
3239 chains, otherwise use short move to avoid extra work.
3241 movaps encodes one byte shorter. */
3242 (eq_attr "alternative" "6")
3244 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3246 (const_string "V4SF")
3247 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3249 (const_string "V2DF")
3251 (const_string "DF"))
3252 /* For architectures resolving dependencies on register
3253 parts we may avoid extra work to zero out upper part
3255 (eq_attr "alternative" "7")
3257 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3259 (const_string "V1DF")
3260 (const_string "DF"))
3262 (const_string "DF")))])
3264 ;; Moving is usually shorter when only FP registers are used. This separate
3265 ;; movdf pattern avoids the use of integer registers for FP operations
3266 ;; when optimizing for size.
3268 (define_insn "*movdf_internal_nointeger"
3269 [(set (match_operand:DF 0 "nonimmediate_operand"
3270 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3271 (match_operand:DF 1 "general_operand"
3272 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3273 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3274 && (optimize_function_for_size_p (cfun)
3275 || !TARGET_INTEGER_DFMODE_MOVES)
3276 && (reload_in_progress || reload_completed
3277 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3278 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3279 && optimize_function_for_size_p (cfun)
3280 && !memory_operand (operands[0], DFmode)
3281 && standard_80387_constant_p (operands[1]))
3282 || GET_CODE (operands[1]) != CONST_DOUBLE
3283 || ((optimize_function_for_size_p (cfun)
3284 || !TARGET_MEMORY_MISMATCH_STALL
3285 || reload_in_progress || reload_completed)
3286 && memory_operand (operands[0], DFmode)))"
3288 switch (which_alternative)
3292 return output_387_reg_move (insn, operands);
3295 return standard_80387_constant_opcode (operands[1]);
3302 switch (get_attr_mode (insn))
3305 return "%vxorps\t%0, %d0";
3307 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3308 return "%vxorps\t%0, %d0";
3310 return "%vxorpd\t%0, %d0";
3312 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3313 return "%vxorps\t%0, %d0";
3315 return "%vpxor\t%0, %d0";
3322 switch (get_attr_mode (insn))
3325 return "%vmovaps\t{%1, %0|%0, %1}";
3327 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3328 return "%vmovaps\t{%1, %0|%0, %1}";
3330 return "%vmovapd\t{%1, %0|%0, %1}";
3332 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3333 return "%vmovaps\t{%1, %0|%0, %1}";
3335 return "%vmovdqa\t{%1, %0|%0, %1}";
3337 return "%vmovq\t{%1, %0|%0, %1}";
3341 if (REG_P (operands[0]) && REG_P (operands[1]))
3342 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3344 return "vmovsd\t{%1, %0|%0, %1}";
3347 return "movsd\t{%1, %0|%0, %1}";
3351 if (REG_P (operands[0]))
3352 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3354 return "vmovlpd\t{%1, %0|%0, %1}";
3357 return "movlpd\t{%1, %0|%0, %1}";
3361 if (REG_P (operands[0]))
3362 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3364 return "vmovlps\t{%1, %0|%0, %1}";
3367 return "movlps\t{%1, %0|%0, %1}";
3376 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3377 (set (attr "prefix")
3378 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3379 (const_string "orig")
3380 (const_string "maybe_vex")))
3381 (set (attr "prefix_data16")
3382 (if_then_else (eq_attr "mode" "V1DF")
3384 (const_string "*")))
3386 (cond [(eq_attr "alternative" "0,1,2")
3388 (eq_attr "alternative" "3,4")
3391 /* For SSE1, we have many fewer alternatives. */
3392 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3393 (cond [(eq_attr "alternative" "5,6")
3394 (const_string "V4SF")
3396 (const_string "V2SF"))
3398 /* xorps is one byte shorter. */
3399 (eq_attr "alternative" "5")
3400 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3402 (const_string "V4SF")
3403 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3407 (const_string "V2DF"))
3409 /* For architectures resolving dependencies on
3410 whole SSE registers use APD move to break dependency
3411 chains, otherwise use short move to avoid extra work.
3413 movaps encodes one byte shorter. */
3414 (eq_attr "alternative" "6")
3416 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3418 (const_string "V4SF")
3419 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3421 (const_string "V2DF")
3423 (const_string "DF"))
3424 /* For architectures resolving dependencies on register
3425 parts we may avoid extra work to zero out upper part
3427 (eq_attr "alternative" "7")
3429 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3431 (const_string "V1DF")
3432 (const_string "DF"))
3434 (const_string "DF")))])
3437 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3438 (match_operand:DF 1 "general_operand" ""))]
3440 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3441 && ! (ANY_FP_REG_P (operands[0]) ||
3442 (GET_CODE (operands[0]) == SUBREG
3443 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3444 && ! (ANY_FP_REG_P (operands[1]) ||
3445 (GET_CODE (operands[1]) == SUBREG
3446 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3448 "ix86_split_long_move (operands); DONE;")
3450 (define_insn "*movsf_internal"
3451 [(set (match_operand:SF 0 "nonimmediate_operand"
3452 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3453 (match_operand:SF 1 "general_operand"
3454 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3455 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3456 && (reload_in_progress || reload_completed
3457 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3458 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3459 && standard_80387_constant_p (operands[1]))
3460 || GET_CODE (operands[1]) != CONST_DOUBLE
3461 || memory_operand (operands[0], SFmode))"
3463 switch (which_alternative)
3467 return output_387_reg_move (insn, operands);
3470 return standard_80387_constant_opcode (operands[1]);
3474 return "mov{l}\t{%1, %0|%0, %1}";
3476 if (get_attr_mode (insn) == MODE_TI)
3477 return "%vpxor\t%0, %d0";
3479 return "%vxorps\t%0, %d0";
3481 if (get_attr_mode (insn) == MODE_V4SF)
3482 return "%vmovaps\t{%1, %0|%0, %1}";
3484 return "%vmovss\t{%1, %d0|%d0, %1}";
3488 if (REG_P (operands[1]))
3489 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3491 return "vmovss\t{%1, %0|%0, %1}";
3494 return "movss\t{%1, %0|%0, %1}";
3496 return "%vmovss\t{%1, %0|%0, %1}";
3498 case 9: case 10: case 14: case 15:
3499 return "movd\t{%1, %0|%0, %1}";
3502 return "movq\t{%1, %0|%0, %1}";
3505 return "%vmovd\t{%1, %0|%0, %1}";
3511 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3512 (set (attr "prefix")
3513 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3514 (const_string "maybe_vex")
3515 (const_string "orig")))
3517 (cond [(eq_attr "alternative" "3,4,9,10")
3519 (eq_attr "alternative" "5")
3521 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3523 (ne (symbol_ref "TARGET_SSE2")
3525 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3528 (const_string "V4SF"))
3529 /* For architectures resolving dependencies on
3530 whole SSE registers use APS move to break dependency
3531 chains, otherwise use short move to avoid extra work.
3533 Do the same for architectures resolving dependencies on
3534 the parts. While in DF mode it is better to always handle
3535 just register parts, the SF mode is different due to lack
3536 of instructions to load just part of the register. It is
3537 better to maintain the whole registers in single format
3538 to avoid problems on using packed logical operations. */
3539 (eq_attr "alternative" "6")
3541 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3543 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3545 (const_string "V4SF")
3546 (const_string "SF"))
3547 (eq_attr "alternative" "11")
3548 (const_string "DI")]
3549 (const_string "SF")))])
3552 [(set (match_operand 0 "register_operand" "")
3553 (match_operand 1 "memory_operand" ""))]
3555 && MEM_P (operands[1])
3556 && (GET_MODE (operands[0]) == TFmode
3557 || GET_MODE (operands[0]) == XFmode
3558 || GET_MODE (operands[0]) == DFmode
3559 || GET_MODE (operands[0]) == SFmode)
3560 && (operands[2] = find_constant_src (insn))"
3561 [(set (match_dup 0) (match_dup 2))]
3563 rtx c = operands[2];
3564 rtx r = operands[0];
3566 if (GET_CODE (r) == SUBREG)
3571 if (!standard_sse_constant_p (c))
3574 else if (FP_REG_P (r))
3576 if (!standard_80387_constant_p (c))
3579 else if (MMX_REG_P (r))
3584 [(set (match_operand 0 "register_operand" "")
3585 (float_extend (match_operand 1 "memory_operand" "")))]
3587 && MEM_P (operands[1])
3588 && (GET_MODE (operands[0]) == TFmode
3589 || GET_MODE (operands[0]) == XFmode
3590 || GET_MODE (operands[0]) == DFmode
3591 || GET_MODE (operands[0]) == SFmode)
3592 && (operands[2] = find_constant_src (insn))"
3593 [(set (match_dup 0) (match_dup 2))]
3595 rtx c = operands[2];
3596 rtx r = operands[0];
3598 if (GET_CODE (r) == SUBREG)
3603 if (!standard_sse_constant_p (c))
3606 else if (FP_REG_P (r))
3608 if (!standard_80387_constant_p (c))
3611 else if (MMX_REG_P (r))
3615 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3617 [(set (match_operand:X87MODEF 0 "register_operand" "")
3618 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3619 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3620 && (standard_80387_constant_p (operands[1]) == 8
3621 || standard_80387_constant_p (operands[1]) == 9)"
3622 [(set (match_dup 0)(match_dup 1))
3624 (neg:X87MODEF (match_dup 0)))]
3628 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3629 if (real_isnegzero (&r))
3630 operands[1] = CONST0_RTX (<MODE>mode);
3632 operands[1] = CONST1_RTX (<MODE>mode);
3635 (define_insn "swapxf"
3636 [(set (match_operand:XF 0 "register_operand" "+f")
3637 (match_operand:XF 1 "register_operand" "+f"))
3642 if (STACK_TOP_P (operands[0]))
3647 [(set_attr "type" "fxch")
3648 (set_attr "mode" "XF")])
3650 (define_insn "*swap<mode>"
3651 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3652 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3655 "TARGET_80387 || reload_completed"
3657 if (STACK_TOP_P (operands[0]))
3662 [(set_attr "type" "fxch")
3663 (set_attr "mode" "<MODE>")])
3665 ;; Zero extension instructions
3667 (define_expand "zero_extendsidi2"
3668 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3669 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3674 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3679 (define_insn "*zero_extendsidi2_rex64"
3680 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3682 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3685 mov\t{%k1, %k0|%k0, %k1}
3687 movd\t{%1, %0|%0, %1}
3688 movd\t{%1, %0|%0, %1}
3689 %vmovd\t{%1, %0|%0, %1}
3690 %vmovd\t{%1, %0|%0, %1}"
3691 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3692 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3693 (set_attr "prefix_0f" "0,*,*,*,*,*")
3694 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3697 [(set (match_operand:DI 0 "memory_operand" "")
3698 (zero_extend:DI (match_dup 0)))]
3700 [(set (match_dup 4) (const_int 0))]
3701 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3703 ;; %%% Kill me once multi-word ops are sane.
3704 (define_insn "zero_extendsidi2_1"
3705 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3707 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3708 (clobber (reg:CC FLAGS_REG))]
3714 movd\t{%1, %0|%0, %1}
3715 movd\t{%1, %0|%0, %1}
3716 %vmovd\t{%1, %0|%0, %1}
3717 %vmovd\t{%1, %0|%0, %1}"
3718 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3719 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3720 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3723 [(set (match_operand:DI 0 "register_operand" "")
3724 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3725 (clobber (reg:CC FLAGS_REG))]
3726 "!TARGET_64BIT && reload_completed
3727 && true_regnum (operands[0]) == true_regnum (operands[1])"
3728 [(set (match_dup 4) (const_int 0))]
3729 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3732 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3733 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3734 (clobber (reg:CC FLAGS_REG))]
3735 "!TARGET_64BIT && reload_completed
3736 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3737 [(set (match_dup 3) (match_dup 1))
3738 (set (match_dup 4) (const_int 0))]
3739 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3741 (define_insn "zero_extend<mode>di2"
3742 [(set (match_operand:DI 0 "register_operand" "=r")
3744 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3746 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3747 [(set_attr "type" "imovx")
3748 (set_attr "mode" "SI")])
3750 (define_expand "zero_extendhisi2"
3751 [(set (match_operand:SI 0 "register_operand" "")
3752 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3755 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3757 operands[1] = force_reg (HImode, operands[1]);
3758 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3763 (define_insn_and_split "zero_extendhisi2_and"
3764 [(set (match_operand:SI 0 "register_operand" "=r")
3765 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3766 (clobber (reg:CC FLAGS_REG))]
3767 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3769 "&& reload_completed"
3770 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3771 (clobber (reg:CC FLAGS_REG))])]
3773 [(set_attr "type" "alu1")
3774 (set_attr "mode" "SI")])
3776 (define_insn "*zero_extendhisi2_movzwl"
3777 [(set (match_operand:SI 0 "register_operand" "=r")
3778 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3779 "!TARGET_ZERO_EXTEND_WITH_AND
3780 || optimize_function_for_size_p (cfun)"
3781 "movz{wl|x}\t{%1, %0|%0, %1}"
3782 [(set_attr "type" "imovx")
3783 (set_attr "mode" "SI")])
3785 (define_expand "zero_extendqi<mode>2"
3787 [(set (match_operand:SWI24 0 "register_operand" "")
3788 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3789 (clobber (reg:CC FLAGS_REG))])])
3791 (define_insn "*zero_extendqi<mode>2_and"
3792 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3793 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3794 (clobber (reg:CC FLAGS_REG))]
3795 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3797 [(set_attr "type" "alu1")
3798 (set_attr "mode" "<MODE>")])
3800 ;; When source and destination does not overlap, clear destination
3801 ;; first and then do the movb
3803 [(set (match_operand:SWI24 0 "register_operand" "")
3804 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3805 (clobber (reg:CC FLAGS_REG))]
3807 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3808 && ANY_QI_REG_P (operands[0])
3809 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3810 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3811 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3813 operands[2] = gen_lowpart (QImode, operands[0]);
3814 ix86_expand_clear (operands[0]);
3817 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3818 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3819 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3820 (clobber (reg:CC FLAGS_REG))]
3821 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3823 [(set_attr "type" "imovx,alu1")
3824 (set_attr "mode" "<MODE>")])
3826 ;; For the movzbl case strip only the clobber
3828 [(set (match_operand:SWI24 0 "register_operand" "")
3829 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3830 (clobber (reg:CC FLAGS_REG))]
3832 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3833 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3835 (zero_extend:SWI24 (match_dup 1)))])
3837 ; zero extend to SImode to avoid partial register stalls
3838 (define_insn "*zero_extendqi<mode>2_movzbl"
3839 [(set (match_operand:SWI24 0 "register_operand" "=r")
3840 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3842 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3843 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3844 [(set_attr "type" "imovx")
3845 (set_attr "mode" "SI")])
3847 ;; Rest is handled by single and.
3849 [(set (match_operand:SWI24 0 "register_operand" "")
3850 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3851 (clobber (reg:CC FLAGS_REG))]
3853 && true_regnum (operands[0]) == true_regnum (operands[1])"
3854 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3855 (clobber (reg:CC FLAGS_REG))])])
3857 ;; Sign extension instructions
3859 (define_expand "extendsidi2"
3860 [(set (match_operand:DI 0 "register_operand" "")
3861 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3866 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3871 (define_insn "*extendsidi2_rex64"
3872 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3873 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3877 movs{lq|x}\t{%1, %0|%0, %1}"
3878 [(set_attr "type" "imovx")
3879 (set_attr "mode" "DI")
3880 (set_attr "prefix_0f" "0")
3881 (set_attr "modrm" "0,1")])
3883 (define_insn "extendsidi2_1"
3884 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3885 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3886 (clobber (reg:CC FLAGS_REG))
3887 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3891 ;; Extend to memory case when source register does die.
3893 [(set (match_operand:DI 0 "memory_operand" "")
3894 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3895 (clobber (reg:CC FLAGS_REG))
3896 (clobber (match_operand:SI 2 "register_operand" ""))]
3898 && dead_or_set_p (insn, operands[1])
3899 && !reg_mentioned_p (operands[1], operands[0]))"
3900 [(set (match_dup 3) (match_dup 1))
3901 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3902 (clobber (reg:CC FLAGS_REG))])
3903 (set (match_dup 4) (match_dup 1))]
3904 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3906 ;; Extend to memory case when source register does not die.
3908 [(set (match_operand:DI 0 "memory_operand" "")
3909 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3910 (clobber (reg:CC FLAGS_REG))
3911 (clobber (match_operand:SI 2 "register_operand" ""))]
3915 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3917 emit_move_insn (operands[3], operands[1]);
3919 /* Generate a cltd if possible and doing so it profitable. */
3920 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3921 && true_regnum (operands[1]) == AX_REG
3922 && true_regnum (operands[2]) == DX_REG)
3924 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3928 emit_move_insn (operands[2], operands[1]);
3929 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3931 emit_move_insn (operands[4], operands[2]);
3935 ;; Extend to register case. Optimize case where source and destination
3936 ;; registers match and cases where we can use cltd.
3938 [(set (match_operand:DI 0 "register_operand" "")
3939 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3940 (clobber (reg:CC FLAGS_REG))
3941 (clobber (match_scratch:SI 2 ""))]
3945 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3947 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3948 emit_move_insn (operands[3], operands[1]);
3950 /* Generate a cltd if possible and doing so it profitable. */
3951 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3952 && true_regnum (operands[3]) == AX_REG
3953 && true_regnum (operands[4]) == DX_REG)
3955 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3959 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3960 emit_move_insn (operands[4], operands[1]);
3962 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3966 (define_insn "extend<mode>di2"
3967 [(set (match_operand:DI 0 "register_operand" "=r")
3969 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3971 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3972 [(set_attr "type" "imovx")
3973 (set_attr "mode" "DI")])
3975 (define_insn "extendhisi2"
3976 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3977 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3980 switch (get_attr_prefix_0f (insn))
3983 return "{cwtl|cwde}";
3985 return "movs{wl|x}\t{%1, %0|%0, %1}";
3988 [(set_attr "type" "imovx")
3989 (set_attr "mode" "SI")
3990 (set (attr "prefix_0f")
3991 ;; movsx is short decodable while cwtl is vector decoded.
3992 (if_then_else (and (eq_attr "cpu" "!k6")
3993 (eq_attr "alternative" "0"))
3995 (const_string "1")))
3997 (if_then_else (eq_attr "prefix_0f" "0")
3999 (const_string "1")))])
4001 (define_insn "*extendhisi2_zext"
4002 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4005 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4008 switch (get_attr_prefix_0f (insn))
4011 return "{cwtl|cwde}";
4013 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4016 [(set_attr "type" "imovx")
4017 (set_attr "mode" "SI")
4018 (set (attr "prefix_0f")
4019 ;; movsx is short decodable while cwtl is vector decoded.
4020 (if_then_else (and (eq_attr "cpu" "!k6")
4021 (eq_attr "alternative" "0"))
4023 (const_string "1")))
4025 (if_then_else (eq_attr "prefix_0f" "0")
4027 (const_string "1")))])
4029 (define_insn "extendqisi2"
4030 [(set (match_operand:SI 0 "register_operand" "=r")
4031 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4033 "movs{bl|x}\t{%1, %0|%0, %1}"
4034 [(set_attr "type" "imovx")
4035 (set_attr "mode" "SI")])
4037 (define_insn "*extendqisi2_zext"
4038 [(set (match_operand:DI 0 "register_operand" "=r")
4040 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4042 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4043 [(set_attr "type" "imovx")
4044 (set_attr "mode" "SI")])
4046 (define_insn "extendqihi2"
4047 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4048 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4051 switch (get_attr_prefix_0f (insn))
4054 return "{cbtw|cbw}";
4056 return "movs{bw|x}\t{%1, %0|%0, %1}";
4059 [(set_attr "type" "imovx")
4060 (set_attr "mode" "HI")
4061 (set (attr "prefix_0f")
4062 ;; movsx is short decodable while cwtl is vector decoded.
4063 (if_then_else (and (eq_attr "cpu" "!k6")
4064 (eq_attr "alternative" "0"))
4066 (const_string "1")))
4068 (if_then_else (eq_attr "prefix_0f" "0")
4070 (const_string "1")))])
4072 ;; Conversions between float and double.
4074 ;; These are all no-ops in the model used for the 80387.
4075 ;; So just emit moves.
4077 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4079 [(set (match_operand:DF 0 "push_operand" "")
4080 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4082 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4083 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4086 [(set (match_operand:XF 0 "push_operand" "")
4087 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4089 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4090 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4091 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4093 (define_expand "extendsfdf2"
4094 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4095 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4096 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4098 /* ??? Needed for compress_float_constant since all fp constants
4099 are TARGET_LEGITIMATE_CONSTANT_P. */
4100 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4102 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4103 && standard_80387_constant_p (operands[1]) > 0)
4105 operands[1] = simplify_const_unary_operation
4106 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4107 emit_move_insn_1 (operands[0], operands[1]);
4110 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4114 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4116 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4118 We do the conversion post reload to avoid producing of 128bit spills
4119 that might lead to ICE on 32bit target. The sequence unlikely combine
4122 [(set (match_operand:DF 0 "register_operand" "")
4124 (match_operand:SF 1 "nonimmediate_operand" "")))]
4125 "TARGET_USE_VECTOR_FP_CONVERTS
4126 && optimize_insn_for_speed_p ()
4127 && reload_completed && SSE_REG_P (operands[0])"
4132 (parallel [(const_int 0) (const_int 1)]))))]
4134 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4135 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4136 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4137 Try to avoid move when unpacking can be done in source. */
4138 if (REG_P (operands[1]))
4140 /* If it is unsafe to overwrite upper half of source, we need
4141 to move to destination and unpack there. */
4142 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4143 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4144 && true_regnum (operands[0]) != true_regnum (operands[1]))
4146 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4147 emit_move_insn (tmp, operands[1]);
4150 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4151 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4155 emit_insn (gen_vec_setv4sf_0 (operands[3],
4156 CONST0_RTX (V4SFmode), operands[1]));
4159 (define_insn "*extendsfdf2_mixed"
4160 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4162 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4163 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4165 switch (which_alternative)
4169 return output_387_reg_move (insn, operands);
4172 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4178 [(set_attr "type" "fmov,fmov,ssecvt")
4179 (set_attr "prefix" "orig,orig,maybe_vex")
4180 (set_attr "mode" "SF,XF,DF")])
4182 (define_insn "*extendsfdf2_sse"
4183 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4184 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4185 "TARGET_SSE2 && TARGET_SSE_MATH"
4186 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4187 [(set_attr "type" "ssecvt")
4188 (set_attr "prefix" "maybe_vex")
4189 (set_attr "mode" "DF")])
4191 (define_insn "*extendsfdf2_i387"
4192 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4193 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4195 "* return output_387_reg_move (insn, operands);"
4196 [(set_attr "type" "fmov")
4197 (set_attr "mode" "SF,XF")])
4199 (define_expand "extend<mode>xf2"
4200 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4201 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4204 /* ??? Needed for compress_float_constant since all fp constants
4205 are TARGET_LEGITIMATE_CONSTANT_P. */
4206 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4208 if (standard_80387_constant_p (operands[1]) > 0)
4210 operands[1] = simplify_const_unary_operation
4211 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4212 emit_move_insn_1 (operands[0], operands[1]);
4215 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4219 (define_insn "*extend<mode>xf2_i387"
4220 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4222 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4224 "* return output_387_reg_move (insn, operands);"
4225 [(set_attr "type" "fmov")
4226 (set_attr "mode" "<MODE>,XF")])
4228 ;; %%% This seems bad bad news.
4229 ;; This cannot output into an f-reg because there is no way to be sure
4230 ;; of truncating in that case. Otherwise this is just like a simple move
4231 ;; insn. So we pretend we can output to a reg in order to get better
4232 ;; register preferencing, but we really use a stack slot.
4234 ;; Conversion from DFmode to SFmode.
4236 (define_expand "truncdfsf2"
4237 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4239 (match_operand:DF 1 "nonimmediate_operand" "")))]
4240 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4242 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4244 else if (flag_unsafe_math_optimizations)
4248 enum ix86_stack_slot slot = (virtuals_instantiated
4251 rtx temp = assign_386_stack_local (SFmode, slot);
4252 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4257 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4259 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4261 We do the conversion post reload to avoid producing of 128bit spills
4262 that might lead to ICE on 32bit target. The sequence unlikely combine
4265 [(set (match_operand:SF 0 "register_operand" "")
4267 (match_operand:DF 1 "nonimmediate_operand" "")))]
4268 "TARGET_USE_VECTOR_FP_CONVERTS
4269 && optimize_insn_for_speed_p ()
4270 && reload_completed && SSE_REG_P (operands[0])"
4273 (float_truncate:V2SF
4277 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4278 operands[3] = CONST0_RTX (V2SFmode);
4279 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4280 /* Use movsd for loading from memory, unpcklpd for registers.
4281 Try to avoid move when unpacking can be done in source, or SSE3
4282 movddup is available. */
4283 if (REG_P (operands[1]))
4286 && true_regnum (operands[0]) != true_regnum (operands[1])
4287 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4288 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4290 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4291 emit_move_insn (tmp, operands[1]);
4294 else if (!TARGET_SSE3)
4295 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4296 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4299 emit_insn (gen_sse2_loadlpd (operands[4],
4300 CONST0_RTX (V2DFmode), operands[1]));
4303 (define_expand "truncdfsf2_with_temp"
4304 [(parallel [(set (match_operand:SF 0 "" "")
4305 (float_truncate:SF (match_operand:DF 1 "" "")))
4306 (clobber (match_operand:SF 2 "" ""))])])
4308 (define_insn "*truncdfsf_fast_mixed"
4309 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4311 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4312 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4314 switch (which_alternative)
4317 return output_387_reg_move (insn, operands);
4319 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4324 [(set_attr "type" "fmov,ssecvt")
4325 (set_attr "prefix" "orig,maybe_vex")
4326 (set_attr "mode" "SF")])
4328 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4329 ;; because nothing we do here is unsafe.
4330 (define_insn "*truncdfsf_fast_sse"
4331 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4333 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4334 "TARGET_SSE2 && TARGET_SSE_MATH"
4335 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4336 [(set_attr "type" "ssecvt")
4337 (set_attr "prefix" "maybe_vex")
4338 (set_attr "mode" "SF")])
4340 (define_insn "*truncdfsf_fast_i387"
4341 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4343 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4344 "TARGET_80387 && flag_unsafe_math_optimizations"
4345 "* return output_387_reg_move (insn, operands);"
4346 [(set_attr "type" "fmov")
4347 (set_attr "mode" "SF")])
4349 (define_insn "*truncdfsf_mixed"
4350 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4352 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4353 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4354 "TARGET_MIX_SSE_I387"
4356 switch (which_alternative)
4359 return output_387_reg_move (insn, operands);
4361 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4367 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4368 (set_attr "unit" "*,*,i387,i387,i387")
4369 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4370 (set_attr "mode" "SF")])
4372 (define_insn "*truncdfsf_i387"
4373 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4375 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4376 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4379 switch (which_alternative)
4382 return output_387_reg_move (insn, operands);
4388 [(set_attr "type" "fmov,multi,multi,multi")
4389 (set_attr "unit" "*,i387,i387,i387")
4390 (set_attr "mode" "SF")])
4392 (define_insn "*truncdfsf2_i387_1"
4393 [(set (match_operand:SF 0 "memory_operand" "=m")
4395 (match_operand:DF 1 "register_operand" "f")))]
4397 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4398 && !TARGET_MIX_SSE_I387"
4399 "* return output_387_reg_move (insn, operands);"
4400 [(set_attr "type" "fmov")
4401 (set_attr "mode" "SF")])
4404 [(set (match_operand:SF 0 "register_operand" "")
4406 (match_operand:DF 1 "fp_register_operand" "")))
4407 (clobber (match_operand 2 "" ""))]
4409 [(set (match_dup 2) (match_dup 1))
4410 (set (match_dup 0) (match_dup 2))]
4411 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4413 ;; Conversion from XFmode to {SF,DF}mode
4415 (define_expand "truncxf<mode>2"
4416 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4417 (float_truncate:MODEF
4418 (match_operand:XF 1 "register_operand" "")))
4419 (clobber (match_dup 2))])]
4422 if (flag_unsafe_math_optimizations)
4424 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4425 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4426 if (reg != operands[0])
4427 emit_move_insn (operands[0], reg);
4432 enum ix86_stack_slot slot = (virtuals_instantiated
4435 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4439 (define_insn "*truncxfsf2_mixed"
4440 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4442 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4443 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4446 gcc_assert (!which_alternative);
4447 return output_387_reg_move (insn, operands);
4449 [(set_attr "type" "fmov,multi,multi,multi")
4450 (set_attr "unit" "*,i387,i387,i387")
4451 (set_attr "mode" "SF")])
4453 (define_insn "*truncxfdf2_mixed"
4454 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4456 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4457 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4460 gcc_assert (!which_alternative);
4461 return output_387_reg_move (insn, operands);
4463 [(set_attr "type" "fmov,multi,multi,multi")
4464 (set_attr "unit" "*,i387,i387,i387")
4465 (set_attr "mode" "DF")])
4467 (define_insn "truncxf<mode>2_i387_noop"
4468 [(set (match_operand:MODEF 0 "register_operand" "=f")
4469 (float_truncate:MODEF
4470 (match_operand:XF 1 "register_operand" "f")))]
4471 "TARGET_80387 && flag_unsafe_math_optimizations"
4472 "* return output_387_reg_move (insn, operands);"
4473 [(set_attr "type" "fmov")
4474 (set_attr "mode" "<MODE>")])
4476 (define_insn "*truncxf<mode>2_i387"
4477 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4478 (float_truncate:MODEF
4479 (match_operand:XF 1 "register_operand" "f")))]
4481 "* return output_387_reg_move (insn, operands);"
4482 [(set_attr "type" "fmov")
4483 (set_attr "mode" "<MODE>")])
4486 [(set (match_operand:MODEF 0 "register_operand" "")
4487 (float_truncate:MODEF
4488 (match_operand:XF 1 "register_operand" "")))
4489 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4490 "TARGET_80387 && reload_completed"
4491 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4492 (set (match_dup 0) (match_dup 2))])
4495 [(set (match_operand:MODEF 0 "memory_operand" "")
4496 (float_truncate:MODEF
4497 (match_operand:XF 1 "register_operand" "")))
4498 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4500 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4502 ;; Signed conversion to DImode.
4504 (define_expand "fix_truncxfdi2"
4505 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4506 (fix:DI (match_operand:XF 1 "register_operand" "")))
4507 (clobber (reg:CC FLAGS_REG))])]
4512 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4517 (define_expand "fix_trunc<mode>di2"
4518 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4519 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4520 (clobber (reg:CC FLAGS_REG))])]
4521 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4524 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4526 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4529 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4531 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4532 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4533 if (out != operands[0])
4534 emit_move_insn (operands[0], out);
4539 ;; Signed conversion to SImode.
4541 (define_expand "fix_truncxfsi2"
4542 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4543 (fix:SI (match_operand:XF 1 "register_operand" "")))
4544 (clobber (reg:CC FLAGS_REG))])]
4549 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4554 (define_expand "fix_trunc<mode>si2"
4555 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4556 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4557 (clobber (reg:CC FLAGS_REG))])]
4558 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4561 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4563 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4566 if (SSE_FLOAT_MODE_P (<MODE>mode))
4568 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4569 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4570 if (out != operands[0])
4571 emit_move_insn (operands[0], out);
4576 ;; Signed conversion to HImode.
4578 (define_expand "fix_trunc<mode>hi2"
4579 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4580 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4581 (clobber (reg:CC FLAGS_REG))])]
4583 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4587 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4592 ;; Unsigned conversion to SImode.
4594 (define_expand "fixuns_trunc<mode>si2"
4596 [(set (match_operand:SI 0 "register_operand" "")
4598 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4600 (clobber (match_scratch:<ssevecmode> 3 ""))
4601 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4602 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4604 enum machine_mode mode = <MODE>mode;
4605 enum machine_mode vecmode = <ssevecmode>mode;
4606 REAL_VALUE_TYPE TWO31r;
4609 if (optimize_insn_for_size_p ())
4612 real_ldexp (&TWO31r, &dconst1, 31);
4613 two31 = const_double_from_real_value (TWO31r, mode);
4614 two31 = ix86_build_const_vector (vecmode, true, two31);
4615 operands[2] = force_reg (vecmode, two31);
4618 (define_insn_and_split "*fixuns_trunc<mode>_1"
4619 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4621 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4622 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4623 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4624 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4625 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4626 && optimize_function_for_speed_p (cfun)"
4628 "&& reload_completed"
4631 ix86_split_convert_uns_si_sse (operands);
4635 ;; Unsigned conversion to HImode.
4636 ;; Without these patterns, we'll try the unsigned SI conversion which
4637 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4639 (define_expand "fixuns_trunc<mode>hi2"
4641 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4642 (set (match_operand:HI 0 "nonimmediate_operand" "")
4643 (subreg:HI (match_dup 2) 0))]
4644 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4645 "operands[2] = gen_reg_rtx (SImode);")
4647 ;; When SSE is available, it is always faster to use it!
4648 (define_insn "fix_trunc<mode>di_sse"
4649 [(set (match_operand:DI 0 "register_operand" "=r,r")
4650 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4651 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4652 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4653 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4654 [(set_attr "type" "sseicvt")
4655 (set_attr "prefix" "maybe_vex")
4656 (set_attr "prefix_rex" "1")
4657 (set_attr "mode" "<MODE>")
4658 (set_attr "athlon_decode" "double,vector")
4659 (set_attr "amdfam10_decode" "double,double")
4660 (set_attr "bdver1_decode" "double,double")])
4662 (define_insn "fix_trunc<mode>si_sse"
4663 [(set (match_operand:SI 0 "register_operand" "=r,r")
4664 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4665 "SSE_FLOAT_MODE_P (<MODE>mode)
4666 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4667 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4668 [(set_attr "type" "sseicvt")
4669 (set_attr "prefix" "maybe_vex")
4670 (set_attr "mode" "<MODE>")
4671 (set_attr "athlon_decode" "double,vector")
4672 (set_attr "amdfam10_decode" "double,double")
4673 (set_attr "bdver1_decode" "double,double")])
4675 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4677 [(set (match_operand:MODEF 0 "register_operand" "")
4678 (match_operand:MODEF 1 "memory_operand" ""))
4679 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4680 (fix:SSEMODEI24 (match_dup 0)))]
4681 "TARGET_SHORTEN_X87_SSE
4682 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4683 && peep2_reg_dead_p (2, operands[0])"
4684 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4686 ;; Avoid vector decoded forms of the instruction.
4688 [(match_scratch:DF 2 "Y2")
4689 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4690 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4691 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4692 [(set (match_dup 2) (match_dup 1))
4693 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4696 [(match_scratch:SF 2 "x")
4697 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4698 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4699 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4700 [(set (match_dup 2) (match_dup 1))
4701 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4703 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4704 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4705 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4706 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4708 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4709 && (TARGET_64BIT || <MODE>mode != DImode))
4711 && can_create_pseudo_p ()"
4716 if (memory_operand (operands[0], VOIDmode))
4717 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4720 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4721 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4727 [(set_attr "type" "fisttp")
4728 (set_attr "mode" "<MODE>")])
4730 (define_insn "fix_trunc<mode>_i387_fisttp"
4731 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4732 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4733 (clobber (match_scratch:XF 2 "=&1f"))]
4734 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4736 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4737 && (TARGET_64BIT || <MODE>mode != DImode))
4738 && TARGET_SSE_MATH)"
4739 "* return output_fix_trunc (insn, operands, 1);"
4740 [(set_attr "type" "fisttp")
4741 (set_attr "mode" "<MODE>")])
4743 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4744 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4745 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4746 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4747 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4748 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4750 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4751 && (TARGET_64BIT || <MODE>mode != DImode))
4752 && TARGET_SSE_MATH)"
4754 [(set_attr "type" "fisttp")
4755 (set_attr "mode" "<MODE>")])
4758 [(set (match_operand:X87MODEI 0 "register_operand" "")
4759 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4760 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4761 (clobber (match_scratch 3 ""))]
4763 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4764 (clobber (match_dup 3))])
4765 (set (match_dup 0) (match_dup 2))])
4768 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4769 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4770 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4771 (clobber (match_scratch 3 ""))]
4773 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4774 (clobber (match_dup 3))])])
4776 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4777 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4778 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4779 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4780 ;; function in i386.c.
4781 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4782 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4783 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4784 (clobber (reg:CC FLAGS_REG))]
4785 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4787 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4788 && (TARGET_64BIT || <MODE>mode != DImode))
4789 && can_create_pseudo_p ()"
4794 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4796 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4797 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4798 if (memory_operand (operands[0], VOIDmode))
4799 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4800 operands[2], operands[3]));
4803 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4804 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4805 operands[2], operands[3],
4810 [(set_attr "type" "fistp")
4811 (set_attr "i387_cw" "trunc")
4812 (set_attr "mode" "<MODE>")])
4814 (define_insn "fix_truncdi_i387"
4815 [(set (match_operand:DI 0 "memory_operand" "=m")
4816 (fix:DI (match_operand 1 "register_operand" "f")))
4817 (use (match_operand:HI 2 "memory_operand" "m"))
4818 (use (match_operand:HI 3 "memory_operand" "m"))
4819 (clobber (match_scratch:XF 4 "=&1f"))]
4820 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4822 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4823 "* return output_fix_trunc (insn, operands, 0);"
4824 [(set_attr "type" "fistp")
4825 (set_attr "i387_cw" "trunc")
4826 (set_attr "mode" "DI")])
4828 (define_insn "fix_truncdi_i387_with_temp"
4829 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4830 (fix:DI (match_operand 1 "register_operand" "f,f")))
4831 (use (match_operand:HI 2 "memory_operand" "m,m"))
4832 (use (match_operand:HI 3 "memory_operand" "m,m"))
4833 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4834 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4835 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4837 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4839 [(set_attr "type" "fistp")
4840 (set_attr "i387_cw" "trunc")
4841 (set_attr "mode" "DI")])
4844 [(set (match_operand:DI 0 "register_operand" "")
4845 (fix:DI (match_operand 1 "register_operand" "")))
4846 (use (match_operand:HI 2 "memory_operand" ""))
4847 (use (match_operand:HI 3 "memory_operand" ""))
4848 (clobber (match_operand:DI 4 "memory_operand" ""))
4849 (clobber (match_scratch 5 ""))]
4851 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4854 (clobber (match_dup 5))])
4855 (set (match_dup 0) (match_dup 4))])
4858 [(set (match_operand:DI 0 "memory_operand" "")
4859 (fix:DI (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:DI 4 "memory_operand" ""))
4863 (clobber (match_scratch 5 ""))]
4865 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4868 (clobber (match_dup 5))])])
4870 (define_insn "fix_trunc<mode>_i387"
4871 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4872 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4873 (use (match_operand:HI 2 "memory_operand" "m"))
4874 (use (match_operand:HI 3 "memory_operand" "m"))]
4875 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4877 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4878 "* return output_fix_trunc (insn, operands, 0);"
4879 [(set_attr "type" "fistp")
4880 (set_attr "i387_cw" "trunc")
4881 (set_attr "mode" "<MODE>")])
4883 (define_insn "fix_trunc<mode>_i387_with_temp"
4884 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4885 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4886 (use (match_operand:HI 2 "memory_operand" "m,m"))
4887 (use (match_operand:HI 3 "memory_operand" "m,m"))
4888 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4889 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4891 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4893 [(set_attr "type" "fistp")
4894 (set_attr "i387_cw" "trunc")
4895 (set_attr "mode" "<MODE>")])
4898 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4899 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4900 (use (match_operand:HI 2 "memory_operand" ""))
4901 (use (match_operand:HI 3 "memory_operand" ""))
4902 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4904 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4906 (use (match_dup 3))])
4907 (set (match_dup 0) (match_dup 4))])
4910 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4911 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4912 (use (match_operand:HI 2 "memory_operand" ""))
4913 (use (match_operand:HI 3 "memory_operand" ""))
4914 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4916 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4918 (use (match_dup 3))])])
4920 (define_insn "x86_fnstcw_1"
4921 [(set (match_operand:HI 0 "memory_operand" "=m")
4922 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4925 [(set (attr "length")
4926 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4927 (set_attr "mode" "HI")
4928 (set_attr "unit" "i387")
4929 (set_attr "bdver1_decode" "vector")])
4931 (define_insn "x86_fldcw_1"
4932 [(set (reg:HI FPCR_REG)
4933 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4936 [(set (attr "length")
4937 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4938 (set_attr "mode" "HI")
4939 (set_attr "unit" "i387")
4940 (set_attr "athlon_decode" "vector")
4941 (set_attr "amdfam10_decode" "vector")
4942 (set_attr "bdver1_decode" "vector")])
4944 ;; Conversion between fixed point and floating point.
4946 ;; Even though we only accept memory inputs, the backend _really_
4947 ;; wants to be able to do this between registers.
4949 (define_expand "floathi<mode>2"
4950 [(set (match_operand:X87MODEF 0 "register_operand" "")
4951 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4953 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4954 || TARGET_MIX_SSE_I387)")
4956 ;; Pre-reload splitter to add memory clobber to the pattern.
4957 (define_insn_and_split "*floathi<mode>2_1"
4958 [(set (match_operand:X87MODEF 0 "register_operand" "")
4959 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4962 || TARGET_MIX_SSE_I387)
4963 && can_create_pseudo_p ()"
4966 [(parallel [(set (match_dup 0)
4967 (float:X87MODEF (match_dup 1)))
4968 (clobber (match_dup 2))])]
4969 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4971 (define_insn "*floathi<mode>2_i387_with_temp"
4972 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4973 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4974 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4977 || TARGET_MIX_SSE_I387)"
4979 [(set_attr "type" "fmov,multi")
4980 (set_attr "mode" "<MODE>")
4981 (set_attr "unit" "*,i387")
4982 (set_attr "fp_int_src" "true")])
4984 (define_insn "*floathi<mode>2_i387"
4985 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4986 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4988 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4989 || TARGET_MIX_SSE_I387)"
4991 [(set_attr "type" "fmov")
4992 (set_attr "mode" "<MODE>")
4993 (set_attr "fp_int_src" "true")])
4996 [(set (match_operand:X87MODEF 0 "register_operand" "")
4997 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4998 (clobber (match_operand:HI 2 "memory_operand" ""))]
5000 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5001 || TARGET_MIX_SSE_I387)
5002 && reload_completed"
5003 [(set (match_dup 2) (match_dup 1))
5004 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5007 [(set (match_operand:X87MODEF 0 "register_operand" "")
5008 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5009 (clobber (match_operand:HI 2 "memory_operand" ""))]
5011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5012 || TARGET_MIX_SSE_I387)
5013 && reload_completed"
5014 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5016 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5017 [(set (match_operand:X87MODEF 0 "register_operand" "")
5019 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5021 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5022 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5024 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5025 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5026 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5028 rtx reg = gen_reg_rtx (XFmode);
5029 rtx (*insn)(rtx, rtx);
5031 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5033 if (<X87MODEF:MODE>mode == SFmode)
5034 insn = gen_truncxfsf2;
5035 else if (<X87MODEF:MODE>mode == DFmode)
5036 insn = gen_truncxfdf2;
5040 emit_insn (insn (operands[0], reg));
5045 ;; Pre-reload splitter to add memory clobber to the pattern.
5046 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5047 [(set (match_operand:X87MODEF 0 "register_operand" "")
5048 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5050 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5051 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5052 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5053 || TARGET_MIX_SSE_I387))
5054 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5055 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5056 && ((<SSEMODEI24:MODE>mode == SImode
5057 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5058 && optimize_function_for_speed_p (cfun)
5059 && flag_trapping_math)
5060 || !(TARGET_INTER_UNIT_CONVERSIONS
5061 || optimize_function_for_size_p (cfun)))))
5062 && can_create_pseudo_p ()"
5065 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5066 (clobber (match_dup 2))])]
5068 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5070 /* Avoid store forwarding (partial memory) stall penalty
5071 by passing DImode value through XMM registers. */
5072 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5073 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5074 && optimize_function_for_speed_p (cfun))
5076 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5083 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5084 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5086 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5087 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5088 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5089 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5091 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5092 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5093 (set_attr "unit" "*,i387,*,*,*")
5094 (set_attr "athlon_decode" "*,*,double,direct,double")
5095 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5096 (set_attr "bdver1_decode" "*,*,double,direct,double")
5097 (set_attr "fp_int_src" "true")])
5099 (define_insn "*floatsi<mode>2_vector_mixed"
5100 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5101 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5102 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5103 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5107 [(set_attr "type" "fmov,sseicvt")
5108 (set_attr "mode" "<MODE>,<ssevecmode>")
5109 (set_attr "unit" "i387,*")
5110 (set_attr "athlon_decode" "*,direct")
5111 (set_attr "amdfam10_decode" "*,double")
5112 (set_attr "bdver1_decode" "*,direct")
5113 (set_attr "fp_int_src" "true")])
5115 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5116 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5118 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5119 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5120 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5121 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5123 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5124 (set_attr "mode" "<MODEF:MODE>")
5125 (set_attr "unit" "*,i387,*,*")
5126 (set_attr "athlon_decode" "*,*,double,direct")
5127 (set_attr "amdfam10_decode" "*,*,vector,double")
5128 (set_attr "bdver1_decode" "*,*,double,direct")
5129 (set_attr "fp_int_src" "true")])
5132 [(set (match_operand:MODEF 0 "register_operand" "")
5133 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5134 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5135 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5136 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5137 && TARGET_INTER_UNIT_CONVERSIONS
5139 && (SSE_REG_P (operands[0])
5140 || (GET_CODE (operands[0]) == SUBREG
5141 && SSE_REG_P (operands[0])))"
5142 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5145 [(set (match_operand:MODEF 0 "register_operand" "")
5146 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5147 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
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))
5152 && (SSE_REG_P (operands[0])
5153 || (GET_CODE (operands[0]) == SUBREG
5154 && SSE_REG_P (operands[0])))"
5155 [(set (match_dup 2) (match_dup 1))
5156 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5158 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5159 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5161 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5162 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5163 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5164 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5167 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5168 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5169 [(set_attr "type" "fmov,sseicvt,sseicvt")
5170 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5171 (set_attr "mode" "<MODEF:MODE>")
5172 (set (attr "prefix_rex")
5174 (and (eq_attr "prefix" "maybe_vex")
5175 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5177 (const_string "*")))
5178 (set_attr "unit" "i387,*,*")
5179 (set_attr "athlon_decode" "*,double,direct")
5180 (set_attr "amdfam10_decode" "*,vector,double")
5181 (set_attr "bdver1_decode" "*,double,direct")
5182 (set_attr "fp_int_src" "true")])
5184 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5185 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5187 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5188 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5189 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5190 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5193 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5194 [(set_attr "type" "fmov,sseicvt")
5195 (set_attr "prefix" "orig,maybe_vex")
5196 (set_attr "mode" "<MODEF:MODE>")
5197 (set (attr "prefix_rex")
5199 (and (eq_attr "prefix" "maybe_vex")
5200 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5202 (const_string "*")))
5203 (set_attr "athlon_decode" "*,direct")
5204 (set_attr "amdfam10_decode" "*,double")
5205 (set_attr "bdver1_decode" "*,direct")
5206 (set_attr "fp_int_src" "true")])
5208 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5209 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5211 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5212 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5213 "TARGET_SSE2 && TARGET_SSE_MATH
5214 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5216 [(set_attr "type" "sseicvt")
5217 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5218 (set_attr "athlon_decode" "double,direct,double")
5219 (set_attr "amdfam10_decode" "vector,double,double")
5220 (set_attr "bdver1_decode" "double,direct,double")
5221 (set_attr "fp_int_src" "true")])
5223 (define_insn "*floatsi<mode>2_vector_sse"
5224 [(set (match_operand:MODEF 0 "register_operand" "=x")
5225 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5226 "TARGET_SSE2 && TARGET_SSE_MATH
5227 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5229 [(set_attr "type" "sseicvt")
5230 (set_attr "mode" "<MODE>")
5231 (set_attr "athlon_decode" "direct")
5232 (set_attr "amdfam10_decode" "double")
5233 (set_attr "bdver1_decode" "direct")
5234 (set_attr "fp_int_src" "true")])
5237 [(set (match_operand:MODEF 0 "register_operand" "")
5238 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5239 (clobber (match_operand:SI 2 "memory_operand" ""))]
5240 "TARGET_SSE2 && TARGET_SSE_MATH
5241 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5243 && (SSE_REG_P (operands[0])
5244 || (GET_CODE (operands[0]) == SUBREG
5245 && SSE_REG_P (operands[0])))"
5248 rtx op1 = operands[1];
5250 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5252 if (GET_CODE (op1) == SUBREG)
5253 op1 = SUBREG_REG (op1);
5255 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5257 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5258 emit_insn (gen_sse2_loadld (operands[4],
5259 CONST0_RTX (V4SImode), operands[1]));
5261 /* We can ignore possible trapping value in the
5262 high part of SSE register for non-trapping math. */
5263 else if (SSE_REG_P (op1) && !flag_trapping_math)
5264 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5267 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5268 emit_move_insn (operands[2], operands[1]);
5269 emit_insn (gen_sse2_loadld (operands[4],
5270 CONST0_RTX (V4SImode), operands[2]));
5273 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5278 [(set (match_operand:MODEF 0 "register_operand" "")
5279 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5280 (clobber (match_operand:SI 2 "memory_operand" ""))]
5281 "TARGET_SSE2 && TARGET_SSE_MATH
5282 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5284 && (SSE_REG_P (operands[0])
5285 || (GET_CODE (operands[0]) == SUBREG
5286 && SSE_REG_P (operands[0])))"
5289 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5291 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5293 emit_insn (gen_sse2_loadld (operands[4],
5294 CONST0_RTX (V4SImode), operands[1]));
5296 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5301 [(set (match_operand:MODEF 0 "register_operand" "")
5302 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5303 "TARGET_SSE2 && TARGET_SSE_MATH
5304 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5306 && (SSE_REG_P (operands[0])
5307 || (GET_CODE (operands[0]) == SUBREG
5308 && SSE_REG_P (operands[0])))"
5311 rtx op1 = operands[1];
5313 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5315 if (GET_CODE (op1) == SUBREG)
5316 op1 = SUBREG_REG (op1);
5318 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5320 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5321 emit_insn (gen_sse2_loadld (operands[4],
5322 CONST0_RTX (V4SImode), operands[1]));
5324 /* We can ignore possible trapping value in the
5325 high part of SSE register for non-trapping math. */
5326 else if (SSE_REG_P (op1) && !flag_trapping_math)
5327 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5331 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5336 [(set (match_operand:MODEF 0 "register_operand" "")
5337 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5338 "TARGET_SSE2 && TARGET_SSE_MATH
5339 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5341 && (SSE_REG_P (operands[0])
5342 || (GET_CODE (operands[0]) == SUBREG
5343 && SSE_REG_P (operands[0])))"
5346 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5348 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5350 emit_insn (gen_sse2_loadld (operands[4],
5351 CONST0_RTX (V4SImode), operands[1]));
5353 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5357 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5358 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5360 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5361 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5362 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5363 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5365 [(set_attr "type" "sseicvt")
5366 (set_attr "mode" "<MODEF:MODE>")
5367 (set_attr "athlon_decode" "double,direct")
5368 (set_attr "amdfam10_decode" "vector,double")
5369 (set_attr "bdver1_decode" "double,direct")
5370 (set_attr "fp_int_src" "true")])
5372 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5373 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5375 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5376 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5377 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5378 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5379 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5380 [(set_attr "type" "sseicvt")
5381 (set_attr "prefix" "maybe_vex")
5382 (set_attr "mode" "<MODEF:MODE>")
5383 (set (attr "prefix_rex")
5385 (and (eq_attr "prefix" "maybe_vex")
5386 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5388 (const_string "*")))
5389 (set_attr "athlon_decode" "double,direct")
5390 (set_attr "amdfam10_decode" "vector,double")
5391 (set_attr "bdver1_decode" "double,direct")
5392 (set_attr "fp_int_src" "true")])
5395 [(set (match_operand:MODEF 0 "register_operand" "")
5396 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5397 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5398 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5399 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5400 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5402 && (SSE_REG_P (operands[0])
5403 || (GET_CODE (operands[0]) == SUBREG
5404 && SSE_REG_P (operands[0])))"
5405 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5407 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5408 [(set (match_operand:MODEF 0 "register_operand" "=x")
5410 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5411 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5412 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5413 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5414 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5415 [(set_attr "type" "sseicvt")
5416 (set_attr "prefix" "maybe_vex")
5417 (set_attr "mode" "<MODEF:MODE>")
5418 (set (attr "prefix_rex")
5420 (and (eq_attr "prefix" "maybe_vex")
5421 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5423 (const_string "*")))
5424 (set_attr "athlon_decode" "direct")
5425 (set_attr "amdfam10_decode" "double")
5426 (set_attr "bdver1_decode" "direct")
5427 (set_attr "fp_int_src" "true")])
5430 [(set (match_operand:MODEF 0 "register_operand" "")
5431 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5432 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5433 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5434 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5435 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5437 && (SSE_REG_P (operands[0])
5438 || (GET_CODE (operands[0]) == SUBREG
5439 && SSE_REG_P (operands[0])))"
5440 [(set (match_dup 2) (match_dup 1))
5441 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5444 [(set (match_operand:MODEF 0 "register_operand" "")
5445 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5446 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5447 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5448 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5450 && (SSE_REG_P (operands[0])
5451 || (GET_CODE (operands[0]) == SUBREG
5452 && SSE_REG_P (operands[0])))"
5453 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5455 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5456 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5458 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5459 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5461 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5465 [(set_attr "type" "fmov,multi")
5466 (set_attr "mode" "<X87MODEF:MODE>")
5467 (set_attr "unit" "*,i387")
5468 (set_attr "fp_int_src" "true")])
5470 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5471 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5473 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5475 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5477 [(set_attr "type" "fmov")
5478 (set_attr "mode" "<X87MODEF:MODE>")
5479 (set_attr "fp_int_src" "true")])
5482 [(set (match_operand:X87MODEF 0 "register_operand" "")
5483 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5484 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5486 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5488 && FP_REG_P (operands[0])"
5489 [(set (match_dup 2) (match_dup 1))
5490 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5493 [(set (match_operand:X87MODEF 0 "register_operand" "")
5494 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5495 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5497 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5499 && FP_REG_P (operands[0])"
5500 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5502 ;; Avoid store forwarding (partial memory) stall penalty
5503 ;; by passing DImode value through XMM registers. */
5505 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5506 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5508 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5509 (clobber (match_scratch:V4SI 3 "=X,x"))
5510 (clobber (match_scratch:V4SI 4 "=X,x"))
5511 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5512 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5513 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5514 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5516 [(set_attr "type" "multi")
5517 (set_attr "mode" "<X87MODEF:MODE>")
5518 (set_attr "unit" "i387")
5519 (set_attr "fp_int_src" "true")])
5522 [(set (match_operand:X87MODEF 0 "register_operand" "")
5523 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5524 (clobber (match_scratch:V4SI 3 ""))
5525 (clobber (match_scratch:V4SI 4 ""))
5526 (clobber (match_operand:DI 2 "memory_operand" ""))]
5527 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5528 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5529 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5531 && FP_REG_P (operands[0])"
5532 [(set (match_dup 2) (match_dup 3))
5533 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5535 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5536 Assemble the 64-bit DImode value in an xmm register. */
5537 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5538 gen_rtx_SUBREG (SImode, operands[1], 0)));
5539 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5540 gen_rtx_SUBREG (SImode, operands[1], 4)));
5541 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5544 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5548 [(set (match_operand:X87MODEF 0 "register_operand" "")
5549 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5550 (clobber (match_scratch:V4SI 3 ""))
5551 (clobber (match_scratch:V4SI 4 ""))
5552 (clobber (match_operand:DI 2 "memory_operand" ""))]
5553 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5554 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5555 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5557 && FP_REG_P (operands[0])"
5558 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5560 ;; Avoid store forwarding (partial memory) stall penalty by extending
5561 ;; SImode value to DImode through XMM register instead of pushing two
5562 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5563 ;; targets benefit from this optimization. Also note that fild
5564 ;; loads from memory only.
5566 (define_insn "*floatunssi<mode>2_1"
5567 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5568 (unsigned_float:X87MODEF
5569 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5570 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5571 (clobber (match_scratch:SI 3 "=X,x"))]
5573 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5576 [(set_attr "type" "multi")
5577 (set_attr "mode" "<MODE>")])
5580 [(set (match_operand:X87MODEF 0 "register_operand" "")
5581 (unsigned_float:X87MODEF
5582 (match_operand:SI 1 "register_operand" "")))
5583 (clobber (match_operand:DI 2 "memory_operand" ""))
5584 (clobber (match_scratch:SI 3 ""))]
5586 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5588 && reload_completed"
5589 [(set (match_dup 2) (match_dup 1))
5591 (float:X87MODEF (match_dup 2)))]
5592 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5595 [(set (match_operand:X87MODEF 0 "register_operand" "")
5596 (unsigned_float:X87MODEF
5597 (match_operand:SI 1 "memory_operand" "")))
5598 (clobber (match_operand:DI 2 "memory_operand" ""))
5599 (clobber (match_scratch:SI 3 ""))]
5601 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5603 && reload_completed"
5604 [(set (match_dup 2) (match_dup 3))
5606 (float:X87MODEF (match_dup 2)))]
5608 emit_move_insn (operands[3], operands[1]);
5609 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5612 (define_expand "floatunssi<mode>2"
5614 [(set (match_operand:X87MODEF 0 "register_operand" "")
5615 (unsigned_float:X87MODEF
5616 (match_operand:SI 1 "nonimmediate_operand" "")))
5617 (clobber (match_dup 2))
5618 (clobber (match_scratch:SI 3 ""))])]
5620 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5622 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5624 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5626 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5631 enum ix86_stack_slot slot = (virtuals_instantiated
5634 operands[2] = assign_386_stack_local (DImode, slot);
5638 (define_expand "floatunsdisf2"
5639 [(use (match_operand:SF 0 "register_operand" ""))
5640 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5641 "TARGET_64BIT && TARGET_SSE_MATH"
5642 "x86_emit_floatuns (operands); DONE;")
5644 (define_expand "floatunsdidf2"
5645 [(use (match_operand:DF 0 "register_operand" ""))
5646 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5647 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5648 && TARGET_SSE2 && TARGET_SSE_MATH"
5651 x86_emit_floatuns (operands);
5653 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5659 (define_expand "add<mode>3"
5660 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5661 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5662 (match_operand:SDWIM 2 "<general_operand>" "")))]
5664 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5666 (define_insn_and_split "*add<dwi>3_doubleword"
5667 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5669 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5670 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5671 (clobber (reg:CC FLAGS_REG))]
5672 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5675 [(parallel [(set (reg:CC FLAGS_REG)
5676 (unspec:CC [(match_dup 1) (match_dup 2)]
5679 (plus:DWIH (match_dup 1) (match_dup 2)))])
5680 (parallel [(set (match_dup 3)
5684 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5686 (clobber (reg:CC FLAGS_REG))])]
5687 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5689 (define_insn "*add<mode>3_cc"
5690 [(set (reg:CC FLAGS_REG)
5692 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5693 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5695 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5696 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5697 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5698 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5699 [(set_attr "type" "alu")
5700 (set_attr "mode" "<MODE>")])
5702 (define_insn "addqi3_cc"
5703 [(set (reg:CC FLAGS_REG)
5705 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5706 (match_operand:QI 2 "general_operand" "qn,qm")]
5708 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5709 (plus:QI (match_dup 1) (match_dup 2)))]
5710 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5711 "add{b}\t{%2, %0|%0, %2}"
5712 [(set_attr "type" "alu")
5713 (set_attr "mode" "QI")])
5715 (define_insn "*lea_1"
5716 [(set (match_operand:P 0 "register_operand" "=r")
5717 (match_operand:P 1 "no_seg_address_operand" "p"))]
5719 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5720 [(set_attr "type" "lea")
5721 (set_attr "mode" "<MODE>")])
5723 (define_insn "*lea_2"
5724 [(set (match_operand:SI 0 "register_operand" "=r")
5725 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5727 "lea{l}\t{%a1, %0|%0, %a1}"
5728 [(set_attr "type" "lea")
5729 (set_attr "mode" "SI")])
5731 (define_insn "*lea_2_zext"
5732 [(set (match_operand:DI 0 "register_operand" "=r")
5734 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5736 "lea{l}\t{%a1, %k0|%k0, %a1}"
5737 [(set_attr "type" "lea")
5738 (set_attr "mode" "SI")])
5740 (define_insn "*add<mode>_1"
5741 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5743 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5744 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5745 (clobber (reg:CC FLAGS_REG))]
5746 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5748 switch (get_attr_type (insn))
5754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755 if (operands[2] == const1_rtx)
5756 return "inc{<imodesuffix>}\t%0";
5759 gcc_assert (operands[2] == constm1_rtx);
5760 return "dec{<imodesuffix>}\t%0";
5764 /* For most processors, ADD is faster than LEA. This alternative
5765 was added to use ADD as much as possible. */
5766 if (which_alternative == 2)
5769 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5773 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5774 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5776 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5780 (cond [(eq_attr "alternative" "3")
5781 (const_string "lea")
5782 (match_operand:SWI48 2 "incdec_operand" "")
5783 (const_string "incdec")
5785 (const_string "alu")))
5786 (set (attr "length_immediate")
5788 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5790 (const_string "*")))
5791 (set_attr "mode" "<MODE>")])
5793 ;; It may seem that nonimmediate operand is proper one for operand 1.
5794 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5795 ;; we take care in ix86_binary_operator_ok to not allow two memory
5796 ;; operands so proper swapping will be done in reload. This allow
5797 ;; patterns constructed from addsi_1 to match.
5799 (define_insn "*addsi_1_zext"
5800 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5802 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5803 (match_operand:SI 2 "general_operand" "g,0,li"))))
5804 (clobber (reg:CC FLAGS_REG))]
5805 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5807 switch (get_attr_type (insn))
5813 if (operands[2] == const1_rtx)
5814 return "inc{l}\t%k0";
5817 gcc_assert (operands[2] == constm1_rtx);
5818 return "dec{l}\t%k0";
5822 /* For most processors, ADD is faster than LEA. This alternative
5823 was added to use ADD as much as possible. */
5824 if (which_alternative == 1)
5827 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5830 if (x86_maybe_negate_const_int (&operands[2], SImode))
5831 return "sub{l}\t{%2, %k0|%k0, %2}";
5833 return "add{l}\t{%2, %k0|%k0, %2}";
5837 (cond [(eq_attr "alternative" "2")
5838 (const_string "lea")
5839 (match_operand:SI 2 "incdec_operand" "")
5840 (const_string "incdec")
5842 (const_string "alu")))
5843 (set (attr "length_immediate")
5845 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5847 (const_string "*")))
5848 (set_attr "mode" "SI")])
5850 (define_insn "*addhi_1"
5851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5852 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5853 (match_operand:HI 2 "general_operand" "rn,rm")))
5854 (clobber (reg:CC FLAGS_REG))]
5855 "TARGET_PARTIAL_REG_STALL
5856 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5858 switch (get_attr_type (insn))
5861 if (operands[2] == const1_rtx)
5862 return "inc{w}\t%0";
5865 gcc_assert (operands[2] == constm1_rtx);
5866 return "dec{w}\t%0";
5870 if (x86_maybe_negate_const_int (&operands[2], HImode))
5871 return "sub{w}\t{%2, %0|%0, %2}";
5873 return "add{w}\t{%2, %0|%0, %2}";
5877 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5878 (const_string "incdec")
5879 (const_string "alu")))
5880 (set (attr "length_immediate")
5882 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5884 (const_string "*")))
5885 (set_attr "mode" "HI")])
5887 (define_insn "*addhi_1_lea"
5888 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5889 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5890 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5891 (clobber (reg:CC FLAGS_REG))]
5892 "!TARGET_PARTIAL_REG_STALL
5893 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5895 switch (get_attr_type (insn))
5901 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5902 if (operands[2] == const1_rtx)
5903 return "inc{w}\t%0";
5906 gcc_assert (operands[2] == constm1_rtx);
5907 return "dec{w}\t%0";
5911 /* For most processors, ADD is faster than LEA. This alternative
5912 was added to use ADD as much as possible. */
5913 if (which_alternative == 2)
5916 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5919 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5920 if (x86_maybe_negate_const_int (&operands[2], HImode))
5921 return "sub{w}\t{%2, %0|%0, %2}";
5923 return "add{w}\t{%2, %0|%0, %2}";
5927 (cond [(eq_attr "alternative" "3")
5928 (const_string "lea")
5929 (match_operand:HI 2 "incdec_operand" "")
5930 (const_string "incdec")
5932 (const_string "alu")))
5933 (set (attr "length_immediate")
5935 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5937 (const_string "*")))
5938 (set_attr "mode" "HI,HI,HI,SI")])
5940 ;; %%% Potential partial reg stall on alternative 2. What to do?
5941 (define_insn "*addqi_1"
5942 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5943 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5944 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5945 (clobber (reg:CC FLAGS_REG))]
5946 "TARGET_PARTIAL_REG_STALL
5947 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5949 int widen = (which_alternative == 2);
5950 switch (get_attr_type (insn))
5953 if (operands[2] == const1_rtx)
5954 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5957 gcc_assert (operands[2] == constm1_rtx);
5958 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5962 if (x86_maybe_negate_const_int (&operands[2], QImode))
5965 return "sub{l}\t{%2, %k0|%k0, %2}";
5967 return "sub{b}\t{%2, %0|%0, %2}";
5970 return "add{l}\t{%k2, %k0|%k0, %k2}";
5972 return "add{b}\t{%2, %0|%0, %2}";
5976 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5977 (const_string "incdec")
5978 (const_string "alu")))
5979 (set (attr "length_immediate")
5981 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5983 (const_string "*")))
5984 (set_attr "mode" "QI,QI,SI")])
5986 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5987 (define_insn "*addqi_1_lea"
5988 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5989 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5990 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5991 (clobber (reg:CC FLAGS_REG))]
5992 "!TARGET_PARTIAL_REG_STALL
5993 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5995 int widen = (which_alternative == 3 || which_alternative == 4);
5997 switch (get_attr_type (insn))
6003 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6004 if (operands[2] == const1_rtx)
6005 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6008 gcc_assert (operands[2] == constm1_rtx);
6009 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6013 /* For most processors, ADD is faster than LEA. These alternatives
6014 were added to use ADD as much as possible. */
6015 if (which_alternative == 2 || which_alternative == 4)
6018 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6021 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6022 if (x86_maybe_negate_const_int (&operands[2], QImode))
6025 return "sub{l}\t{%2, %k0|%k0, %2}";
6027 return "sub{b}\t{%2, %0|%0, %2}";
6030 return "add{l}\t{%k2, %k0|%k0, %k2}";
6032 return "add{b}\t{%2, %0|%0, %2}";
6036 (cond [(eq_attr "alternative" "5")
6037 (const_string "lea")
6038 (match_operand:QI 2 "incdec_operand" "")
6039 (const_string "incdec")
6041 (const_string "alu")))
6042 (set (attr "length_immediate")
6044 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6046 (const_string "*")))
6047 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
6049 (define_insn "*addqi_1_slp"
6050 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6051 (plus:QI (match_dup 0)
6052 (match_operand:QI 1 "general_operand" "qn,qnm")))
6053 (clobber (reg:CC FLAGS_REG))]
6054 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6055 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6057 switch (get_attr_type (insn))
6060 if (operands[1] == const1_rtx)
6061 return "inc{b}\t%0";
6064 gcc_assert (operands[1] == constm1_rtx);
6065 return "dec{b}\t%0";
6069 if (x86_maybe_negate_const_int (&operands[1], QImode))
6070 return "sub{b}\t{%1, %0|%0, %1}";
6072 return "add{b}\t{%1, %0|%0, %1}";
6076 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6077 (const_string "incdec")
6078 (const_string "alu1")))
6079 (set (attr "memory")
6080 (if_then_else (match_operand 1 "memory_operand" "")
6081 (const_string "load")
6082 (const_string "none")))
6083 (set_attr "mode" "QI")])
6085 ;; Convert lea to the lea pattern to avoid flags dependency.
6087 [(set (match_operand 0 "register_operand" "")
6088 (plus (match_operand 1 "register_operand" "")
6089 (match_operand 2 "nonmemory_operand" "")))
6090 (clobber (reg:CC FLAGS_REG))]
6091 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6095 enum machine_mode mode = GET_MODE (operands[0]);
6097 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6098 may confuse gen_lowpart. */
6101 operands[1] = gen_lowpart (Pmode, operands[1]);
6102 operands[2] = gen_lowpart (Pmode, operands[2]);
6105 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6107 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6108 operands[0] = gen_lowpart (SImode, operands[0]);
6110 if (TARGET_64BIT && mode != Pmode)
6111 pat = gen_rtx_SUBREG (SImode, pat, 0);
6113 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6117 ;; Convert lea to the lea pattern to avoid flags dependency.
6118 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6119 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
6121 [(set (match_operand:DI 0 "register_operand" "")
6122 (plus:DI (match_operand:DI 1 "register_operand" "")
6123 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6124 (clobber (reg:CC FLAGS_REG))]
6125 "TARGET_64BIT && reload_completed
6126 && true_regnum (operands[0]) != true_regnum (operands[1])"
6128 (plus:DI (match_dup 1) (match_dup 2)))])
6130 ;; Convert lea to the lea pattern to avoid flags dependency.
6132 [(set (match_operand:DI 0 "register_operand" "")
6134 (plus:SI (match_operand:SI 1 "register_operand" "")
6135 (match_operand:SI 2 "nonmemory_operand" ""))))
6136 (clobber (reg:CC FLAGS_REG))]
6137 "TARGET_64BIT && reload_completed
6138 && ix86_lea_for_add_ok (insn, operands)"
6140 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6142 operands[1] = gen_lowpart (DImode, operands[1]);
6143 operands[2] = gen_lowpart (DImode, operands[2]);
6146 (define_insn "*add<mode>_2"
6147 [(set (reg FLAGS_REG)
6150 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6151 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6153 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6154 (plus:SWI (match_dup 1) (match_dup 2)))]
6155 "ix86_match_ccmode (insn, CCGOCmode)
6156 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6158 switch (get_attr_type (insn))
6161 if (operands[2] == const1_rtx)
6162 return "inc{<imodesuffix>}\t%0";
6165 gcc_assert (operands[2] == constm1_rtx);
6166 return "dec{<imodesuffix>}\t%0";
6170 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6171 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6173 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6177 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6178 (const_string "incdec")
6179 (const_string "alu")))
6180 (set (attr "length_immediate")
6182 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6184 (const_string "*")))
6185 (set_attr "mode" "<MODE>")])
6187 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6188 (define_insn "*addsi_2_zext"
6189 [(set (reg FLAGS_REG)
6191 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6192 (match_operand:SI 2 "general_operand" "g"))
6194 (set (match_operand:DI 0 "register_operand" "=r")
6195 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6196 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6197 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6199 switch (get_attr_type (insn))
6202 if (operands[2] == const1_rtx)
6203 return "inc{l}\t%k0";
6206 gcc_assert (operands[2] == constm1_rtx);
6207 return "dec{l}\t%k0";
6211 if (x86_maybe_negate_const_int (&operands[2], SImode))
6212 return "sub{l}\t{%2, %k0|%k0, %2}";
6214 return "add{l}\t{%2, %k0|%k0, %2}";
6218 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6219 (const_string "incdec")
6220 (const_string "alu")))
6221 (set (attr "length_immediate")
6223 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6225 (const_string "*")))
6226 (set_attr "mode" "SI")])
6228 (define_insn "*add<mode>_3"
6229 [(set (reg FLAGS_REG)
6231 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6232 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6233 (clobber (match_scratch:SWI 0 "=<r>"))]
6234 "ix86_match_ccmode (insn, CCZmode)
6235 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6237 switch (get_attr_type (insn))
6240 if (operands[2] == const1_rtx)
6241 return "inc{<imodesuffix>}\t%0";
6244 gcc_assert (operands[2] == constm1_rtx);
6245 return "dec{<imodesuffix>}\t%0";
6249 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6250 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6252 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6256 (if_then_else (match_operand:SWI 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" "<MODE>")])
6266 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6267 (define_insn "*addsi_3_zext"
6268 [(set (reg FLAGS_REG)
6270 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6271 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6272 (set (match_operand:DI 0 "register_operand" "=r")
6273 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6274 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6275 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6277 switch (get_attr_type (insn))
6280 if (operands[2] == const1_rtx)
6281 return "inc{l}\t%k0";
6284 gcc_assert (operands[2] == constm1_rtx);
6285 return "dec{l}\t%k0";
6289 if (x86_maybe_negate_const_int (&operands[2], SImode))
6290 return "sub{l}\t{%2, %k0|%k0, %2}";
6292 return "add{l}\t{%2, %k0|%k0, %2}";
6296 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6297 (const_string "incdec")
6298 (const_string "alu")))
6299 (set (attr "length_immediate")
6301 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6303 (const_string "*")))
6304 (set_attr "mode" "SI")])
6306 ; For comparisons against 1, -1 and 128, we may generate better code
6307 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6308 ; is matched then. We can't accept general immediate, because for
6309 ; case of overflows, the result is messed up.
6310 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6311 ; only for comparisons not depending on it.
6313 (define_insn "*adddi_4"
6314 [(set (reg FLAGS_REG)
6316 (match_operand:DI 1 "nonimmediate_operand" "0")
6317 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6318 (clobber (match_scratch:DI 0 "=rm"))]
6320 && ix86_match_ccmode (insn, CCGCmode)"
6322 switch (get_attr_type (insn))
6325 if (operands[2] == constm1_rtx)
6326 return "inc{q}\t%0";
6329 gcc_assert (operands[2] == const1_rtx);
6330 return "dec{q}\t%0";
6334 if (x86_maybe_negate_const_int (&operands[2], DImode))
6335 return "add{q}\t{%2, %0|%0, %2}";
6337 return "sub{q}\t{%2, %0|%0, %2}";
6341 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6342 (const_string "incdec")
6343 (const_string "alu")))
6344 (set (attr "length_immediate")
6346 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6348 (const_string "*")))
6349 (set_attr "mode" "DI")])
6351 ; For comparisons against 1, -1 and 128, we may generate better code
6352 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6353 ; is matched then. We can't accept general immediate, because for
6354 ; case of overflows, the result is messed up.
6355 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6356 ; only for comparisons not depending on it.
6358 (define_insn "*add<mode>_4"
6359 [(set (reg FLAGS_REG)
6361 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6362 (match_operand:SWI124 2 "const_int_operand" "n")))
6363 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6364 "ix86_match_ccmode (insn, CCGCmode)"
6366 switch (get_attr_type (insn))
6369 if (operands[2] == constm1_rtx)
6370 return "inc{<imodesuffix>}\t%0";
6373 gcc_assert (operands[2] == const1_rtx);
6374 return "dec{<imodesuffix>}\t%0";
6378 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6379 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6381 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6385 (if_then_else (match_operand:<MODE> 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 "*add<mode>_5"
6396 [(set (reg FLAGS_REG)
6399 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6400 (match_operand:SWI 2 "<general_operand>" "<g>"))
6402 (clobber (match_scratch:SWI 0 "=<r>"))]
6403 "ix86_match_ccmode (insn, CCGOCmode)
6404 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6406 switch (get_attr_type (insn))
6409 if (operands[2] == const1_rtx)
6410 return "inc{<imodesuffix>}\t%0";
6413 gcc_assert (operands[2] == constm1_rtx);
6414 return "dec{<imodesuffix>}\t%0";
6418 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6419 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6421 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6425 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6426 (const_string "incdec")
6427 (const_string "alu")))
6428 (set (attr "length_immediate")
6430 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6432 (const_string "*")))
6433 (set_attr "mode" "<MODE>")])
6435 (define_insn "*addqi_ext_1_rex64"
6436 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6441 (match_operand 1 "ext_register_operand" "0")
6444 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6445 (clobber (reg:CC FLAGS_REG))]
6448 switch (get_attr_type (insn))
6451 if (operands[2] == const1_rtx)
6452 return "inc{b}\t%h0";
6455 gcc_assert (operands[2] == constm1_rtx);
6456 return "dec{b}\t%h0";
6460 return "add{b}\t{%2, %h0|%h0, %2}";
6464 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6465 (const_string "incdec")
6466 (const_string "alu")))
6467 (set_attr "modrm" "1")
6468 (set_attr "mode" "QI")])
6470 (define_insn "addqi_ext_1"
6471 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6476 (match_operand 1 "ext_register_operand" "0")
6479 (match_operand:QI 2 "general_operand" "Qmn")))
6480 (clobber (reg:CC FLAGS_REG))]
6483 switch (get_attr_type (insn))
6486 if (operands[2] == const1_rtx)
6487 return "inc{b}\t%h0";
6490 gcc_assert (operands[2] == constm1_rtx);
6491 return "dec{b}\t%h0";
6495 return "add{b}\t{%2, %h0|%h0, %2}";
6499 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6500 (const_string "incdec")
6501 (const_string "alu")))
6502 (set_attr "modrm" "1")
6503 (set_attr "mode" "QI")])
6505 (define_insn "*addqi_ext_2"
6506 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6511 (match_operand 1 "ext_register_operand" "%0")
6515 (match_operand 2 "ext_register_operand" "Q")
6518 (clobber (reg:CC FLAGS_REG))]
6520 "add{b}\t{%h2, %h0|%h0, %h2}"
6521 [(set_attr "type" "alu")
6522 (set_attr "mode" "QI")])
6524 ;; The lea patterns for non-Pmodes needs to be matched by
6525 ;; several insns converted to real lea by splitters.
6527 (define_insn_and_split "*lea_general_1"
6528 [(set (match_operand 0 "register_operand" "=r")
6529 (plus (plus (match_operand 1 "index_register_operand" "l")
6530 (match_operand 2 "register_operand" "r"))
6531 (match_operand 3 "immediate_operand" "i")))]
6532 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6533 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6534 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6535 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6536 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6537 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6538 || GET_MODE (operands[3]) == VOIDmode)"
6540 "&& reload_completed"
6544 operands[0] = gen_lowpart (SImode, operands[0]);
6545 operands[1] = gen_lowpart (Pmode, operands[1]);
6546 operands[2] = gen_lowpart (Pmode, operands[2]);
6547 operands[3] = gen_lowpart (Pmode, operands[3]);
6548 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6550 if (Pmode != SImode)
6551 pat = gen_rtx_SUBREG (SImode, pat, 0);
6552 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6555 [(set_attr "type" "lea")
6556 (set_attr "mode" "SI")])
6558 (define_insn_and_split "*lea_general_1_zext"
6559 [(set (match_operand:DI 0 "register_operand" "=r")
6562 (match_operand:SI 1 "index_register_operand" "l")
6563 (match_operand:SI 2 "register_operand" "r"))
6564 (match_operand:SI 3 "immediate_operand" "i"))))]
6567 "&& reload_completed"
6569 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6571 (match_dup 3)) 0)))]
6573 operands[1] = gen_lowpart (Pmode, operands[1]);
6574 operands[2] = gen_lowpart (Pmode, operands[2]);
6575 operands[3] = gen_lowpart (Pmode, operands[3]);
6577 [(set_attr "type" "lea")
6578 (set_attr "mode" "SI")])
6580 (define_insn_and_split "*lea_general_2"
6581 [(set (match_operand 0 "register_operand" "=r")
6582 (plus (mult (match_operand 1 "index_register_operand" "l")
6583 (match_operand 2 "const248_operand" "i"))
6584 (match_operand 3 "nonmemory_operand" "ri")))]
6585 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6586 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6587 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6588 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6589 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6590 || GET_MODE (operands[3]) == VOIDmode)"
6592 "&& reload_completed"
6596 operands[0] = gen_lowpart (SImode, operands[0]);
6597 operands[1] = gen_lowpart (Pmode, operands[1]);
6598 operands[3] = gen_lowpart (Pmode, operands[3]);
6599 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6601 if (Pmode != SImode)
6602 pat = gen_rtx_SUBREG (SImode, pat, 0);
6603 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6606 [(set_attr "type" "lea")
6607 (set_attr "mode" "SI")])
6609 (define_insn_and_split "*lea_general_2_zext"
6610 [(set (match_operand:DI 0 "register_operand" "=r")
6613 (match_operand:SI 1 "index_register_operand" "l")
6614 (match_operand:SI 2 "const248_operand" "n"))
6615 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6618 "&& reload_completed"
6620 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6622 (match_dup 3)) 0)))]
6624 operands[1] = gen_lowpart (Pmode, operands[1]);
6625 operands[3] = gen_lowpart (Pmode, operands[3]);
6627 [(set_attr "type" "lea")
6628 (set_attr "mode" "SI")])
6630 (define_insn_and_split "*lea_general_3"
6631 [(set (match_operand 0 "register_operand" "=r")
6632 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6633 (match_operand 2 "const248_operand" "i"))
6634 (match_operand 3 "register_operand" "r"))
6635 (match_operand 4 "immediate_operand" "i")))]
6636 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6637 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6638 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6639 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6640 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6642 "&& reload_completed"
6646 operands[0] = gen_lowpart (SImode, operands[0]);
6647 operands[1] = gen_lowpart (Pmode, operands[1]);
6648 operands[3] = gen_lowpart (Pmode, operands[3]);
6649 operands[4] = gen_lowpart (Pmode, operands[4]);
6650 pat = gen_rtx_PLUS (Pmode,
6651 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6655 if (Pmode != SImode)
6656 pat = gen_rtx_SUBREG (SImode, pat, 0);
6657 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6660 [(set_attr "type" "lea")
6661 (set_attr "mode" "SI")])
6663 (define_insn_and_split "*lea_general_3_zext"
6664 [(set (match_operand:DI 0 "register_operand" "=r")
6668 (match_operand:SI 1 "index_register_operand" "l")
6669 (match_operand:SI 2 "const248_operand" "n"))
6670 (match_operand:SI 3 "register_operand" "r"))
6671 (match_operand:SI 4 "immediate_operand" "i"))))]
6674 "&& reload_completed"
6676 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6679 (match_dup 4)) 0)))]
6681 operands[1] = gen_lowpart (Pmode, operands[1]);
6682 operands[3] = gen_lowpart (Pmode, operands[3]);
6683 operands[4] = gen_lowpart (Pmode, operands[4]);
6685 [(set_attr "type" "lea")
6686 (set_attr "mode" "SI")])
6688 ;; Subtract instructions
6690 (define_expand "sub<mode>3"
6691 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6692 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6693 (match_operand:SDWIM 2 "<general_operand>" "")))]
6695 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6697 (define_insn_and_split "*sub<dwi>3_doubleword"
6698 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6700 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6701 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6702 (clobber (reg:CC FLAGS_REG))]
6703 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6706 [(parallel [(set (reg:CC FLAGS_REG)
6707 (compare:CC (match_dup 1) (match_dup 2)))
6709 (minus:DWIH (match_dup 1) (match_dup 2)))])
6710 (parallel [(set (match_dup 3)
6714 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6716 (clobber (reg:CC FLAGS_REG))])]
6717 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6719 (define_insn "*sub<mode>_1"
6720 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6722 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6723 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6724 (clobber (reg:CC FLAGS_REG))]
6725 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6726 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6727 [(set_attr "type" "alu")
6728 (set_attr "mode" "<MODE>")])
6730 (define_insn "*subsi_1_zext"
6731 [(set (match_operand:DI 0 "register_operand" "=r")
6733 (minus:SI (match_operand:SI 1 "register_operand" "0")
6734 (match_operand:SI 2 "general_operand" "g"))))
6735 (clobber (reg:CC FLAGS_REG))]
6736 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6737 "sub{l}\t{%2, %k0|%k0, %2}"
6738 [(set_attr "type" "alu")
6739 (set_attr "mode" "SI")])
6741 (define_insn "*subqi_1_slp"
6742 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6743 (minus:QI (match_dup 0)
6744 (match_operand:QI 1 "general_operand" "qn,qm")))
6745 (clobber (reg:CC FLAGS_REG))]
6746 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6747 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6748 "sub{b}\t{%1, %0|%0, %1}"
6749 [(set_attr "type" "alu1")
6750 (set_attr "mode" "QI")])
6752 (define_insn "*sub<mode>_2"
6753 [(set (reg FLAGS_REG)
6756 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6757 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6759 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6760 (minus:SWI (match_dup 1) (match_dup 2)))]
6761 "ix86_match_ccmode (insn, CCGOCmode)
6762 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6763 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "<MODE>")])
6767 (define_insn "*subsi_2_zext"
6768 [(set (reg FLAGS_REG)
6770 (minus:SI (match_operand:SI 1 "register_operand" "0")
6771 (match_operand:SI 2 "general_operand" "g"))
6773 (set (match_operand:DI 0 "register_operand" "=r")
6775 (minus:SI (match_dup 1)
6777 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6778 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6779 "sub{l}\t{%2, %k0|%k0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "SI")])
6783 (define_insn "*sub<mode>_3"
6784 [(set (reg FLAGS_REG)
6785 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6786 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6787 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6788 (minus:SWI (match_dup 1) (match_dup 2)))]
6789 "ix86_match_ccmode (insn, CCmode)
6790 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6791 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6792 [(set_attr "type" "alu")
6793 (set_attr "mode" "<MODE>")])
6795 (define_insn "*subsi_3_zext"
6796 [(set (reg FLAGS_REG)
6797 (compare (match_operand:SI 1 "register_operand" "0")
6798 (match_operand:SI 2 "general_operand" "g")))
6799 (set (match_operand:DI 0 "register_operand" "=r")
6801 (minus:SI (match_dup 1)
6803 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6804 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6805 "sub{l}\t{%2, %1|%1, %2}"
6806 [(set_attr "type" "alu")
6807 (set_attr "mode" "SI")])
6809 ;; Add with carry and subtract with borrow
6811 (define_expand "<plusminus_insn><mode>3_carry"
6813 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6815 (match_operand:SWI 1 "nonimmediate_operand" "")
6816 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6817 [(match_operand 3 "flags_reg_operand" "")
6819 (match_operand:SWI 2 "<general_operand>" ""))))
6820 (clobber (reg:CC FLAGS_REG))])]
6821 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6823 (define_insn "*<plusminus_insn><mode>3_carry"
6824 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6826 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6828 (match_operator 3 "ix86_carry_flag_operator"
6829 [(reg FLAGS_REG) (const_int 0)])
6830 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6831 (clobber (reg:CC FLAGS_REG))]
6832 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6833 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6834 [(set_attr "type" "alu")
6835 (set_attr "use_carry" "1")
6836 (set_attr "pent_pair" "pu")
6837 (set_attr "mode" "<MODE>")])
6839 (define_insn "*addsi3_carry_zext"
6840 [(set (match_operand:DI 0 "register_operand" "=r")
6842 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6843 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6844 [(reg FLAGS_REG) (const_int 0)])
6845 (match_operand:SI 2 "general_operand" "g")))))
6846 (clobber (reg:CC FLAGS_REG))]
6847 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6848 "adc{l}\t{%2, %k0|%k0, %2}"
6849 [(set_attr "type" "alu")
6850 (set_attr "use_carry" "1")
6851 (set_attr "pent_pair" "pu")
6852 (set_attr "mode" "SI")])
6854 (define_insn "*subsi3_carry_zext"
6855 [(set (match_operand:DI 0 "register_operand" "=r")
6857 (minus:SI (match_operand:SI 1 "register_operand" "0")
6858 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6859 [(reg FLAGS_REG) (const_int 0)])
6860 (match_operand:SI 2 "general_operand" "g")))))
6861 (clobber (reg:CC FLAGS_REG))]
6862 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6863 "sbb{l}\t{%2, %k0|%k0, %2}"
6864 [(set_attr "type" "alu")
6865 (set_attr "pent_pair" "pu")
6866 (set_attr "mode" "SI")])
6868 ;; Overflow setting add and subtract instructions
6870 (define_insn "*add<mode>3_cconly_overflow"
6871 [(set (reg:CCC FLAGS_REG)
6874 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6875 (match_operand:SWI 2 "<general_operand>" "<g>"))
6877 (clobber (match_scratch:SWI 0 "=<r>"))]
6878 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6879 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6880 [(set_attr "type" "alu")
6881 (set_attr "mode" "<MODE>")])
6883 (define_insn "*sub<mode>3_cconly_overflow"
6884 [(set (reg:CCC FLAGS_REG)
6887 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6888 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6891 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6892 [(set_attr "type" "icmp")
6893 (set_attr "mode" "<MODE>")])
6895 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6896 [(set (reg:CCC FLAGS_REG)
6899 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6900 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6902 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6903 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6904 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6905 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6906 [(set_attr "type" "alu")
6907 (set_attr "mode" "<MODE>")])
6909 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6910 [(set (reg:CCC FLAGS_REG)
6913 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6914 (match_operand:SI 2 "general_operand" "g"))
6916 (set (match_operand:DI 0 "register_operand" "=r")
6917 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6918 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6919 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6920 [(set_attr "type" "alu")
6921 (set_attr "mode" "SI")])
6923 ;; The patterns that match these are at the end of this file.
6925 (define_expand "<plusminus_insn>xf3"
6926 [(set (match_operand:XF 0 "register_operand" "")
6928 (match_operand:XF 1 "register_operand" "")
6929 (match_operand:XF 2 "register_operand" "")))]
6932 (define_expand "<plusminus_insn><mode>3"
6933 [(set (match_operand:MODEF 0 "register_operand" "")
6935 (match_operand:MODEF 1 "register_operand" "")
6936 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6937 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6938 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6940 ;; Multiply instructions
6942 (define_expand "mul<mode>3"
6943 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6945 (match_operand:SWIM248 1 "register_operand" "")
6946 (match_operand:SWIM248 2 "<general_operand>" "")))
6947 (clobber (reg:CC FLAGS_REG))])])
6949 (define_expand "mulqi3"
6950 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6952 (match_operand:QI 1 "register_operand" "")
6953 (match_operand:QI 2 "nonimmediate_operand" "")))
6954 (clobber (reg:CC FLAGS_REG))])]
6955 "TARGET_QIMODE_MATH")
6958 ;; IMUL reg32/64, reg32/64, imm8 Direct
6959 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6960 ;; IMUL reg32/64, reg32/64, imm32 Direct
6961 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6962 ;; IMUL reg32/64, reg32/64 Direct
6963 ;; IMUL reg32/64, mem32/64 Direct
6965 ;; On BDVER1, all above IMULs use DirectPath
6967 (define_insn "*mul<mode>3_1"
6968 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6970 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6971 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6972 (clobber (reg:CC FLAGS_REG))]
6973 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6975 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6976 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6977 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6978 [(set_attr "type" "imul")
6979 (set_attr "prefix_0f" "0,0,1")
6980 (set (attr "athlon_decode")
6981 (cond [(eq_attr "cpu" "athlon")
6982 (const_string "vector")
6983 (eq_attr "alternative" "1")
6984 (const_string "vector")
6985 (and (eq_attr "alternative" "2")
6986 (match_operand 1 "memory_operand" ""))
6987 (const_string "vector")]
6988 (const_string "direct")))
6989 (set (attr "amdfam10_decode")
6990 (cond [(and (eq_attr "alternative" "0,1")
6991 (match_operand 1 "memory_operand" ""))
6992 (const_string "vector")]
6993 (const_string "direct")))
6994 (set_attr "bdver1_decode" "direct")
6995 (set_attr "mode" "<MODE>")])
6997 (define_insn "*mulsi3_1_zext"
6998 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7000 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7001 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7002 (clobber (reg:CC FLAGS_REG))]
7004 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7006 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7007 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7008 imul{l}\t{%2, %k0|%k0, %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")
7015 (const_string "vector")
7016 (and (eq_attr "alternative" "2")
7017 (match_operand 1 "memory_operand" ""))
7018 (const_string "vector")]
7019 (const_string "direct")))
7020 (set (attr "amdfam10_decode")
7021 (cond [(and (eq_attr "alternative" "0,1")
7022 (match_operand 1 "memory_operand" ""))
7023 (const_string "vector")]
7024 (const_string "direct")))
7025 (set_attr "bdver1_decode" "direct")
7026 (set_attr "mode" "SI")])
7029 ;; IMUL reg16, reg16, imm8 VectorPath
7030 ;; IMUL reg16, mem16, imm8 VectorPath
7031 ;; IMUL reg16, reg16, imm16 VectorPath
7032 ;; IMUL reg16, mem16, imm16 VectorPath
7033 ;; IMUL reg16, reg16 Direct
7034 ;; IMUL reg16, mem16 Direct
7036 ;; On BDVER1, all HI MULs use DoublePath
7038 (define_insn "*mulhi3_1"
7039 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7040 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7041 (match_operand:HI 2 "general_operand" "K,n,mr")))
7042 (clobber (reg:CC FLAGS_REG))]
7044 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7046 imul{w}\t{%2, %1, %0|%0, %1, %2}
7047 imul{w}\t{%2, %1, %0|%0, %1, %2}
7048 imul{w}\t{%2, %0|%0, %2}"
7049 [(set_attr "type" "imul")
7050 (set_attr "prefix_0f" "0,0,1")
7051 (set (attr "athlon_decode")
7052 (cond [(eq_attr "cpu" "athlon")
7053 (const_string "vector")
7054 (eq_attr "alternative" "1,2")
7055 (const_string "vector")]
7056 (const_string "direct")))
7057 (set (attr "amdfam10_decode")
7058 (cond [(eq_attr "alternative" "0,1")
7059 (const_string "vector")]
7060 (const_string "direct")))
7061 (set_attr "bdver1_decode" "double")
7062 (set_attr "mode" "HI")])
7064 ;;On AMDFAM10 and BDVER1
7068 (define_insn "*mulqi3_1"
7069 [(set (match_operand:QI 0 "register_operand" "=a")
7070 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7071 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7072 (clobber (reg:CC FLAGS_REG))]
7074 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7076 [(set_attr "type" "imul")
7077 (set_attr "length_immediate" "0")
7078 (set (attr "athlon_decode")
7079 (if_then_else (eq_attr "cpu" "athlon")
7080 (const_string "vector")
7081 (const_string "direct")))
7082 (set_attr "amdfam10_decode" "direct")
7083 (set_attr "bdver1_decode" "direct")
7084 (set_attr "mode" "QI")])
7086 (define_expand "<u>mul<mode><dwi>3"
7087 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7090 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7092 (match_operand:DWIH 2 "register_operand" ""))))
7093 (clobber (reg:CC FLAGS_REG))])])
7095 (define_expand "<u>mulqihi3"
7096 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7099 (match_operand:QI 1 "nonimmediate_operand" ""))
7101 (match_operand:QI 2 "register_operand" ""))))
7102 (clobber (reg:CC FLAGS_REG))])]
7103 "TARGET_QIMODE_MATH")
7105 (define_insn "*<u>mul<mode><dwi>3_1"
7106 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7109 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7111 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7112 (clobber (reg:CC FLAGS_REG))]
7113 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7114 "<sgnprefix>mul{<imodesuffix>}\t%2"
7115 [(set_attr "type" "imul")
7116 (set_attr "length_immediate" "0")
7117 (set (attr "athlon_decode")
7118 (if_then_else (eq_attr "cpu" "athlon")
7119 (const_string "vector")
7120 (const_string "double")))
7121 (set_attr "amdfam10_decode" "double")
7122 (set_attr "bdver1_decode" "direct")
7123 (set_attr "mode" "<MODE>")])
7125 (define_insn "*<u>mulqihi3_1"
7126 [(set (match_operand:HI 0 "register_operand" "=a")
7129 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7131 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7132 (clobber (reg:CC FLAGS_REG))]
7134 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7135 "<sgnprefix>mul{b}\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 "direct")))
7142 (set_attr "amdfam10_decode" "direct")
7143 (set_attr "bdver1_decode" "direct")
7144 (set_attr "mode" "QI")])
7146 (define_expand "<s>mul<mode>3_highpart"
7147 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7152 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7154 (match_operand:SWI48 2 "register_operand" "")))
7156 (clobber (match_scratch:SWI48 3 ""))
7157 (clobber (reg:CC FLAGS_REG))])]
7159 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7161 (define_insn "*<s>muldi3_highpart_1"
7162 [(set (match_operand:DI 0 "register_operand" "=d")
7167 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7169 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7171 (clobber (match_scratch:DI 3 "=1"))
7172 (clobber (reg:CC FLAGS_REG))]
7174 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7175 "<sgnprefix>mul{q}\t%2"
7176 [(set_attr "type" "imul")
7177 (set_attr "length_immediate" "0")
7178 (set (attr "athlon_decode")
7179 (if_then_else (eq_attr "cpu" "athlon")
7180 (const_string "vector")
7181 (const_string "double")))
7182 (set_attr "amdfam10_decode" "double")
7183 (set_attr "bdver1_decode" "direct")
7184 (set_attr "mode" "DI")])
7186 (define_insn "*<s>mulsi3_highpart_1"
7187 [(set (match_operand:SI 0 "register_operand" "=d")
7192 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7194 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7196 (clobber (match_scratch:SI 3 "=1"))
7197 (clobber (reg:CC FLAGS_REG))]
7198 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7199 "<sgnprefix>mul{l}\t%2"
7200 [(set_attr "type" "imul")
7201 (set_attr "length_immediate" "0")
7202 (set (attr "athlon_decode")
7203 (if_then_else (eq_attr "cpu" "athlon")
7204 (const_string "vector")
7205 (const_string "double")))
7206 (set_attr "amdfam10_decode" "double")
7207 (set_attr "bdver1_decode" "direct")
7208 (set_attr "mode" "SI")])
7210 (define_insn "*<s>mulsi3_highpart_zext"
7211 [(set (match_operand:DI 0 "register_operand" "=d")
7212 (zero_extend:DI (truncate:SI
7214 (mult:DI (any_extend:DI
7215 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7217 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7219 (clobber (match_scratch:SI 3 "=1"))
7220 (clobber (reg:CC FLAGS_REG))]
7222 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7223 "<sgnprefix>mul{l}\t%2"
7224 [(set_attr "type" "imul")
7225 (set_attr "length_immediate" "0")
7226 (set (attr "athlon_decode")
7227 (if_then_else (eq_attr "cpu" "athlon")
7228 (const_string "vector")
7229 (const_string "double")))
7230 (set_attr "amdfam10_decode" "double")
7231 (set_attr "bdver1_decode" "direct")
7232 (set_attr "mode" "SI")])
7234 ;; The patterns that match these are at the end of this file.
7236 (define_expand "mulxf3"
7237 [(set (match_operand:XF 0 "register_operand" "")
7238 (mult:XF (match_operand:XF 1 "register_operand" "")
7239 (match_operand:XF 2 "register_operand" "")))]
7242 (define_expand "mul<mode>3"
7243 [(set (match_operand:MODEF 0 "register_operand" "")
7244 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7245 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7246 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7247 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7249 ;; Divide instructions
7251 ;; The patterns that match these are at the end of this file.
7253 (define_expand "divxf3"
7254 [(set (match_operand:XF 0 "register_operand" "")
7255 (div:XF (match_operand:XF 1 "register_operand" "")
7256 (match_operand:XF 2 "register_operand" "")))]
7259 (define_expand "divdf3"
7260 [(set (match_operand:DF 0 "register_operand" "")
7261 (div:DF (match_operand:DF 1 "register_operand" "")
7262 (match_operand:DF 2 "nonimmediate_operand" "")))]
7263 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7264 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7266 (define_expand "divsf3"
7267 [(set (match_operand:SF 0 "register_operand" "")
7268 (div:SF (match_operand:SF 1 "register_operand" "")
7269 (match_operand:SF 2 "nonimmediate_operand" "")))]
7270 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7273 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7274 && flag_finite_math_only && !flag_trapping_math
7275 && flag_unsafe_math_optimizations)
7277 ix86_emit_swdivsf (operands[0], operands[1],
7278 operands[2], SFmode);
7283 ;; Divmod instructions.
7285 (define_expand "divmod<mode>4"
7286 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7288 (match_operand:SWIM248 1 "register_operand" "")
7289 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7290 (set (match_operand:SWIM248 3 "register_operand" "")
7291 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7292 (clobber (reg:CC FLAGS_REG))])])
7294 ;; Split with 8bit unsigned divide:
7295 ;; if (dividend an divisor are in [0-255])
7296 ;; use 8bit unsigned integer divide
7298 ;; use original integer divide
7300 [(set (match_operand:SWI48 0 "register_operand" "")
7301 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7302 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7303 (set (match_operand:SWI48 1 "register_operand" "")
7304 (mod:SWI48 (match_dup 2) (match_dup 3)))
7305 (clobber (reg:CC FLAGS_REG))]
7306 "TARGET_USE_8BIT_IDIV
7307 && TARGET_QIMODE_MATH
7308 && can_create_pseudo_p ()
7309 && !optimize_insn_for_size_p ()"
7311 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7313 (define_insn_and_split "divmod<mode>4_1"
7314 [(set (match_operand:SWI48 0 "register_operand" "=a")
7315 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7316 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7317 (set (match_operand:SWI48 1 "register_operand" "=&d")
7318 (mod:SWI48 (match_dup 2) (match_dup 3)))
7319 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7320 (clobber (reg:CC FLAGS_REG))]
7324 [(parallel [(set (match_dup 1)
7325 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7326 (clobber (reg:CC FLAGS_REG))])
7327 (parallel [(set (match_dup 0)
7328 (div:SWI48 (match_dup 2) (match_dup 3)))
7330 (mod:SWI48 (match_dup 2) (match_dup 3)))
7332 (clobber (reg:CC FLAGS_REG))])]
7334 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7336 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7337 operands[4] = operands[2];
7340 /* Avoid use of cltd in favor of a mov+shift. */
7341 emit_move_insn (operands[1], operands[2]);
7342 operands[4] = operands[1];
7345 [(set_attr "type" "multi")
7346 (set_attr "mode" "<MODE>")])
7348 (define_insn_and_split "*divmod<mode>4"
7349 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7350 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7351 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7352 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7353 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7354 (clobber (reg:CC FLAGS_REG))]
7358 [(parallel [(set (match_dup 1)
7359 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7360 (clobber (reg:CC FLAGS_REG))])
7361 (parallel [(set (match_dup 0)
7362 (div:SWIM248 (match_dup 2) (match_dup 3)))
7364 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7366 (clobber (reg:CC FLAGS_REG))])]
7368 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7370 if (<MODE>mode != HImode
7371 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7372 operands[4] = operands[2];
7375 /* Avoid use of cltd in favor of a mov+shift. */
7376 emit_move_insn (operands[1], operands[2]);
7377 operands[4] = operands[1];
7380 [(set_attr "type" "multi")
7381 (set_attr "mode" "<MODE>")])
7383 (define_insn "*divmod<mode>4_noext"
7384 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7385 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7386 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7387 (set (match_operand:SWIM248 1 "register_operand" "=d")
7388 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7389 (use (match_operand:SWIM248 4 "register_operand" "1"))
7390 (clobber (reg:CC FLAGS_REG))]
7392 "idiv{<imodesuffix>}\t%3"
7393 [(set_attr "type" "idiv")
7394 (set_attr "mode" "<MODE>")])
7396 (define_expand "divmodqi4"
7397 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7399 (match_operand:QI 1 "register_operand" "")
7400 (match_operand:QI 2 "nonimmediate_operand" "")))
7401 (set (match_operand:QI 3 "register_operand" "")
7402 (mod:QI (match_dup 1) (match_dup 2)))
7403 (clobber (reg:CC FLAGS_REG))])]
7404 "TARGET_QIMODE_MATH"
7409 tmp0 = gen_reg_rtx (HImode);
7410 tmp1 = gen_reg_rtx (HImode);
7412 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7414 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7415 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7417 /* Extract remainder from AH. */
7418 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7419 insn = emit_move_insn (operands[3], tmp1);
7421 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7422 set_unique_reg_note (insn, REG_EQUAL, mod);
7424 /* Extract quotient from AL. */
7425 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7427 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7428 set_unique_reg_note (insn, REG_EQUAL, div);
7433 ;; Divide AX by r/m8, with result stored in
7436 ;; Change div/mod to HImode and extend the second argument to HImode
7437 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7438 ;; combine may fail.
7439 (define_insn "divmodhiqi3"
7440 [(set (match_operand:HI 0 "register_operand" "=a")
7445 (mod:HI (match_operand:HI 1 "register_operand" "0")
7447 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7451 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7452 (clobber (reg:CC FLAGS_REG))]
7453 "TARGET_QIMODE_MATH"
7455 [(set_attr "type" "idiv")
7456 (set_attr "mode" "QI")])
7458 (define_expand "udivmod<mode>4"
7459 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7461 (match_operand:SWIM248 1 "register_operand" "")
7462 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7463 (set (match_operand:SWIM248 3 "register_operand" "")
7464 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7465 (clobber (reg:CC FLAGS_REG))])])
7467 ;; Split with 8bit unsigned divide:
7468 ;; if (dividend an divisor are in [0-255])
7469 ;; use 8bit unsigned integer divide
7471 ;; use original integer divide
7473 [(set (match_operand:SWI48 0 "register_operand" "")
7474 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7475 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7476 (set (match_operand:SWI48 1 "register_operand" "")
7477 (umod:SWI48 (match_dup 2) (match_dup 3)))
7478 (clobber (reg:CC FLAGS_REG))]
7479 "TARGET_USE_8BIT_IDIV
7480 && TARGET_QIMODE_MATH
7481 && can_create_pseudo_p ()
7482 && !optimize_insn_for_size_p ()"
7484 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7486 (define_insn_and_split "udivmod<mode>4_1"
7487 [(set (match_operand:SWI48 0 "register_operand" "=a")
7488 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7489 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7490 (set (match_operand:SWI48 1 "register_operand" "=&d")
7491 (umod:SWI48 (match_dup 2) (match_dup 3)))
7492 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7493 (clobber (reg:CC FLAGS_REG))]
7497 [(set (match_dup 1) (const_int 0))
7498 (parallel [(set (match_dup 0)
7499 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7501 (umod:SWI48 (match_dup 2) (match_dup 3)))
7503 (clobber (reg:CC FLAGS_REG))])]
7505 [(set_attr "type" "multi")
7506 (set_attr "mode" "<MODE>")])
7508 (define_insn_and_split "*udivmod<mode>4"
7509 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7510 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7511 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7512 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7513 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7514 (clobber (reg:CC FLAGS_REG))]
7518 [(set (match_dup 1) (const_int 0))
7519 (parallel [(set (match_dup 0)
7520 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7522 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7524 (clobber (reg:CC FLAGS_REG))])]
7526 [(set_attr "type" "multi")
7527 (set_attr "mode" "<MODE>")])
7529 (define_insn "*udivmod<mode>4_noext"
7530 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7531 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7532 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7533 (set (match_operand:SWIM248 1 "register_operand" "=d")
7534 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7535 (use (match_operand:SWIM248 4 "register_operand" "1"))
7536 (clobber (reg:CC FLAGS_REG))]
7538 "div{<imodesuffix>}\t%3"
7539 [(set_attr "type" "idiv")
7540 (set_attr "mode" "<MODE>")])
7542 (define_expand "udivmodqi4"
7543 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7545 (match_operand:QI 1 "register_operand" "")
7546 (match_operand:QI 2 "nonimmediate_operand" "")))
7547 (set (match_operand:QI 3 "register_operand" "")
7548 (umod:QI (match_dup 1) (match_dup 2)))
7549 (clobber (reg:CC FLAGS_REG))])]
7550 "TARGET_QIMODE_MATH"
7555 tmp0 = gen_reg_rtx (HImode);
7556 tmp1 = gen_reg_rtx (HImode);
7558 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7560 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7561 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7563 /* Extract remainder from AH. */
7564 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7565 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7566 insn = emit_move_insn (operands[3], tmp1);
7568 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7569 set_unique_reg_note (insn, REG_EQUAL, mod);
7571 /* Extract quotient from AL. */
7572 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7574 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7575 set_unique_reg_note (insn, REG_EQUAL, div);
7580 (define_insn "udivmodhiqi3"
7581 [(set (match_operand:HI 0 "register_operand" "=a")
7586 (mod:HI (match_operand:HI 1 "register_operand" "0")
7588 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7592 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7593 (clobber (reg:CC FLAGS_REG))]
7594 "TARGET_QIMODE_MATH"
7596 [(set_attr "type" "idiv")
7597 (set_attr "mode" "QI")])
7599 ;; We cannot use div/idiv for double division, because it causes
7600 ;; "division by zero" on the overflow and that's not what we expect
7601 ;; from truncate. Because true (non truncating) double division is
7602 ;; never generated, we can't create this insn anyway.
7605 ; [(set (match_operand:SI 0 "register_operand" "=a")
7607 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7609 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7610 ; (set (match_operand:SI 3 "register_operand" "=d")
7612 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7613 ; (clobber (reg:CC FLAGS_REG))]
7615 ; "div{l}\t{%2, %0|%0, %2}"
7616 ; [(set_attr "type" "idiv")])
7618 ;;- Logical AND instructions
7620 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7621 ;; Note that this excludes ah.
7623 (define_expand "testsi_ccno_1"
7624 [(set (reg:CCNO FLAGS_REG)
7626 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7627 (match_operand:SI 1 "nonmemory_operand" ""))
7630 (define_expand "testqi_ccz_1"
7631 [(set (reg:CCZ FLAGS_REG)
7632 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7633 (match_operand:QI 1 "nonmemory_operand" ""))
7636 (define_expand "testdi_ccno_1"
7637 [(set (reg:CCNO FLAGS_REG)
7639 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7640 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7642 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7644 (define_insn "*testdi_1"
7645 [(set (reg FLAGS_REG)
7648 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7649 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7651 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7652 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7654 test{l}\t{%k1, %k0|%k0, %k1}
7655 test{l}\t{%k1, %k0|%k0, %k1}
7656 test{q}\t{%1, %0|%0, %1}
7657 test{q}\t{%1, %0|%0, %1}
7658 test{q}\t{%1, %0|%0, %1}"
7659 [(set_attr "type" "test")
7660 (set_attr "modrm" "0,1,0,1,1")
7661 (set_attr "mode" "SI,SI,DI,DI,DI")])
7663 (define_insn "*testqi_1_maybe_si"
7664 [(set (reg FLAGS_REG)
7667 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7668 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7670 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7671 && ix86_match_ccmode (insn,
7672 CONST_INT_P (operands[1])
7673 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7675 if (which_alternative == 3)
7677 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7678 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7679 return "test{l}\t{%1, %k0|%k0, %1}";
7681 return "test{b}\t{%1, %0|%0, %1}";
7683 [(set_attr "type" "test")
7684 (set_attr "modrm" "0,1,1,1")
7685 (set_attr "mode" "QI,QI,QI,SI")
7686 (set_attr "pent_pair" "uv,np,uv,np")])
7688 (define_insn "*test<mode>_1"
7689 [(set (reg FLAGS_REG)
7692 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7693 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7695 "ix86_match_ccmode (insn, CCNOmode)
7696 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7697 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7698 [(set_attr "type" "test")
7699 (set_attr "modrm" "0,1,1")
7700 (set_attr "mode" "<MODE>")
7701 (set_attr "pent_pair" "uv,np,uv")])
7703 (define_expand "testqi_ext_ccno_0"
7704 [(set (reg:CCNO FLAGS_REG)
7708 (match_operand 0 "ext_register_operand" "")
7711 (match_operand 1 "const_int_operand" ""))
7714 (define_insn "*testqi_ext_0"
7715 [(set (reg FLAGS_REG)
7719 (match_operand 0 "ext_register_operand" "Q")
7722 (match_operand 1 "const_int_operand" "n"))
7724 "ix86_match_ccmode (insn, CCNOmode)"
7725 "test{b}\t{%1, %h0|%h0, %1}"
7726 [(set_attr "type" "test")
7727 (set_attr "mode" "QI")
7728 (set_attr "length_immediate" "1")
7729 (set_attr "modrm" "1")
7730 (set_attr "pent_pair" "np")])
7732 (define_insn "*testqi_ext_1_rex64"
7733 [(set (reg FLAGS_REG)
7737 (match_operand 0 "ext_register_operand" "Q")
7741 (match_operand:QI 1 "register_operand" "Q")))
7743 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7744 "test{b}\t{%1, %h0|%h0, %1}"
7745 [(set_attr "type" "test")
7746 (set_attr "mode" "QI")])
7748 (define_insn "*testqi_ext_1"
7749 [(set (reg FLAGS_REG)
7753 (match_operand 0 "ext_register_operand" "Q")
7757 (match_operand:QI 1 "general_operand" "Qm")))
7759 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7760 "test{b}\t{%1, %h0|%h0, %1}"
7761 [(set_attr "type" "test")
7762 (set_attr "mode" "QI")])
7764 (define_insn "*testqi_ext_2"
7765 [(set (reg FLAGS_REG)
7769 (match_operand 0 "ext_register_operand" "Q")
7773 (match_operand 1 "ext_register_operand" "Q")
7777 "ix86_match_ccmode (insn, CCNOmode)"
7778 "test{b}\t{%h1, %h0|%h0, %h1}"
7779 [(set_attr "type" "test")
7780 (set_attr "mode" "QI")])
7782 (define_insn "*testqi_ext_3_rex64"
7783 [(set (reg FLAGS_REG)
7784 (compare (zero_extract:DI
7785 (match_operand 0 "nonimmediate_operand" "rm")
7786 (match_operand:DI 1 "const_int_operand" "")
7787 (match_operand:DI 2 "const_int_operand" ""))
7790 && ix86_match_ccmode (insn, CCNOmode)
7791 && INTVAL (operands[1]) > 0
7792 && INTVAL (operands[2]) >= 0
7793 /* Ensure that resulting mask is zero or sign extended operand. */
7794 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7795 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7796 && INTVAL (operands[1]) > 32))
7797 && (GET_MODE (operands[0]) == SImode
7798 || GET_MODE (operands[0]) == DImode
7799 || GET_MODE (operands[0]) == HImode
7800 || GET_MODE (operands[0]) == QImode)"
7803 ;; Combine likes to form bit extractions for some tests. Humor it.
7804 (define_insn "*testqi_ext_3"
7805 [(set (reg FLAGS_REG)
7806 (compare (zero_extract:SI
7807 (match_operand 0 "nonimmediate_operand" "rm")
7808 (match_operand:SI 1 "const_int_operand" "")
7809 (match_operand:SI 2 "const_int_operand" ""))
7811 "ix86_match_ccmode (insn, CCNOmode)
7812 && INTVAL (operands[1]) > 0
7813 && INTVAL (operands[2]) >= 0
7814 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7815 && (GET_MODE (operands[0]) == SImode
7816 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7817 || GET_MODE (operands[0]) == HImode
7818 || GET_MODE (operands[0]) == QImode)"
7822 [(set (match_operand 0 "flags_reg_operand" "")
7823 (match_operator 1 "compare_operator"
7825 (match_operand 2 "nonimmediate_operand" "")
7826 (match_operand 3 "const_int_operand" "")
7827 (match_operand 4 "const_int_operand" ""))
7829 "ix86_match_ccmode (insn, CCNOmode)"
7830 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7832 rtx val = operands[2];
7833 HOST_WIDE_INT len = INTVAL (operands[3]);
7834 HOST_WIDE_INT pos = INTVAL (operands[4]);
7836 enum machine_mode mode, submode;
7838 mode = GET_MODE (val);
7841 /* ??? Combine likes to put non-volatile mem extractions in QImode
7842 no matter the size of the test. So find a mode that works. */
7843 if (! MEM_VOLATILE_P (val))
7845 mode = smallest_mode_for_size (pos + len, MODE_INT);
7846 val = adjust_address (val, mode, 0);
7849 else if (GET_CODE (val) == SUBREG
7850 && (submode = GET_MODE (SUBREG_REG (val)),
7851 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7852 && pos + len <= GET_MODE_BITSIZE (submode)
7853 && GET_MODE_CLASS (submode) == MODE_INT)
7855 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7857 val = SUBREG_REG (val);
7859 else if (mode == HImode && pos + len <= 8)
7861 /* Small HImode tests can be converted to QImode. */
7863 val = gen_lowpart (QImode, val);
7866 if (len == HOST_BITS_PER_WIDE_INT)
7869 mask = ((HOST_WIDE_INT)1 << len) - 1;
7872 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7875 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7876 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7877 ;; this is relatively important trick.
7878 ;; Do the conversion only post-reload to avoid limiting of the register class
7881 [(set (match_operand 0 "flags_reg_operand" "")
7882 (match_operator 1 "compare_operator"
7883 [(and (match_operand 2 "register_operand" "")
7884 (match_operand 3 "const_int_operand" ""))
7887 && QI_REG_P (operands[2])
7888 && GET_MODE (operands[2]) != QImode
7889 && ((ix86_match_ccmode (insn, CCZmode)
7890 && !(INTVAL (operands[3]) & ~(255 << 8)))
7891 || (ix86_match_ccmode (insn, CCNOmode)
7892 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7895 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7898 "operands[2] = gen_lowpart (SImode, operands[2]);
7899 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7902 [(set (match_operand 0 "flags_reg_operand" "")
7903 (match_operator 1 "compare_operator"
7904 [(and (match_operand 2 "nonimmediate_operand" "")
7905 (match_operand 3 "const_int_operand" ""))
7908 && GET_MODE (operands[2]) != QImode
7909 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7910 && ((ix86_match_ccmode (insn, CCZmode)
7911 && !(INTVAL (operands[3]) & ~255))
7912 || (ix86_match_ccmode (insn, CCNOmode)
7913 && !(INTVAL (operands[3]) & ~127)))"
7915 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7917 "operands[2] = gen_lowpart (QImode, operands[2]);
7918 operands[3] = gen_lowpart (QImode, operands[3]);")
7920 ;; %%% This used to optimize known byte-wide and operations to memory,
7921 ;; and sometimes to QImode registers. If this is considered useful,
7922 ;; it should be done with splitters.
7924 (define_expand "and<mode>3"
7925 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7926 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7927 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7929 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7931 (define_insn "*anddi_1"
7932 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7934 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7935 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7936 (clobber (reg:CC FLAGS_REG))]
7937 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7939 switch (get_attr_type (insn))
7943 enum machine_mode mode;
7945 gcc_assert (CONST_INT_P (operands[2]));
7946 if (INTVAL (operands[2]) == 0xff)
7950 gcc_assert (INTVAL (operands[2]) == 0xffff);
7954 operands[1] = gen_lowpart (mode, operands[1]);
7956 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7958 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7962 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7963 if (get_attr_mode (insn) == MODE_SI)
7964 return "and{l}\t{%k2, %k0|%k0, %k2}";
7966 return "and{q}\t{%2, %0|%0, %2}";
7969 [(set_attr "type" "alu,alu,alu,imovx")
7970 (set_attr "length_immediate" "*,*,*,0")
7971 (set (attr "prefix_rex")
7973 (and (eq_attr "type" "imovx")
7974 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7975 (match_operand 1 "ext_QIreg_operand" "")))
7977 (const_string "*")))
7978 (set_attr "mode" "SI,DI,DI,SI")])
7980 (define_insn "*andsi_1"
7981 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7982 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7983 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7984 (clobber (reg:CC FLAGS_REG))]
7985 "ix86_binary_operator_ok (AND, SImode, operands)"
7987 switch (get_attr_type (insn))
7991 enum machine_mode mode;
7993 gcc_assert (CONST_INT_P (operands[2]));
7994 if (INTVAL (operands[2]) == 0xff)
7998 gcc_assert (INTVAL (operands[2]) == 0xffff);
8002 operands[1] = gen_lowpart (mode, operands[1]);
8004 return "movz{bl|x}\t{%1, %0|%0, %1}";
8006 return "movz{wl|x}\t{%1, %0|%0, %1}";
8010 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8011 return "and{l}\t{%2, %0|%0, %2}";
8014 [(set_attr "type" "alu,alu,imovx")
8015 (set (attr "prefix_rex")
8017 (and (eq_attr "type" "imovx")
8018 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8019 (match_operand 1 "ext_QIreg_operand" "")))
8021 (const_string "*")))
8022 (set_attr "length_immediate" "*,*,0")
8023 (set_attr "mode" "SI")])
8025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8026 (define_insn "*andsi_1_zext"
8027 [(set (match_operand:DI 0 "register_operand" "=r")
8029 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8030 (match_operand:SI 2 "general_operand" "g"))))
8031 (clobber (reg:CC FLAGS_REG))]
8032 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8033 "and{l}\t{%2, %k0|%k0, %2}"
8034 [(set_attr "type" "alu")
8035 (set_attr "mode" "SI")])
8037 (define_insn "*andhi_1"
8038 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8039 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8040 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8041 (clobber (reg:CC FLAGS_REG))]
8042 "ix86_binary_operator_ok (AND, HImode, operands)"
8044 switch (get_attr_type (insn))
8047 gcc_assert (CONST_INT_P (operands[2]));
8048 gcc_assert (INTVAL (operands[2]) == 0xff);
8049 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8052 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8054 return "and{w}\t{%2, %0|%0, %2}";
8057 [(set_attr "type" "alu,alu,imovx")
8058 (set_attr "length_immediate" "*,*,0")
8059 (set (attr "prefix_rex")
8061 (and (eq_attr "type" "imovx")
8062 (match_operand 1 "ext_QIreg_operand" ""))
8064 (const_string "*")))
8065 (set_attr "mode" "HI,HI,SI")])
8067 ;; %%% Potential partial reg stall on alternative 2. What to do?
8068 (define_insn "*andqi_1"
8069 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8070 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8071 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8072 (clobber (reg:CC FLAGS_REG))]
8073 "ix86_binary_operator_ok (AND, QImode, operands)"
8075 and{b}\t{%2, %0|%0, %2}
8076 and{b}\t{%2, %0|%0, %2}
8077 and{l}\t{%k2, %k0|%k0, %k2}"
8078 [(set_attr "type" "alu")
8079 (set_attr "mode" "QI,QI,SI")])
8081 (define_insn "*andqi_1_slp"
8082 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8083 (and:QI (match_dup 0)
8084 (match_operand:QI 1 "general_operand" "qn,qmn")))
8085 (clobber (reg:CC FLAGS_REG))]
8086 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8087 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8088 "and{b}\t{%1, %0|%0, %1}"
8089 [(set_attr "type" "alu1")
8090 (set_attr "mode" "QI")])
8093 [(set (match_operand 0 "register_operand" "")
8095 (const_int -65536)))
8096 (clobber (reg:CC FLAGS_REG))]
8097 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8098 || optimize_function_for_size_p (cfun)"
8099 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8100 "operands[1] = gen_lowpart (HImode, operands[0]);")
8103 [(set (match_operand 0 "ext_register_operand" "")
8106 (clobber (reg:CC FLAGS_REG))]
8107 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8108 && reload_completed"
8109 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8110 "operands[1] = gen_lowpart (QImode, operands[0]);")
8113 [(set (match_operand 0 "ext_register_operand" "")
8115 (const_int -65281)))
8116 (clobber (reg:CC FLAGS_REG))]
8117 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8118 && reload_completed"
8119 [(parallel [(set (zero_extract:SI (match_dup 0)
8123 (zero_extract:SI (match_dup 0)
8126 (zero_extract:SI (match_dup 0)
8129 (clobber (reg:CC FLAGS_REG))])]
8130 "operands[0] = gen_lowpart (SImode, operands[0]);")
8132 (define_insn "*anddi_2"
8133 [(set (reg FLAGS_REG)
8136 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8137 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8139 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8140 (and:DI (match_dup 1) (match_dup 2)))]
8141 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8142 && ix86_binary_operator_ok (AND, DImode, operands)"
8144 and{l}\t{%k2, %k0|%k0, %k2}
8145 and{q}\t{%2, %0|%0, %2}
8146 and{q}\t{%2, %0|%0, %2}"
8147 [(set_attr "type" "alu")
8148 (set_attr "mode" "SI,DI,DI")])
8150 (define_insn "*andqi_2_maybe_si"
8151 [(set (reg FLAGS_REG)
8153 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8154 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8156 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8157 (and:QI (match_dup 1) (match_dup 2)))]
8158 "ix86_binary_operator_ok (AND, QImode, operands)
8159 && ix86_match_ccmode (insn,
8160 CONST_INT_P (operands[2])
8161 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8163 if (which_alternative == 2)
8165 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8166 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8167 return "and{l}\t{%2, %k0|%k0, %2}";
8169 return "and{b}\t{%2, %0|%0, %2}";
8171 [(set_attr "type" "alu")
8172 (set_attr "mode" "QI,QI,SI")])
8174 (define_insn "*and<mode>_2"
8175 [(set (reg FLAGS_REG)
8176 (compare (and:SWI124
8177 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8178 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8180 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8181 (and:SWI124 (match_dup 1) (match_dup 2)))]
8182 "ix86_match_ccmode (insn, CCNOmode)
8183 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8184 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8185 [(set_attr "type" "alu")
8186 (set_attr "mode" "<MODE>")])
8188 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8189 (define_insn "*andsi_2_zext"
8190 [(set (reg FLAGS_REG)
8192 (match_operand:SI 1 "nonimmediate_operand" "%0")
8193 (match_operand:SI 2 "general_operand" "g"))
8195 (set (match_operand:DI 0 "register_operand" "=r")
8196 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8197 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8198 && ix86_binary_operator_ok (AND, SImode, operands)"
8199 "and{l}\t{%2, %k0|%k0, %2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "mode" "SI")])
8203 (define_insn "*andqi_2_slp"
8204 [(set (reg FLAGS_REG)
8206 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8207 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8209 (set (strict_low_part (match_dup 0))
8210 (and:QI (match_dup 0) (match_dup 1)))]
8211 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8212 && ix86_match_ccmode (insn, CCNOmode)
8213 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8214 "and{b}\t{%1, %0|%0, %1}"
8215 [(set_attr "type" "alu1")
8216 (set_attr "mode" "QI")])
8218 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8219 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8220 ;; for a QImode operand, which of course failed.
8221 (define_insn "andqi_ext_0"
8222 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8227 (match_operand 1 "ext_register_operand" "0")
8230 (match_operand 2 "const_int_operand" "n")))
8231 (clobber (reg:CC FLAGS_REG))]
8233 "and{b}\t{%2, %h0|%h0, %2}"
8234 [(set_attr "type" "alu")
8235 (set_attr "length_immediate" "1")
8236 (set_attr "modrm" "1")
8237 (set_attr "mode" "QI")])
8239 ;; Generated by peephole translating test to and. This shows up
8240 ;; often in fp comparisons.
8241 (define_insn "*andqi_ext_0_cc"
8242 [(set (reg FLAGS_REG)
8246 (match_operand 1 "ext_register_operand" "0")
8249 (match_operand 2 "const_int_operand" "n"))
8251 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8260 "ix86_match_ccmode (insn, CCNOmode)"
8261 "and{b}\t{%2, %h0|%h0, %2}"
8262 [(set_attr "type" "alu")
8263 (set_attr "length_immediate" "1")
8264 (set_attr "modrm" "1")
8265 (set_attr "mode" "QI")])
8267 (define_insn "*andqi_ext_1_rex64"
8268 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8273 (match_operand 1 "ext_register_operand" "0")
8277 (match_operand 2 "ext_register_operand" "Q"))))
8278 (clobber (reg:CC FLAGS_REG))]
8280 "and{b}\t{%2, %h0|%h0, %2}"
8281 [(set_attr "type" "alu")
8282 (set_attr "length_immediate" "0")
8283 (set_attr "mode" "QI")])
8285 (define_insn "*andqi_ext_1"
8286 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8291 (match_operand 1 "ext_register_operand" "0")
8295 (match_operand:QI 2 "general_operand" "Qm"))))
8296 (clobber (reg:CC FLAGS_REG))]
8298 "and{b}\t{%2, %h0|%h0, %2}"
8299 [(set_attr "type" "alu")
8300 (set_attr "length_immediate" "0")
8301 (set_attr "mode" "QI")])
8303 (define_insn "*andqi_ext_2"
8304 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8309 (match_operand 1 "ext_register_operand" "%0")
8313 (match_operand 2 "ext_register_operand" "Q")
8316 (clobber (reg:CC FLAGS_REG))]
8318 "and{b}\t{%h2, %h0|%h0, %h2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "length_immediate" "0")
8321 (set_attr "mode" "QI")])
8323 ;; Convert wide AND instructions with immediate operand to shorter QImode
8324 ;; equivalents when possible.
8325 ;; Don't do the splitting with memory operands, since it introduces risk
8326 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8327 ;; for size, but that can (should?) be handled by generic code instead.
8329 [(set (match_operand 0 "register_operand" "")
8330 (and (match_operand 1 "register_operand" "")
8331 (match_operand 2 "const_int_operand" "")))
8332 (clobber (reg:CC FLAGS_REG))]
8334 && QI_REG_P (operands[0])
8335 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8336 && !(~INTVAL (operands[2]) & ~(255 << 8))
8337 && GET_MODE (operands[0]) != QImode"
8338 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8339 (and:SI (zero_extract:SI (match_dup 1)
8340 (const_int 8) (const_int 8))
8342 (clobber (reg:CC FLAGS_REG))])]
8343 "operands[0] = gen_lowpart (SImode, operands[0]);
8344 operands[1] = gen_lowpart (SImode, operands[1]);
8345 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8347 ;; Since AND can be encoded with sign extended immediate, this is only
8348 ;; profitable when 7th bit is not set.
8350 [(set (match_operand 0 "register_operand" "")
8351 (and (match_operand 1 "general_operand" "")
8352 (match_operand 2 "const_int_operand" "")))
8353 (clobber (reg:CC FLAGS_REG))]
8355 && ANY_QI_REG_P (operands[0])
8356 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8357 && !(~INTVAL (operands[2]) & ~255)
8358 && !(INTVAL (operands[2]) & 128)
8359 && GET_MODE (operands[0]) != QImode"
8360 [(parallel [(set (strict_low_part (match_dup 0))
8361 (and:QI (match_dup 1)
8363 (clobber (reg:CC FLAGS_REG))])]
8364 "operands[0] = gen_lowpart (QImode, operands[0]);
8365 operands[1] = gen_lowpart (QImode, operands[1]);
8366 operands[2] = gen_lowpart (QImode, operands[2]);")
8368 ;; Logical inclusive and exclusive OR instructions
8370 ;; %%% This used to optimize known byte-wide and operations to memory.
8371 ;; If this is considered useful, it should be done with splitters.
8373 (define_expand "<code><mode>3"
8374 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8375 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8376 (match_operand:SWIM 2 "<general_operand>" "")))]
8378 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8380 (define_insn "*<code><mode>_1"
8381 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8383 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8384 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8385 (clobber (reg:CC FLAGS_REG))]
8386 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8387 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8388 [(set_attr "type" "alu")
8389 (set_attr "mode" "<MODE>")])
8391 ;; %%% Potential partial reg stall on alternative 2. What to do?
8392 (define_insn "*<code>qi_1"
8393 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8394 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8395 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8396 (clobber (reg:CC FLAGS_REG))]
8397 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8399 <logic>{b}\t{%2, %0|%0, %2}
8400 <logic>{b}\t{%2, %0|%0, %2}
8401 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8402 [(set_attr "type" "alu")
8403 (set_attr "mode" "QI,QI,SI")])
8405 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8406 (define_insn "*<code>si_1_zext"
8407 [(set (match_operand:DI 0 "register_operand" "=r")
8409 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8410 (match_operand:SI 2 "general_operand" "g"))))
8411 (clobber (reg:CC FLAGS_REG))]
8412 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8413 "<logic>{l}\t{%2, %k0|%k0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "SI")])
8417 (define_insn "*<code>si_1_zext_imm"
8418 [(set (match_operand:DI 0 "register_operand" "=r")
8420 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8421 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8422 (clobber (reg:CC FLAGS_REG))]
8423 "TARGET_64BIT && 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>qi_1_slp"
8429 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8430 (any_or:QI (match_dup 0)
8431 (match_operand:QI 1 "general_operand" "qmn,qn")))
8432 (clobber (reg:CC FLAGS_REG))]
8433 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8434 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8435 "<logic>{b}\t{%1, %0|%0, %1}"
8436 [(set_attr "type" "alu1")
8437 (set_attr "mode" "QI")])
8439 (define_insn "*<code><mode>_2"
8440 [(set (reg FLAGS_REG)
8441 (compare (any_or:SWI
8442 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8443 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8445 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8446 (any_or:SWI (match_dup 1) (match_dup 2)))]
8447 "ix86_match_ccmode (insn, CCNOmode)
8448 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8449 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8450 [(set_attr "type" "alu")
8451 (set_attr "mode" "<MODE>")])
8453 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8454 ;; ??? Special case for immediate operand is missing - it is tricky.
8455 (define_insn "*<code>si_2_zext"
8456 [(set (reg FLAGS_REG)
8457 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8458 (match_operand:SI 2 "general_operand" "g"))
8460 (set (match_operand:DI 0 "register_operand" "=r")
8461 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8462 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8463 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8464 "<logic>{l}\t{%2, %k0|%k0, %2}"
8465 [(set_attr "type" "alu")
8466 (set_attr "mode" "SI")])
8468 (define_insn "*<code>si_2_zext_imm"
8469 [(set (reg FLAGS_REG)
8471 (match_operand:SI 1 "nonimmediate_operand" "%0")
8472 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8474 (set (match_operand:DI 0 "register_operand" "=r")
8475 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8476 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8477 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8478 "<logic>{l}\t{%2, %k0|%k0, %2}"
8479 [(set_attr "type" "alu")
8480 (set_attr "mode" "SI")])
8482 (define_insn "*<code>qi_2_slp"
8483 [(set (reg FLAGS_REG)
8484 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8485 (match_operand:QI 1 "general_operand" "qmn,qn"))
8487 (set (strict_low_part (match_dup 0))
8488 (any_or:QI (match_dup 0) (match_dup 1)))]
8489 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8490 && ix86_match_ccmode (insn, CCNOmode)
8491 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8492 "<logic>{b}\t{%1, %0|%0, %1}"
8493 [(set_attr "type" "alu1")
8494 (set_attr "mode" "QI")])
8496 (define_insn "*<code><mode>_3"
8497 [(set (reg FLAGS_REG)
8498 (compare (any_or:SWI
8499 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8500 (match_operand:SWI 2 "<general_operand>" "<g>"))
8502 (clobber (match_scratch:SWI 0 "=<r>"))]
8503 "ix86_match_ccmode (insn, CCNOmode)
8504 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8505 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8506 [(set_attr "type" "alu")
8507 (set_attr "mode" "<MODE>")])
8509 (define_insn "*<code>qi_ext_0"
8510 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8515 (match_operand 1 "ext_register_operand" "0")
8518 (match_operand 2 "const_int_operand" "n")))
8519 (clobber (reg:CC FLAGS_REG))]
8520 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8521 "<logic>{b}\t{%2, %h0|%h0, %2}"
8522 [(set_attr "type" "alu")
8523 (set_attr "length_immediate" "1")
8524 (set_attr "modrm" "1")
8525 (set_attr "mode" "QI")])
8527 (define_insn "*<code>qi_ext_1_rex64"
8528 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8533 (match_operand 1 "ext_register_operand" "0")
8537 (match_operand 2 "ext_register_operand" "Q"))))
8538 (clobber (reg:CC FLAGS_REG))]
8540 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8541 "<logic>{b}\t{%2, %h0|%h0, %2}"
8542 [(set_attr "type" "alu")
8543 (set_attr "length_immediate" "0")
8544 (set_attr "mode" "QI")])
8546 (define_insn "*<code>qi_ext_1"
8547 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8552 (match_operand 1 "ext_register_operand" "0")
8556 (match_operand:QI 2 "general_operand" "Qm"))))
8557 (clobber (reg:CC FLAGS_REG))]
8559 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8560 "<logic>{b}\t{%2, %h0|%h0, %2}"
8561 [(set_attr "type" "alu")
8562 (set_attr "length_immediate" "0")
8563 (set_attr "mode" "QI")])
8565 (define_insn "*<code>qi_ext_2"
8566 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8570 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8573 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8576 (clobber (reg:CC FLAGS_REG))]
8577 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8578 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8579 [(set_attr "type" "alu")
8580 (set_attr "length_immediate" "0")
8581 (set_attr "mode" "QI")])
8584 [(set (match_operand 0 "register_operand" "")
8585 (any_or (match_operand 1 "register_operand" "")
8586 (match_operand 2 "const_int_operand" "")))
8587 (clobber (reg:CC FLAGS_REG))]
8589 && QI_REG_P (operands[0])
8590 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8591 && !(INTVAL (operands[2]) & ~(255 << 8))
8592 && GET_MODE (operands[0]) != QImode"
8593 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8594 (any_or:SI (zero_extract:SI (match_dup 1)
8595 (const_int 8) (const_int 8))
8597 (clobber (reg:CC FLAGS_REG))])]
8598 "operands[0] = gen_lowpart (SImode, operands[0]);
8599 operands[1] = gen_lowpart (SImode, operands[1]);
8600 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8602 ;; Since OR can be encoded with sign extended immediate, this is only
8603 ;; profitable when 7th bit is set.
8605 [(set (match_operand 0 "register_operand" "")
8606 (any_or (match_operand 1 "general_operand" "")
8607 (match_operand 2 "const_int_operand" "")))
8608 (clobber (reg:CC FLAGS_REG))]
8610 && ANY_QI_REG_P (operands[0])
8611 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8612 && !(INTVAL (operands[2]) & ~255)
8613 && (INTVAL (operands[2]) & 128)
8614 && GET_MODE (operands[0]) != QImode"
8615 [(parallel [(set (strict_low_part (match_dup 0))
8616 (any_or:QI (match_dup 1)
8618 (clobber (reg:CC FLAGS_REG))])]
8619 "operands[0] = gen_lowpart (QImode, operands[0]);
8620 operands[1] = gen_lowpart (QImode, operands[1]);
8621 operands[2] = gen_lowpart (QImode, operands[2]);")
8623 (define_expand "xorqi_cc_ext_1"
8625 (set (reg:CCNO FLAGS_REG)
8629 (match_operand 1 "ext_register_operand" "")
8632 (match_operand:QI 2 "general_operand" ""))
8634 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8644 (define_insn "*xorqi_cc_ext_1_rex64"
8645 [(set (reg FLAGS_REG)
8649 (match_operand 1 "ext_register_operand" "0")
8652 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8654 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8663 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8664 "xor{b}\t{%2, %h0|%h0, %2}"
8665 [(set_attr "type" "alu")
8666 (set_attr "modrm" "1")
8667 (set_attr "mode" "QI")])
8669 (define_insn "*xorqi_cc_ext_1"
8670 [(set (reg FLAGS_REG)
8674 (match_operand 1 "ext_register_operand" "0")
8677 (match_operand:QI 2 "general_operand" "qmn"))
8679 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8688 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8689 "xor{b}\t{%2, %h0|%h0, %2}"
8690 [(set_attr "type" "alu")
8691 (set_attr "modrm" "1")
8692 (set_attr "mode" "QI")])
8694 ;; Negation instructions
8696 (define_expand "neg<mode>2"
8697 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8698 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8700 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8702 (define_insn_and_split "*neg<dwi>2_doubleword"
8703 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8704 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8705 (clobber (reg:CC FLAGS_REG))]
8706 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8710 [(set (reg:CCZ FLAGS_REG)
8711 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8712 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8715 (plus:DWIH (match_dup 3)
8716 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8718 (clobber (reg:CC FLAGS_REG))])
8721 (neg:DWIH (match_dup 2)))
8722 (clobber (reg:CC FLAGS_REG))])]
8723 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8725 (define_insn "*neg<mode>2_1"
8726 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8727 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8728 (clobber (reg:CC FLAGS_REG))]
8729 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8730 "neg{<imodesuffix>}\t%0"
8731 [(set_attr "type" "negnot")
8732 (set_attr "mode" "<MODE>")])
8734 ;; Combine is quite creative about this pattern.
8735 (define_insn "*negsi2_1_zext"
8736 [(set (match_operand:DI 0 "register_operand" "=r")
8738 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8741 (clobber (reg:CC FLAGS_REG))]
8742 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8744 [(set_attr "type" "negnot")
8745 (set_attr "mode" "SI")])
8747 ;; The problem with neg is that it does not perform (compare x 0),
8748 ;; it really performs (compare 0 x), which leaves us with the zero
8749 ;; flag being the only useful item.
8751 (define_insn "*neg<mode>2_cmpz"
8752 [(set (reg:CCZ FLAGS_REG)
8754 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8756 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8757 (neg:SWI (match_dup 1)))]
8758 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8759 "neg{<imodesuffix>}\t%0"
8760 [(set_attr "type" "negnot")
8761 (set_attr "mode" "<MODE>")])
8763 (define_insn "*negsi2_cmpz_zext"
8764 [(set (reg:CCZ FLAGS_REG)
8768 (match_operand:DI 1 "register_operand" "0")
8772 (set (match_operand:DI 0 "register_operand" "=r")
8773 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8776 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8778 [(set_attr "type" "negnot")
8779 (set_attr "mode" "SI")])
8781 ;; Changing of sign for FP values is doable using integer unit too.
8783 (define_expand "<code><mode>2"
8784 [(set (match_operand:X87MODEF 0 "register_operand" "")
8785 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8786 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8787 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8789 (define_insn "*absneg<mode>2_mixed"
8790 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8791 (match_operator:MODEF 3 "absneg_operator"
8792 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8793 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8794 (clobber (reg:CC FLAGS_REG))]
8795 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8798 (define_insn "*absneg<mode>2_sse"
8799 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8800 (match_operator:MODEF 3 "absneg_operator"
8801 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8802 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8803 (clobber (reg:CC FLAGS_REG))]
8804 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8807 (define_insn "*absneg<mode>2_i387"
8808 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8809 (match_operator:X87MODEF 3 "absneg_operator"
8810 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8811 (use (match_operand 2 "" ""))
8812 (clobber (reg:CC FLAGS_REG))]
8813 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8816 (define_expand "<code>tf2"
8817 [(set (match_operand:TF 0 "register_operand" "")
8818 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8820 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8822 (define_insn "*absnegtf2_sse"
8823 [(set (match_operand:TF 0 "register_operand" "=x,x")
8824 (match_operator:TF 3 "absneg_operator"
8825 [(match_operand:TF 1 "register_operand" "0,x")]))
8826 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8827 (clobber (reg:CC FLAGS_REG))]
8831 ;; Splitters for fp abs and neg.
8834 [(set (match_operand 0 "fp_register_operand" "")
8835 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8836 (use (match_operand 2 "" ""))
8837 (clobber (reg:CC FLAGS_REG))]
8839 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8842 [(set (match_operand 0 "register_operand" "")
8843 (match_operator 3 "absneg_operator"
8844 [(match_operand 1 "register_operand" "")]))
8845 (use (match_operand 2 "nonimmediate_operand" ""))
8846 (clobber (reg:CC FLAGS_REG))]
8847 "reload_completed && SSE_REG_P (operands[0])"
8848 [(set (match_dup 0) (match_dup 3))]
8850 enum machine_mode mode = GET_MODE (operands[0]);
8851 enum machine_mode vmode = GET_MODE (operands[2]);
8854 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8855 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8856 if (operands_match_p (operands[0], operands[2]))
8859 operands[1] = operands[2];
8862 if (GET_CODE (operands[3]) == ABS)
8863 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8865 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8870 [(set (match_operand:SF 0 "register_operand" "")
8871 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8872 (use (match_operand:V4SF 2 "" ""))
8873 (clobber (reg:CC FLAGS_REG))]
8875 [(parallel [(set (match_dup 0) (match_dup 1))
8876 (clobber (reg:CC FLAGS_REG))])]
8879 operands[0] = gen_lowpart (SImode, operands[0]);
8880 if (GET_CODE (operands[1]) == ABS)
8882 tmp = gen_int_mode (0x7fffffff, SImode);
8883 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8887 tmp = gen_int_mode (0x80000000, SImode);
8888 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8894 [(set (match_operand:DF 0 "register_operand" "")
8895 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8896 (use (match_operand 2 "" ""))
8897 (clobber (reg:CC FLAGS_REG))]
8899 [(parallel [(set (match_dup 0) (match_dup 1))
8900 (clobber (reg:CC FLAGS_REG))])]
8905 tmp = gen_lowpart (DImode, operands[0]);
8906 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8909 if (GET_CODE (operands[1]) == ABS)
8912 tmp = gen_rtx_NOT (DImode, tmp);
8916 operands[0] = gen_highpart (SImode, operands[0]);
8917 if (GET_CODE (operands[1]) == ABS)
8919 tmp = gen_int_mode (0x7fffffff, SImode);
8920 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8924 tmp = gen_int_mode (0x80000000, SImode);
8925 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8932 [(set (match_operand:XF 0 "register_operand" "")
8933 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8934 (use (match_operand 2 "" ""))
8935 (clobber (reg:CC FLAGS_REG))]
8937 [(parallel [(set (match_dup 0) (match_dup 1))
8938 (clobber (reg:CC FLAGS_REG))])]
8941 operands[0] = gen_rtx_REG (SImode,
8942 true_regnum (operands[0])
8943 + (TARGET_64BIT ? 1 : 2));
8944 if (GET_CODE (operands[1]) == ABS)
8946 tmp = GEN_INT (0x7fff);
8947 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8951 tmp = GEN_INT (0x8000);
8952 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8957 ;; Conditionalize these after reload. If they match before reload, we
8958 ;; lose the clobber and ability to use integer instructions.
8960 (define_insn "*<code><mode>2_1"
8961 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8962 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8964 && (reload_completed
8965 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8966 "f<absneg_mnemonic>"
8967 [(set_attr "type" "fsgn")
8968 (set_attr "mode" "<MODE>")])
8970 (define_insn "*<code>extendsfdf2"
8971 [(set (match_operand:DF 0 "register_operand" "=f")
8972 (absneg:DF (float_extend:DF
8973 (match_operand:SF 1 "register_operand" "0"))))]
8974 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8975 "f<absneg_mnemonic>"
8976 [(set_attr "type" "fsgn")
8977 (set_attr "mode" "DF")])
8979 (define_insn "*<code>extendsfxf2"
8980 [(set (match_operand:XF 0 "register_operand" "=f")
8981 (absneg:XF (float_extend:XF
8982 (match_operand:SF 1 "register_operand" "0"))))]
8984 "f<absneg_mnemonic>"
8985 [(set_attr "type" "fsgn")
8986 (set_attr "mode" "XF")])
8988 (define_insn "*<code>extenddfxf2"
8989 [(set (match_operand:XF 0 "register_operand" "=f")
8990 (absneg:XF (float_extend:XF
8991 (match_operand:DF 1 "register_operand" "0"))))]
8993 "f<absneg_mnemonic>"
8994 [(set_attr "type" "fsgn")
8995 (set_attr "mode" "XF")])
8997 ;; Copysign instructions
8999 (define_mode_iterator CSGNMODE [SF DF TF])
9000 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9002 (define_expand "copysign<mode>3"
9003 [(match_operand:CSGNMODE 0 "register_operand" "")
9004 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9005 (match_operand:CSGNMODE 2 "register_operand" "")]
9006 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9007 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9008 "ix86_expand_copysign (operands); DONE;")
9010 (define_insn_and_split "copysign<mode>3_const"
9011 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9013 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9014 (match_operand:CSGNMODE 2 "register_operand" "0")
9015 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9017 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9018 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9020 "&& reload_completed"
9022 "ix86_split_copysign_const (operands); DONE;")
9024 (define_insn "copysign<mode>3_var"
9025 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9027 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9028 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9029 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9030 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9032 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9033 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9034 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9038 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9040 [(match_operand:CSGNMODE 2 "register_operand" "")
9041 (match_operand:CSGNMODE 3 "register_operand" "")
9042 (match_operand:<CSGNVMODE> 4 "" "")
9043 (match_operand:<CSGNVMODE> 5 "" "")]
9045 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9046 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9047 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9048 && reload_completed"
9050 "ix86_split_copysign_var (operands); DONE;")
9052 ;; One complement instructions
9054 (define_expand "one_cmpl<mode>2"
9055 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9056 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9058 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9060 (define_insn "*one_cmpl<mode>2_1"
9061 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9062 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9063 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9064 "not{<imodesuffix>}\t%0"
9065 [(set_attr "type" "negnot")
9066 (set_attr "mode" "<MODE>")])
9068 ;; %%% Potential partial reg stall on alternative 1. What to do?
9069 (define_insn "*one_cmplqi2_1"
9070 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9071 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9072 "ix86_unary_operator_ok (NOT, QImode, operands)"
9076 [(set_attr "type" "negnot")
9077 (set_attr "mode" "QI,SI")])
9079 ;; ??? Currently never generated - xor is used instead.
9080 (define_insn "*one_cmplsi2_1_zext"
9081 [(set (match_operand:DI 0 "register_operand" "=r")
9083 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9084 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9086 [(set_attr "type" "negnot")
9087 (set_attr "mode" "SI")])
9089 (define_insn "*one_cmpl<mode>2_2"
9090 [(set (reg FLAGS_REG)
9091 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9093 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9094 (not:SWI (match_dup 1)))]
9095 "ix86_match_ccmode (insn, CCNOmode)
9096 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9098 [(set_attr "type" "alu1")
9099 (set_attr "mode" "<MODE>")])
9102 [(set (match_operand 0 "flags_reg_operand" "")
9103 (match_operator 2 "compare_operator"
9104 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9106 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9107 (not:SWI (match_dup 3)))]
9108 "ix86_match_ccmode (insn, CCNOmode)"
9109 [(parallel [(set (match_dup 0)
9110 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9113 (xor:SWI (match_dup 3) (const_int -1)))])])
9115 ;; ??? Currently never generated - xor is used instead.
9116 (define_insn "*one_cmplsi2_2_zext"
9117 [(set (reg FLAGS_REG)
9118 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9120 (set (match_operand:DI 0 "register_operand" "=r")
9121 (zero_extend:DI (not:SI (match_dup 1))))]
9122 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9123 && ix86_unary_operator_ok (NOT, SImode, operands)"
9125 [(set_attr "type" "alu1")
9126 (set_attr "mode" "SI")])
9129 [(set (match_operand 0 "flags_reg_operand" "")
9130 (match_operator 2 "compare_operator"
9131 [(not:SI (match_operand:SI 3 "register_operand" ""))
9133 (set (match_operand:DI 1 "register_operand" "")
9134 (zero_extend:DI (not:SI (match_dup 3))))]
9135 "ix86_match_ccmode (insn, CCNOmode)"
9136 [(parallel [(set (match_dup 0)
9137 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9140 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9142 ;; Shift instructions
9144 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9145 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9146 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9147 ;; from the assembler input.
9149 ;; This instruction shifts the target reg/mem as usual, but instead of
9150 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9151 ;; is a left shift double, bits are taken from the high order bits of
9152 ;; reg, else if the insn is a shift right double, bits are taken from the
9153 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9154 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9156 ;; Since sh[lr]d does not change the `reg' operand, that is done
9157 ;; separately, making all shifts emit pairs of shift double and normal
9158 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9159 ;; support a 63 bit shift, each shift where the count is in a reg expands
9160 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9162 ;; If the shift count is a constant, we need never emit more than one
9163 ;; shift pair, instead using moves and sign extension for counts greater
9166 (define_expand "ashl<mode>3"
9167 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9168 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9169 (match_operand:QI 2 "nonmemory_operand" "")))]
9171 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9173 (define_insn "*ashl<mode>3_doubleword"
9174 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9175 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9176 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9177 (clobber (reg:CC FLAGS_REG))]
9180 [(set_attr "type" "multi")])
9183 [(set (match_operand:DWI 0 "register_operand" "")
9184 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9185 (match_operand:QI 2 "nonmemory_operand" "")))
9186 (clobber (reg:CC FLAGS_REG))]
9187 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9189 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9191 ;; By default we don't ask for a scratch register, because when DWImode
9192 ;; values are manipulated, registers are already at a premium. But if
9193 ;; we have one handy, we won't turn it away.
9196 [(match_scratch:DWIH 3 "r")
9197 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9199 (match_operand:<DWI> 1 "nonmemory_operand" "")
9200 (match_operand:QI 2 "nonmemory_operand" "")))
9201 (clobber (reg:CC FLAGS_REG))])
9205 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9207 (define_insn "x86_64_shld"
9208 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9209 (ior:DI (ashift:DI (match_dup 0)
9210 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9211 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9212 (minus:QI (const_int 64) (match_dup 2)))))
9213 (clobber (reg:CC FLAGS_REG))]
9215 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9216 [(set_attr "type" "ishift")
9217 (set_attr "prefix_0f" "1")
9218 (set_attr "mode" "DI")
9219 (set_attr "athlon_decode" "vector")
9220 (set_attr "amdfam10_decode" "vector")
9221 (set_attr "bdver1_decode" "vector")])
9223 (define_insn "x86_shld"
9224 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9225 (ior:SI (ashift:SI (match_dup 0)
9226 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9227 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9228 (minus:QI (const_int 32) (match_dup 2)))))
9229 (clobber (reg:CC FLAGS_REG))]
9231 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9232 [(set_attr "type" "ishift")
9233 (set_attr "prefix_0f" "1")
9234 (set_attr "mode" "SI")
9235 (set_attr "pent_pair" "np")
9236 (set_attr "athlon_decode" "vector")
9237 (set_attr "amdfam10_decode" "vector")
9238 (set_attr "bdver1_decode" "vector")])
9240 (define_expand "x86_shift<mode>_adj_1"
9241 [(set (reg:CCZ FLAGS_REG)
9242 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9245 (set (match_operand:SWI48 0 "register_operand" "")
9246 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9247 (match_operand:SWI48 1 "register_operand" "")
9250 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9251 (match_operand:SWI48 3 "register_operand" "r")
9254 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9256 (define_expand "x86_shift<mode>_adj_2"
9257 [(use (match_operand:SWI48 0 "register_operand" ""))
9258 (use (match_operand:SWI48 1 "register_operand" ""))
9259 (use (match_operand:QI 2 "register_operand" ""))]
9262 rtx label = gen_label_rtx ();
9265 emit_insn (gen_testqi_ccz_1 (operands[2],
9266 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9268 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9269 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9270 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9271 gen_rtx_LABEL_REF (VOIDmode, label),
9273 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9274 JUMP_LABEL (tmp) = label;
9276 emit_move_insn (operands[0], operands[1]);
9277 ix86_expand_clear (operands[1]);
9280 LABEL_NUSES (label) = 1;
9285 ;; Avoid useless masking of count operand.
9286 (define_insn_and_split "*ashl<mode>3_mask"
9287 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9289 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9292 (match_operand:SI 2 "nonimmediate_operand" "c")
9293 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9294 (clobber (reg:CC FLAGS_REG))]
9295 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9296 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9297 == GET_MODE_BITSIZE (<MODE>mode)-1"
9300 [(parallel [(set (match_dup 0)
9301 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9302 (clobber (reg:CC FLAGS_REG))])]
9304 if (can_create_pseudo_p ())
9305 operands [2] = force_reg (SImode, operands[2]);
9307 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9309 [(set_attr "type" "ishift")
9310 (set_attr "mode" "<MODE>")])
9312 (define_insn "*ashl<mode>3_1"
9313 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9314 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9315 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9316 (clobber (reg:CC FLAGS_REG))]
9317 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9319 switch (get_attr_type (insn))
9325 gcc_assert (operands[2] == const1_rtx);
9326 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9327 return "add{<imodesuffix>}\t%0, %0";
9330 if (operands[2] == const1_rtx
9331 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9332 return "sal{<imodesuffix>}\t%0";
9334 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9338 (cond [(eq_attr "alternative" "1")
9339 (const_string "lea")
9340 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9342 (match_operand 0 "register_operand" ""))
9343 (match_operand 2 "const1_operand" ""))
9344 (const_string "alu")
9346 (const_string "ishift")))
9347 (set (attr "length_immediate")
9349 (ior (eq_attr "type" "alu")
9350 (and (eq_attr "type" "ishift")
9351 (and (match_operand 2 "const1_operand" "")
9352 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9355 (const_string "*")))
9356 (set_attr "mode" "<MODE>")])
9358 (define_insn "*ashlsi3_1_zext"
9359 [(set (match_operand:DI 0 "register_operand" "=r,r")
9361 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9362 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9363 (clobber (reg:CC FLAGS_REG))]
9364 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9366 switch (get_attr_type (insn))
9372 gcc_assert (operands[2] == const1_rtx);
9373 return "add{l}\t%k0, %k0";
9376 if (operands[2] == const1_rtx
9377 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9378 return "sal{l}\t%k0";
9380 return "sal{l}\t{%2, %k0|%k0, %2}";
9384 (cond [(eq_attr "alternative" "1")
9385 (const_string "lea")
9386 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9388 (match_operand 2 "const1_operand" ""))
9389 (const_string "alu")
9391 (const_string "ishift")))
9392 (set (attr "length_immediate")
9394 (ior (eq_attr "type" "alu")
9395 (and (eq_attr "type" "ishift")
9396 (and (match_operand 2 "const1_operand" "")
9397 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9400 (const_string "*")))
9401 (set_attr "mode" "SI")])
9403 (define_insn "*ashlhi3_1"
9404 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9405 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9406 (match_operand:QI 2 "nonmemory_operand" "cI")))
9407 (clobber (reg:CC FLAGS_REG))]
9408 "TARGET_PARTIAL_REG_STALL
9409 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9411 switch (get_attr_type (insn))
9414 gcc_assert (operands[2] == const1_rtx);
9415 return "add{w}\t%0, %0";
9418 if (operands[2] == const1_rtx
9419 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9420 return "sal{w}\t%0";
9422 return "sal{w}\t{%2, %0|%0, %2}";
9426 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9428 (match_operand 0 "register_operand" ""))
9429 (match_operand 2 "const1_operand" ""))
9430 (const_string "alu")
9432 (const_string "ishift")))
9433 (set (attr "length_immediate")
9435 (ior (eq_attr "type" "alu")
9436 (and (eq_attr "type" "ishift")
9437 (and (match_operand 2 "const1_operand" "")
9438 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9441 (const_string "*")))
9442 (set_attr "mode" "HI")])
9444 (define_insn "*ashlhi3_1_lea"
9445 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9446 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9447 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9448 (clobber (reg:CC FLAGS_REG))]
9449 "!TARGET_PARTIAL_REG_STALL
9450 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9452 switch (get_attr_type (insn))
9458 gcc_assert (operands[2] == const1_rtx);
9459 return "add{w}\t%0, %0";
9462 if (operands[2] == const1_rtx
9463 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9464 return "sal{w}\t%0";
9466 return "sal{w}\t{%2, %0|%0, %2}";
9470 (cond [(eq_attr "alternative" "1")
9471 (const_string "lea")
9472 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9474 (match_operand 0 "register_operand" ""))
9475 (match_operand 2 "const1_operand" ""))
9476 (const_string "alu")
9478 (const_string "ishift")))
9479 (set (attr "length_immediate")
9481 (ior (eq_attr "type" "alu")
9482 (and (eq_attr "type" "ishift")
9483 (and (match_operand 2 "const1_operand" "")
9484 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9487 (const_string "*")))
9488 (set_attr "mode" "HI,SI")])
9490 (define_insn "*ashlqi3_1"
9491 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9492 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9493 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9494 (clobber (reg:CC FLAGS_REG))]
9495 "TARGET_PARTIAL_REG_STALL
9496 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9498 switch (get_attr_type (insn))
9501 gcc_assert (operands[2] == const1_rtx);
9502 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9503 return "add{l}\t%k0, %k0";
9505 return "add{b}\t%0, %0";
9508 if (operands[2] == const1_rtx
9509 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9511 if (get_attr_mode (insn) == MODE_SI)
9512 return "sal{l}\t%k0";
9514 return "sal{b}\t%0";
9518 if (get_attr_mode (insn) == MODE_SI)
9519 return "sal{l}\t{%2, %k0|%k0, %2}";
9521 return "sal{b}\t{%2, %0|%0, %2}";
9526 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9528 (match_operand 0 "register_operand" ""))
9529 (match_operand 2 "const1_operand" ""))
9530 (const_string "alu")
9532 (const_string "ishift")))
9533 (set (attr "length_immediate")
9535 (ior (eq_attr "type" "alu")
9536 (and (eq_attr "type" "ishift")
9537 (and (match_operand 2 "const1_operand" "")
9538 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9541 (const_string "*")))
9542 (set_attr "mode" "QI,SI")])
9544 ;; %%% Potential partial reg stall on alternative 2. What to do?
9545 (define_insn "*ashlqi3_1_lea"
9546 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9547 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9548 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9549 (clobber (reg:CC FLAGS_REG))]
9550 "!TARGET_PARTIAL_REG_STALL
9551 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9553 switch (get_attr_type (insn))
9559 gcc_assert (operands[2] == const1_rtx);
9560 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9561 return "add{l}\t%k0, %k0";
9563 return "add{b}\t%0, %0";
9566 if (operands[2] == const1_rtx
9567 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9569 if (get_attr_mode (insn) == MODE_SI)
9570 return "sal{l}\t%k0";
9572 return "sal{b}\t%0";
9576 if (get_attr_mode (insn) == MODE_SI)
9577 return "sal{l}\t{%2, %k0|%k0, %2}";
9579 return "sal{b}\t{%2, %0|%0, %2}";
9584 (cond [(eq_attr "alternative" "2")
9585 (const_string "lea")
9586 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9588 (match_operand 0 "register_operand" ""))
9589 (match_operand 2 "const1_operand" ""))
9590 (const_string "alu")
9592 (const_string "ishift")))
9593 (set (attr "length_immediate")
9595 (ior (eq_attr "type" "alu")
9596 (and (eq_attr "type" "ishift")
9597 (and (match_operand 2 "const1_operand" "")
9598 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9601 (const_string "*")))
9602 (set_attr "mode" "QI,SI,SI")])
9604 (define_insn "*ashlqi3_1_slp"
9605 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9606 (ashift:QI (match_dup 0)
9607 (match_operand:QI 1 "nonmemory_operand" "cI")))
9608 (clobber (reg:CC FLAGS_REG))]
9609 "(optimize_function_for_size_p (cfun)
9610 || !TARGET_PARTIAL_FLAG_REG_STALL
9611 || (operands[1] == const1_rtx
9613 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9615 switch (get_attr_type (insn))
9618 gcc_assert (operands[1] == const1_rtx);
9619 return "add{b}\t%0, %0";
9622 if (operands[1] == const1_rtx
9623 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9624 return "sal{b}\t%0";
9626 return "sal{b}\t{%1, %0|%0, %1}";
9630 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9632 (match_operand 0 "register_operand" ""))
9633 (match_operand 1 "const1_operand" ""))
9634 (const_string "alu")
9636 (const_string "ishift1")))
9637 (set (attr "length_immediate")
9639 (ior (eq_attr "type" "alu")
9640 (and (eq_attr "type" "ishift1")
9641 (and (match_operand 1 "const1_operand" "")
9642 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9645 (const_string "*")))
9646 (set_attr "mode" "QI")])
9648 ;; Convert lea to the lea pattern to avoid flags dependency.
9650 [(set (match_operand 0 "register_operand" "")
9651 (ashift (match_operand 1 "index_register_operand" "")
9652 (match_operand:QI 2 "const_int_operand" "")))
9653 (clobber (reg:CC FLAGS_REG))]
9655 && true_regnum (operands[0]) != true_regnum (operands[1])"
9659 enum machine_mode mode = GET_MODE (operands[0]);
9662 operands[1] = gen_lowpart (Pmode, operands[1]);
9663 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9665 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9667 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9668 operands[0] = gen_lowpart (SImode, operands[0]);
9670 if (TARGET_64BIT && mode != Pmode)
9671 pat = gen_rtx_SUBREG (SImode, pat, 0);
9673 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9677 ;; Convert lea to the lea pattern to avoid flags dependency.
9679 [(set (match_operand:DI 0 "register_operand" "")
9681 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9682 (match_operand:QI 2 "const_int_operand" ""))))
9683 (clobber (reg:CC FLAGS_REG))]
9684 "TARGET_64BIT && reload_completed
9685 && true_regnum (operands[0]) != true_regnum (operands[1])"
9687 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9689 operands[1] = gen_lowpart (DImode, operands[1]);
9690 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9693 ;; This pattern can't accept a variable shift count, since shifts by
9694 ;; zero don't affect the flags. We assume that shifts by constant
9695 ;; zero are optimized away.
9696 (define_insn "*ashl<mode>3_cmp"
9697 [(set (reg FLAGS_REG)
9699 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9700 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9702 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9703 (ashift:SWI (match_dup 1) (match_dup 2)))]
9704 "(optimize_function_for_size_p (cfun)
9705 || !TARGET_PARTIAL_FLAG_REG_STALL
9706 || (operands[2] == const1_rtx
9708 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9709 && ix86_match_ccmode (insn, CCGOCmode)
9710 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9712 switch (get_attr_type (insn))
9715 gcc_assert (operands[2] == const1_rtx);
9716 return "add{<imodesuffix>}\t%0, %0";
9719 if (operands[2] == const1_rtx
9720 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9721 return "sal{<imodesuffix>}\t%0";
9723 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9727 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9729 (match_operand 0 "register_operand" ""))
9730 (match_operand 2 "const1_operand" ""))
9731 (const_string "alu")
9733 (const_string "ishift")))
9734 (set (attr "length_immediate")
9736 (ior (eq_attr "type" "alu")
9737 (and (eq_attr "type" "ishift")
9738 (and (match_operand 2 "const1_operand" "")
9739 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9742 (const_string "*")))
9743 (set_attr "mode" "<MODE>")])
9745 (define_insn "*ashlsi3_cmp_zext"
9746 [(set (reg FLAGS_REG)
9748 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9749 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9751 (set (match_operand:DI 0 "register_operand" "=r")
9752 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9754 && (optimize_function_for_size_p (cfun)
9755 || !TARGET_PARTIAL_FLAG_REG_STALL
9756 || (operands[2] == const1_rtx
9758 || TARGET_DOUBLE_WITH_ADD)))
9759 && ix86_match_ccmode (insn, CCGOCmode)
9760 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9762 switch (get_attr_type (insn))
9765 gcc_assert (operands[2] == const1_rtx);
9766 return "add{l}\t%k0, %k0";
9769 if (operands[2] == const1_rtx
9770 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9771 return "sal{l}\t%k0";
9773 return "sal{l}\t{%2, %k0|%k0, %2}";
9777 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9779 (match_operand 2 "const1_operand" ""))
9780 (const_string "alu")
9782 (const_string "ishift")))
9783 (set (attr "length_immediate")
9785 (ior (eq_attr "type" "alu")
9786 (and (eq_attr "type" "ishift")
9787 (and (match_operand 2 "const1_operand" "")
9788 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9791 (const_string "*")))
9792 (set_attr "mode" "SI")])
9794 (define_insn "*ashl<mode>3_cconly"
9795 [(set (reg FLAGS_REG)
9797 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9798 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9800 (clobber (match_scratch:SWI 0 "=<r>"))]
9801 "(optimize_function_for_size_p (cfun)
9802 || !TARGET_PARTIAL_FLAG_REG_STALL
9803 || (operands[2] == const1_rtx
9805 || TARGET_DOUBLE_WITH_ADD)))
9806 && ix86_match_ccmode (insn, CCGOCmode)"
9808 switch (get_attr_type (insn))
9811 gcc_assert (operands[2] == const1_rtx);
9812 return "add{<imodesuffix>}\t%0, %0";
9815 if (operands[2] == const1_rtx
9816 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9817 return "sal{<imodesuffix>}\t%0";
9819 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9823 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9825 (match_operand 0 "register_operand" ""))
9826 (match_operand 2 "const1_operand" ""))
9827 (const_string "alu")
9829 (const_string "ishift")))
9830 (set (attr "length_immediate")
9832 (ior (eq_attr "type" "alu")
9833 (and (eq_attr "type" "ishift")
9834 (and (match_operand 2 "const1_operand" "")
9835 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9838 (const_string "*")))
9839 (set_attr "mode" "<MODE>")])
9841 ;; See comment above `ashl<mode>3' about how this works.
9843 (define_expand "<shiftrt_insn><mode>3"
9844 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9845 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9846 (match_operand:QI 2 "nonmemory_operand" "")))]
9848 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9850 ;; Avoid useless masking of count operand.
9851 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9852 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9854 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9857 (match_operand:SI 2 "nonimmediate_operand" "c")
9858 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9859 (clobber (reg:CC FLAGS_REG))]
9860 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9861 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9862 == GET_MODE_BITSIZE (<MODE>mode)-1"
9865 [(parallel [(set (match_dup 0)
9866 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9867 (clobber (reg:CC FLAGS_REG))])]
9869 if (can_create_pseudo_p ())
9870 operands [2] = force_reg (SImode, operands[2]);
9872 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9874 [(set_attr "type" "ishift")
9875 (set_attr "mode" "<MODE>")])
9877 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9878 [(set (match_operand:DWI 0 "register_operand" "=r")
9879 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9880 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9881 (clobber (reg:CC FLAGS_REG))]
9884 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9886 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9887 [(set_attr "type" "multi")])
9889 ;; By default we don't ask for a scratch register, because when DWImode
9890 ;; values are manipulated, registers are already at a premium. But if
9891 ;; we have one handy, we won't turn it away.
9894 [(match_scratch:DWIH 3 "r")
9895 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9897 (match_operand:<DWI> 1 "register_operand" "")
9898 (match_operand:QI 2 "nonmemory_operand" "")))
9899 (clobber (reg:CC FLAGS_REG))])
9903 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9905 (define_insn "x86_64_shrd"
9906 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9907 (ior:DI (ashiftrt:DI (match_dup 0)
9908 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9909 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9910 (minus:QI (const_int 64) (match_dup 2)))))
9911 (clobber (reg:CC FLAGS_REG))]
9913 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9914 [(set_attr "type" "ishift")
9915 (set_attr "prefix_0f" "1")
9916 (set_attr "mode" "DI")
9917 (set_attr "athlon_decode" "vector")
9918 (set_attr "amdfam10_decode" "vector")
9919 (set_attr "bdver1_decode" "vector")])
9921 (define_insn "x86_shrd"
9922 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9923 (ior:SI (ashiftrt:SI (match_dup 0)
9924 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9925 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9926 (minus:QI (const_int 32) (match_dup 2)))))
9927 (clobber (reg:CC FLAGS_REG))]
9929 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9930 [(set_attr "type" "ishift")
9931 (set_attr "prefix_0f" "1")
9932 (set_attr "mode" "SI")
9933 (set_attr "pent_pair" "np")
9934 (set_attr "athlon_decode" "vector")
9935 (set_attr "amdfam10_decode" "vector")
9936 (set_attr "bdver1_decode" "vector")])
9938 (define_insn "ashrdi3_cvt"
9939 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9940 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9941 (match_operand:QI 2 "const_int_operand" "")))
9942 (clobber (reg:CC FLAGS_REG))]
9943 "TARGET_64BIT && INTVAL (operands[2]) == 63
9944 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9945 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9948 sar{q}\t{%2, %0|%0, %2}"
9949 [(set_attr "type" "imovx,ishift")
9950 (set_attr "prefix_0f" "0,*")
9951 (set_attr "length_immediate" "0,*")
9952 (set_attr "modrm" "0,1")
9953 (set_attr "mode" "DI")])
9955 (define_insn "ashrsi3_cvt"
9956 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9957 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9958 (match_operand:QI 2 "const_int_operand" "")))
9959 (clobber (reg:CC FLAGS_REG))]
9960 "INTVAL (operands[2]) == 31
9961 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9962 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9965 sar{l}\t{%2, %0|%0, %2}"
9966 [(set_attr "type" "imovx,ishift")
9967 (set_attr "prefix_0f" "0,*")
9968 (set_attr "length_immediate" "0,*")
9969 (set_attr "modrm" "0,1")
9970 (set_attr "mode" "SI")])
9972 (define_insn "*ashrsi3_cvt_zext"
9973 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9975 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9976 (match_operand:QI 2 "const_int_operand" ""))))
9977 (clobber (reg:CC FLAGS_REG))]
9978 "TARGET_64BIT && INTVAL (operands[2]) == 31
9979 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9980 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9983 sar{l}\t{%2, %k0|%k0, %2}"
9984 [(set_attr "type" "imovx,ishift")
9985 (set_attr "prefix_0f" "0,*")
9986 (set_attr "length_immediate" "0,*")
9987 (set_attr "modrm" "0,1")
9988 (set_attr "mode" "SI")])
9990 (define_expand "x86_shift<mode>_adj_3"
9991 [(use (match_operand:SWI48 0 "register_operand" ""))
9992 (use (match_operand:SWI48 1 "register_operand" ""))
9993 (use (match_operand:QI 2 "register_operand" ""))]
9996 rtx label = gen_label_rtx ();
9999 emit_insn (gen_testqi_ccz_1 (operands[2],
10000 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10002 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10003 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10004 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10005 gen_rtx_LABEL_REF (VOIDmode, label),
10007 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10008 JUMP_LABEL (tmp) = label;
10010 emit_move_insn (operands[0], operands[1]);
10011 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10012 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10013 emit_label (label);
10014 LABEL_NUSES (label) = 1;
10019 (define_insn "*<shiftrt_insn><mode>3_1"
10020 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10021 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10022 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10023 (clobber (reg:CC FLAGS_REG))]
10024 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10026 if (operands[2] == const1_rtx
10027 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10028 return "<shiftrt>{<imodesuffix>}\t%0";
10030 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10032 [(set_attr "type" "ishift")
10033 (set (attr "length_immediate")
10035 (and (match_operand 2 "const1_operand" "")
10036 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10039 (const_string "*")))
10040 (set_attr "mode" "<MODE>")])
10042 (define_insn "*<shiftrt_insn>si3_1_zext"
10043 [(set (match_operand:DI 0 "register_operand" "=r")
10045 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10046 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10047 (clobber (reg:CC FLAGS_REG))]
10048 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10050 if (operands[2] == const1_rtx
10051 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10052 return "<shiftrt>{l}\t%k0";
10054 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10056 [(set_attr "type" "ishift")
10057 (set (attr "length_immediate")
10059 (and (match_operand 2 "const1_operand" "")
10060 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10063 (const_string "*")))
10064 (set_attr "mode" "SI")])
10066 (define_insn "*<shiftrt_insn>qi3_1_slp"
10067 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10068 (any_shiftrt:QI (match_dup 0)
10069 (match_operand:QI 1 "nonmemory_operand" "cI")))
10070 (clobber (reg:CC FLAGS_REG))]
10071 "(optimize_function_for_size_p (cfun)
10072 || !TARGET_PARTIAL_REG_STALL
10073 || (operands[1] == const1_rtx
10074 && TARGET_SHIFT1))"
10076 if (operands[1] == const1_rtx
10077 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10078 return "<shiftrt>{b}\t%0";
10080 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10082 [(set_attr "type" "ishift1")
10083 (set (attr "length_immediate")
10085 (and (match_operand 1 "const1_operand" "")
10086 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10089 (const_string "*")))
10090 (set_attr "mode" "QI")])
10092 ;; This pattern can't accept a variable shift count, since shifts by
10093 ;; zero don't affect the flags. We assume that shifts by constant
10094 ;; zero are optimized away.
10095 (define_insn "*<shiftrt_insn><mode>3_cmp"
10096 [(set (reg FLAGS_REG)
10099 (match_operand:SWI 1 "nonimmediate_operand" "0")
10100 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10102 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10103 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10104 "(optimize_function_for_size_p (cfun)
10105 || !TARGET_PARTIAL_FLAG_REG_STALL
10106 || (operands[2] == const1_rtx
10108 && ix86_match_ccmode (insn, CCGOCmode)
10109 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10111 if (operands[2] == const1_rtx
10112 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10113 return "<shiftrt>{<imodesuffix>}\t%0";
10115 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10117 [(set_attr "type" "ishift")
10118 (set (attr "length_immediate")
10120 (and (match_operand 2 "const1_operand" "")
10121 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10124 (const_string "*")))
10125 (set_attr "mode" "<MODE>")])
10127 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10128 [(set (reg FLAGS_REG)
10130 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10131 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10133 (set (match_operand:DI 0 "register_operand" "=r")
10134 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10136 && (optimize_function_for_size_p (cfun)
10137 || !TARGET_PARTIAL_FLAG_REG_STALL
10138 || (operands[2] == const1_rtx
10140 && ix86_match_ccmode (insn, CCGOCmode)
10141 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10143 if (operands[2] == const1_rtx
10144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10145 return "<shiftrt>{l}\t%k0";
10147 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10149 [(set_attr "type" "ishift")
10150 (set (attr "length_immediate")
10152 (and (match_operand 2 "const1_operand" "")
10153 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10156 (const_string "*")))
10157 (set_attr "mode" "SI")])
10159 (define_insn "*<shiftrt_insn><mode>3_cconly"
10160 [(set (reg FLAGS_REG)
10163 (match_operand:SWI 1 "register_operand" "0")
10164 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10166 (clobber (match_scratch:SWI 0 "=<r>"))]
10167 "(optimize_function_for_size_p (cfun)
10168 || !TARGET_PARTIAL_FLAG_REG_STALL
10169 || (operands[2] == const1_rtx
10171 && ix86_match_ccmode (insn, CCGOCmode)"
10173 if (operands[2] == const1_rtx
10174 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10175 return "<shiftrt>{<imodesuffix>}\t%0";
10177 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10179 [(set_attr "type" "ishift")
10180 (set (attr "length_immediate")
10182 (and (match_operand 2 "const1_operand" "")
10183 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10186 (const_string "*")))
10187 (set_attr "mode" "<MODE>")])
10189 ;; Rotate instructions
10191 (define_expand "<rotate_insn>ti3"
10192 [(set (match_operand:TI 0 "register_operand" "")
10193 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10194 (match_operand:QI 2 "nonmemory_operand" "")))]
10197 if (const_1_to_63_operand (operands[2], VOIDmode))
10198 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10199 (operands[0], operands[1], operands[2]));
10206 (define_expand "<rotate_insn>di3"
10207 [(set (match_operand:DI 0 "shiftdi_operand" "")
10208 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10209 (match_operand:QI 2 "nonmemory_operand" "")))]
10213 ix86_expand_binary_operator (<CODE>, DImode, operands);
10214 else if (const_1_to_31_operand (operands[2], VOIDmode))
10215 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10216 (operands[0], operands[1], operands[2]));
10223 (define_expand "<rotate_insn><mode>3"
10224 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10225 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10226 (match_operand:QI 2 "nonmemory_operand" "")))]
10228 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10230 ;; Avoid useless masking of count operand.
10231 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10232 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10234 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10237 (match_operand:SI 2 "nonimmediate_operand" "c")
10238 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10239 (clobber (reg:CC FLAGS_REG))]
10240 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10241 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10242 == GET_MODE_BITSIZE (<MODE>mode)-1"
10245 [(parallel [(set (match_dup 0)
10246 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10247 (clobber (reg:CC FLAGS_REG))])]
10249 if (can_create_pseudo_p ())
10250 operands [2] = force_reg (SImode, operands[2]);
10252 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10254 [(set_attr "type" "rotate")
10255 (set_attr "mode" "<MODE>")])
10257 ;; Implement rotation using two double-precision
10258 ;; shift instructions and a scratch register.
10260 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10261 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10262 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10263 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10264 (clobber (reg:CC FLAGS_REG))
10265 (clobber (match_scratch:DWIH 3 "=&r"))]
10269 [(set (match_dup 3) (match_dup 4))
10271 [(set (match_dup 4)
10272 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10273 (lshiftrt:DWIH (match_dup 5)
10274 (minus:QI (match_dup 6) (match_dup 2)))))
10275 (clobber (reg:CC FLAGS_REG))])
10277 [(set (match_dup 5)
10278 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10279 (lshiftrt:DWIH (match_dup 3)
10280 (minus:QI (match_dup 6) (match_dup 2)))))
10281 (clobber (reg:CC FLAGS_REG))])]
10283 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10285 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10288 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10289 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10290 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10291 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10292 (clobber (reg:CC FLAGS_REG))
10293 (clobber (match_scratch:DWIH 3 "=&r"))]
10297 [(set (match_dup 3) (match_dup 4))
10299 [(set (match_dup 4)
10300 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10301 (ashift:DWIH (match_dup 5)
10302 (minus:QI (match_dup 6) (match_dup 2)))))
10303 (clobber (reg:CC FLAGS_REG))])
10305 [(set (match_dup 5)
10306 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10307 (ashift:DWIH (match_dup 3)
10308 (minus:QI (match_dup 6) (match_dup 2)))))
10309 (clobber (reg:CC FLAGS_REG))])]
10311 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10313 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10316 (define_insn "*<rotate_insn><mode>3_1"
10317 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10318 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10319 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10320 (clobber (reg:CC FLAGS_REG))]
10321 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10323 if (operands[2] == const1_rtx
10324 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10325 return "<rotate>{<imodesuffix>}\t%0";
10327 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10329 [(set_attr "type" "rotate")
10330 (set (attr "length_immediate")
10332 (and (match_operand 2 "const1_operand" "")
10333 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10336 (const_string "*")))
10337 (set_attr "mode" "<MODE>")])
10339 (define_insn "*<rotate_insn>si3_1_zext"
10340 [(set (match_operand:DI 0 "register_operand" "=r")
10342 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10343 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10344 (clobber (reg:CC FLAGS_REG))]
10345 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10347 if (operands[2] == const1_rtx
10348 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10349 return "<rotate>{l}\t%k0";
10351 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10353 [(set_attr "type" "rotate")
10354 (set (attr "length_immediate")
10356 (and (match_operand 2 "const1_operand" "")
10357 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10360 (const_string "*")))
10361 (set_attr "mode" "SI")])
10363 (define_insn "*<rotate_insn>qi3_1_slp"
10364 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10365 (any_rotate:QI (match_dup 0)
10366 (match_operand:QI 1 "nonmemory_operand" "cI")))
10367 (clobber (reg:CC FLAGS_REG))]
10368 "(optimize_function_for_size_p (cfun)
10369 || !TARGET_PARTIAL_REG_STALL
10370 || (operands[1] == const1_rtx
10371 && TARGET_SHIFT1))"
10373 if (operands[1] == const1_rtx
10374 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10375 return "<rotate>{b}\t%0";
10377 return "<rotate>{b}\t{%1, %0|%0, %1}";
10379 [(set_attr "type" "rotate1")
10380 (set (attr "length_immediate")
10382 (and (match_operand 1 "const1_operand" "")
10383 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10386 (const_string "*")))
10387 (set_attr "mode" "QI")])
10390 [(set (match_operand:HI 0 "register_operand" "")
10391 (any_rotate:HI (match_dup 0) (const_int 8)))
10392 (clobber (reg:CC FLAGS_REG))]
10394 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10395 [(parallel [(set (strict_low_part (match_dup 0))
10396 (bswap:HI (match_dup 0)))
10397 (clobber (reg:CC FLAGS_REG))])])
10399 ;; Bit set / bit test instructions
10401 (define_expand "extv"
10402 [(set (match_operand:SI 0 "register_operand" "")
10403 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10404 (match_operand:SI 2 "const8_operand" "")
10405 (match_operand:SI 3 "const8_operand" "")))]
10408 /* Handle extractions from %ah et al. */
10409 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10412 /* From mips.md: extract_bit_field doesn't verify that our source
10413 matches the predicate, so check it again here. */
10414 if (! ext_register_operand (operands[1], VOIDmode))
10418 (define_expand "extzv"
10419 [(set (match_operand:SI 0 "register_operand" "")
10420 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10421 (match_operand:SI 2 "const8_operand" "")
10422 (match_operand:SI 3 "const8_operand" "")))]
10425 /* Handle extractions from %ah et al. */
10426 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10429 /* From mips.md: extract_bit_field doesn't verify that our source
10430 matches the predicate, so check it again here. */
10431 if (! ext_register_operand (operands[1], VOIDmode))
10435 (define_expand "insv"
10436 [(set (zero_extract (match_operand 0 "register_operand" "")
10437 (match_operand 1 "const_int_operand" "")
10438 (match_operand 2 "const_int_operand" ""))
10439 (match_operand 3 "register_operand" ""))]
10442 rtx (*gen_mov_insv_1) (rtx, rtx);
10444 if (ix86_expand_pinsr (operands))
10447 /* Handle insertions to %ah et al. */
10448 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10451 /* From mips.md: insert_bit_field doesn't verify that our source
10452 matches the predicate, so check it again here. */
10453 if (! ext_register_operand (operands[0], VOIDmode))
10456 gen_mov_insv_1 = (TARGET_64BIT
10457 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10459 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10463 ;; %%% bts, btr, btc, bt.
10464 ;; In general these instructions are *slow* when applied to memory,
10465 ;; since they enforce atomic operation. When applied to registers,
10466 ;; it depends on the cpu implementation. They're never faster than
10467 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10468 ;; no point. But in 64-bit, we can't hold the relevant immediates
10469 ;; within the instruction itself, so operating on bits in the high
10470 ;; 32-bits of a register becomes easier.
10472 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10473 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10474 ;; negdf respectively, so they can never be disabled entirely.
10476 (define_insn "*btsq"
10477 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10479 (match_operand:DI 1 "const_0_to_63_operand" ""))
10481 (clobber (reg:CC FLAGS_REG))]
10482 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10483 "bts{q}\t{%1, %0|%0, %1}"
10484 [(set_attr "type" "alu1")
10485 (set_attr "prefix_0f" "1")
10486 (set_attr "mode" "DI")])
10488 (define_insn "*btrq"
10489 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10491 (match_operand:DI 1 "const_0_to_63_operand" ""))
10493 (clobber (reg:CC FLAGS_REG))]
10494 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10495 "btr{q}\t{%1, %0|%0, %1}"
10496 [(set_attr "type" "alu1")
10497 (set_attr "prefix_0f" "1")
10498 (set_attr "mode" "DI")])
10500 (define_insn "*btcq"
10501 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10503 (match_operand:DI 1 "const_0_to_63_operand" ""))
10504 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10505 (clobber (reg:CC FLAGS_REG))]
10506 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10507 "btc{q}\t{%1, %0|%0, %1}"
10508 [(set_attr "type" "alu1")
10509 (set_attr "prefix_0f" "1")
10510 (set_attr "mode" "DI")])
10512 ;; Allow Nocona to avoid these instructions if a register is available.
10515 [(match_scratch:DI 2 "r")
10516 (parallel [(set (zero_extract:DI
10517 (match_operand:DI 0 "register_operand" "")
10519 (match_operand:DI 1 "const_0_to_63_operand" ""))
10521 (clobber (reg:CC FLAGS_REG))])]
10522 "TARGET_64BIT && !TARGET_USE_BT"
10525 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10528 if (HOST_BITS_PER_WIDE_INT >= 64)
10529 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10530 else if (i < HOST_BITS_PER_WIDE_INT)
10531 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10533 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10535 op1 = immed_double_const (lo, hi, DImode);
10538 emit_move_insn (operands[2], op1);
10542 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10547 [(match_scratch:DI 2 "r")
10548 (parallel [(set (zero_extract:DI
10549 (match_operand:DI 0 "register_operand" "")
10551 (match_operand:DI 1 "const_0_to_63_operand" ""))
10553 (clobber (reg:CC FLAGS_REG))])]
10554 "TARGET_64BIT && !TARGET_USE_BT"
10557 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10560 if (HOST_BITS_PER_WIDE_INT >= 64)
10561 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10562 else if (i < HOST_BITS_PER_WIDE_INT)
10563 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10565 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10567 op1 = immed_double_const (~lo, ~hi, DImode);
10570 emit_move_insn (operands[2], op1);
10574 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10579 [(match_scratch:DI 2 "r")
10580 (parallel [(set (zero_extract:DI
10581 (match_operand:DI 0 "register_operand" "")
10583 (match_operand:DI 1 "const_0_to_63_operand" ""))
10584 (not:DI (zero_extract:DI
10585 (match_dup 0) (const_int 1) (match_dup 1))))
10586 (clobber (reg:CC FLAGS_REG))])]
10587 "TARGET_64BIT && !TARGET_USE_BT"
10590 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10593 if (HOST_BITS_PER_WIDE_INT >= 64)
10594 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10595 else if (i < HOST_BITS_PER_WIDE_INT)
10596 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10598 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10600 op1 = immed_double_const (lo, hi, DImode);
10603 emit_move_insn (operands[2], op1);
10607 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10611 (define_insn "*bt<mode>"
10612 [(set (reg:CCC FLAGS_REG)
10614 (zero_extract:SWI48
10615 (match_operand:SWI48 0 "register_operand" "r")
10617 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10619 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10620 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10621 [(set_attr "type" "alu1")
10622 (set_attr "prefix_0f" "1")
10623 (set_attr "mode" "<MODE>")])
10625 ;; Store-flag instructions.
10627 ;; For all sCOND expanders, also expand the compare or test insn that
10628 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10630 (define_insn_and_split "*setcc_di_1"
10631 [(set (match_operand:DI 0 "register_operand" "=q")
10632 (match_operator:DI 1 "ix86_comparison_operator"
10633 [(reg FLAGS_REG) (const_int 0)]))]
10634 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10636 "&& reload_completed"
10637 [(set (match_dup 2) (match_dup 1))
10638 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10640 PUT_MODE (operands[1], QImode);
10641 operands[2] = gen_lowpart (QImode, operands[0]);
10644 (define_insn_and_split "*setcc_si_1_and"
10645 [(set (match_operand:SI 0 "register_operand" "=q")
10646 (match_operator:SI 1 "ix86_comparison_operator"
10647 [(reg FLAGS_REG) (const_int 0)]))
10648 (clobber (reg:CC FLAGS_REG))]
10649 "!TARGET_PARTIAL_REG_STALL
10650 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10652 "&& reload_completed"
10653 [(set (match_dup 2) (match_dup 1))
10654 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10655 (clobber (reg:CC FLAGS_REG))])]
10657 PUT_MODE (operands[1], QImode);
10658 operands[2] = gen_lowpart (QImode, operands[0]);
10661 (define_insn_and_split "*setcc_si_1_movzbl"
10662 [(set (match_operand:SI 0 "register_operand" "=q")
10663 (match_operator:SI 1 "ix86_comparison_operator"
10664 [(reg FLAGS_REG) (const_int 0)]))]
10665 "!TARGET_PARTIAL_REG_STALL
10666 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10668 "&& reload_completed"
10669 [(set (match_dup 2) (match_dup 1))
10670 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10672 PUT_MODE (operands[1], QImode);
10673 operands[2] = gen_lowpart (QImode, operands[0]);
10676 (define_insn "*setcc_qi"
10677 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10678 (match_operator:QI 1 "ix86_comparison_operator"
10679 [(reg FLAGS_REG) (const_int 0)]))]
10682 [(set_attr "type" "setcc")
10683 (set_attr "mode" "QI")])
10685 (define_insn "*setcc_qi_slp"
10686 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10687 (match_operator:QI 1 "ix86_comparison_operator"
10688 [(reg FLAGS_REG) (const_int 0)]))]
10691 [(set_attr "type" "setcc")
10692 (set_attr "mode" "QI")])
10694 ;; In general it is not safe to assume too much about CCmode registers,
10695 ;; so simplify-rtx stops when it sees a second one. Under certain
10696 ;; conditions this is safe on x86, so help combine not create
10703 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10704 (ne:QI (match_operator 1 "ix86_comparison_operator"
10705 [(reg FLAGS_REG) (const_int 0)])
10708 [(set (match_dup 0) (match_dup 1))]
10709 "PUT_MODE (operands[1], QImode);")
10712 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10713 (ne:QI (match_operator 1 "ix86_comparison_operator"
10714 [(reg FLAGS_REG) (const_int 0)])
10717 [(set (match_dup 0) (match_dup 1))]
10718 "PUT_MODE (operands[1], QImode);")
10721 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10722 (eq:QI (match_operator 1 "ix86_comparison_operator"
10723 [(reg FLAGS_REG) (const_int 0)])
10726 [(set (match_dup 0) (match_dup 1))]
10728 rtx new_op1 = copy_rtx (operands[1]);
10729 operands[1] = new_op1;
10730 PUT_MODE (new_op1, QImode);
10731 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10732 GET_MODE (XEXP (new_op1, 0))));
10734 /* Make sure that (a) the CCmode we have for the flags is strong
10735 enough for the reversed compare or (b) we have a valid FP compare. */
10736 if (! ix86_comparison_operator (new_op1, VOIDmode))
10741 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10742 (eq:QI (match_operator 1 "ix86_comparison_operator"
10743 [(reg FLAGS_REG) (const_int 0)])
10746 [(set (match_dup 0) (match_dup 1))]
10748 rtx new_op1 = copy_rtx (operands[1]);
10749 operands[1] = new_op1;
10750 PUT_MODE (new_op1, QImode);
10751 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10752 GET_MODE (XEXP (new_op1, 0))));
10754 /* Make sure that (a) the CCmode we have for the flags is strong
10755 enough for the reversed compare or (b) we have a valid FP compare. */
10756 if (! ix86_comparison_operator (new_op1, VOIDmode))
10760 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10761 ;; subsequent logical operations are used to imitate conditional moves.
10762 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10765 (define_insn "setcc_<mode>_sse"
10766 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10767 (match_operator:MODEF 3 "sse_comparison_operator"
10768 [(match_operand:MODEF 1 "register_operand" "0,x")
10769 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10770 "SSE_FLOAT_MODE_P (<MODE>mode)"
10772 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10773 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10774 [(set_attr "isa" "noavx,avx")
10775 (set_attr "type" "ssecmp")
10776 (set_attr "length_immediate" "1")
10777 (set_attr "prefix" "orig,vex")
10778 (set_attr "mode" "<MODE>")])
10780 ;; Basic conditional jump instructions.
10781 ;; We ignore the overflow flag for signed branch instructions.
10783 (define_insn "*jcc_1"
10785 (if_then_else (match_operator 1 "ix86_comparison_operator"
10786 [(reg FLAGS_REG) (const_int 0)])
10787 (label_ref (match_operand 0 "" ""))
10791 [(set_attr "type" "ibr")
10792 (set_attr "modrm" "0")
10793 (set (attr "length")
10794 (if_then_else (and (ge (minus (match_dup 0) (pc))
10796 (lt (minus (match_dup 0) (pc))
10801 (define_insn "*jcc_2"
10803 (if_then_else (match_operator 1 "ix86_comparison_operator"
10804 [(reg FLAGS_REG) (const_int 0)])
10806 (label_ref (match_operand 0 "" ""))))]
10809 [(set_attr "type" "ibr")
10810 (set_attr "modrm" "0")
10811 (set (attr "length")
10812 (if_then_else (and (ge (minus (match_dup 0) (pc))
10814 (lt (minus (match_dup 0) (pc))
10819 ;; In general it is not safe to assume too much about CCmode registers,
10820 ;; so simplify-rtx stops when it sees a second one. Under certain
10821 ;; conditions this is safe on x86, so help combine not create
10829 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10830 [(reg FLAGS_REG) (const_int 0)])
10832 (label_ref (match_operand 1 "" ""))
10836 (if_then_else (match_dup 0)
10837 (label_ref (match_dup 1))
10839 "PUT_MODE (operands[0], VOIDmode);")
10843 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10844 [(reg FLAGS_REG) (const_int 0)])
10846 (label_ref (match_operand 1 "" ""))
10850 (if_then_else (match_dup 0)
10851 (label_ref (match_dup 1))
10854 rtx new_op0 = copy_rtx (operands[0]);
10855 operands[0] = new_op0;
10856 PUT_MODE (new_op0, VOIDmode);
10857 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10858 GET_MODE (XEXP (new_op0, 0))));
10860 /* Make sure that (a) the CCmode we have for the flags is strong
10861 enough for the reversed compare or (b) we have a valid FP compare. */
10862 if (! ix86_comparison_operator (new_op0, VOIDmode))
10866 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10867 ;; pass generates from shift insn with QImode operand. Actually, the mode
10868 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10869 ;; appropriate modulo of the bit offset value.
10871 (define_insn_and_split "*jcc_bt<mode>"
10873 (if_then_else (match_operator 0 "bt_comparison_operator"
10874 [(zero_extract:SWI48
10875 (match_operand:SWI48 1 "register_operand" "r")
10878 (match_operand:QI 2 "register_operand" "r")))
10880 (label_ref (match_operand 3 "" ""))
10882 (clobber (reg:CC FLAGS_REG))]
10883 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10886 [(set (reg:CCC FLAGS_REG)
10888 (zero_extract:SWI48
10894 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10895 (label_ref (match_dup 3))
10898 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10900 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10903 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10904 ;; also for DImode, this is what combine produces.
10905 (define_insn_and_split "*jcc_bt<mode>_mask"
10907 (if_then_else (match_operator 0 "bt_comparison_operator"
10908 [(zero_extract:SWI48
10909 (match_operand:SWI48 1 "register_operand" "r")
10912 (match_operand:SI 2 "register_operand" "r")
10913 (match_operand:SI 3 "const_int_operand" "n")))])
10914 (label_ref (match_operand 4 "" ""))
10916 (clobber (reg:CC FLAGS_REG))]
10917 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10918 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10919 == GET_MODE_BITSIZE (<MODE>mode)-1"
10922 [(set (reg:CCC FLAGS_REG)
10924 (zero_extract:SWI48
10930 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10931 (label_ref (match_dup 4))
10934 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10936 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10939 (define_insn_and_split "*jcc_btsi_1"
10941 (if_then_else (match_operator 0 "bt_comparison_operator"
10944 (match_operand:SI 1 "register_operand" "r")
10945 (match_operand:QI 2 "register_operand" "r"))
10948 (label_ref (match_operand 3 "" ""))
10950 (clobber (reg:CC FLAGS_REG))]
10951 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10954 [(set (reg:CCC FLAGS_REG)
10962 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10963 (label_ref (match_dup 3))
10966 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10968 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10971 ;; avoid useless masking of bit offset operand
10972 (define_insn_and_split "*jcc_btsi_mask_1"
10975 (match_operator 0 "bt_comparison_operator"
10978 (match_operand:SI 1 "register_operand" "r")
10981 (match_operand:SI 2 "register_operand" "r")
10982 (match_operand:SI 3 "const_int_operand" "n")) 0))
10985 (label_ref (match_operand 4 "" ""))
10987 (clobber (reg:CC FLAGS_REG))]
10988 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10989 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10992 [(set (reg:CCC FLAGS_REG)
11000 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11001 (label_ref (match_dup 4))
11003 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11005 ;; Define combination compare-and-branch fp compare instructions to help
11008 (define_insn "*fp_jcc_1_387"
11010 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11011 [(match_operand 1 "register_operand" "f")
11012 (match_operand 2 "nonimmediate_operand" "fm")])
11013 (label_ref (match_operand 3 "" ""))
11015 (clobber (reg:CCFP FPSR_REG))
11016 (clobber (reg:CCFP FLAGS_REG))
11017 (clobber (match_scratch:HI 4 "=a"))]
11019 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11020 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11021 && SELECT_CC_MODE (GET_CODE (operands[0]),
11022 operands[1], operands[2]) == CCFPmode
11026 (define_insn "*fp_jcc_1r_387"
11028 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11029 [(match_operand 1 "register_operand" "f")
11030 (match_operand 2 "nonimmediate_operand" "fm")])
11032 (label_ref (match_operand 3 "" ""))))
11033 (clobber (reg:CCFP FPSR_REG))
11034 (clobber (reg:CCFP FLAGS_REG))
11035 (clobber (match_scratch:HI 4 "=a"))]
11037 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11038 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11039 && SELECT_CC_MODE (GET_CODE (operands[0]),
11040 operands[1], operands[2]) == CCFPmode
11044 (define_insn "*fp_jcc_2_387"
11046 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11047 [(match_operand 1 "register_operand" "f")
11048 (match_operand 2 "register_operand" "f")])
11049 (label_ref (match_operand 3 "" ""))
11051 (clobber (reg:CCFP FPSR_REG))
11052 (clobber (reg:CCFP FLAGS_REG))
11053 (clobber (match_scratch:HI 4 "=a"))]
11054 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11055 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11059 (define_insn "*fp_jcc_2r_387"
11061 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11062 [(match_operand 1 "register_operand" "f")
11063 (match_operand 2 "register_operand" "f")])
11065 (label_ref (match_operand 3 "" ""))))
11066 (clobber (reg:CCFP FPSR_REG))
11067 (clobber (reg:CCFP FLAGS_REG))
11068 (clobber (match_scratch:HI 4 "=a"))]
11069 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11070 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11074 (define_insn "*fp_jcc_3_387"
11076 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11077 [(match_operand 1 "register_operand" "f")
11078 (match_operand 2 "const0_operand" "")])
11079 (label_ref (match_operand 3 "" ""))
11081 (clobber (reg:CCFP FPSR_REG))
11082 (clobber (reg:CCFP FLAGS_REG))
11083 (clobber (match_scratch:HI 4 "=a"))]
11084 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11085 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11086 && SELECT_CC_MODE (GET_CODE (operands[0]),
11087 operands[1], operands[2]) == CCFPmode
11093 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11094 [(match_operand 1 "register_operand" "")
11095 (match_operand 2 "nonimmediate_operand" "")])
11096 (match_operand 3 "" "")
11097 (match_operand 4 "" "")))
11098 (clobber (reg:CCFP FPSR_REG))
11099 (clobber (reg:CCFP FLAGS_REG))]
11103 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11104 operands[3], operands[4], NULL_RTX, NULL_RTX);
11110 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11111 [(match_operand 1 "register_operand" "")
11112 (match_operand 2 "general_operand" "")])
11113 (match_operand 3 "" "")
11114 (match_operand 4 "" "")))
11115 (clobber (reg:CCFP FPSR_REG))
11116 (clobber (reg:CCFP FLAGS_REG))
11117 (clobber (match_scratch:HI 5 "=a"))]
11121 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11122 operands[3], operands[4], operands[5], NULL_RTX);
11126 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11127 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11128 ;; with a precedence over other operators and is always put in the first
11129 ;; place. Swap condition and operands to match ficom instruction.
11131 (define_insn "*fp_jcc_4_<mode>_387"
11134 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11135 [(match_operator 1 "float_operator"
11136 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11137 (match_operand 3 "register_operand" "f,f")])
11138 (label_ref (match_operand 4 "" ""))
11140 (clobber (reg:CCFP FPSR_REG))
11141 (clobber (reg:CCFP FLAGS_REG))
11142 (clobber (match_scratch:HI 5 "=a,a"))]
11143 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11144 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11145 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11146 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11153 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11154 [(match_operator 1 "float_operator"
11155 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11156 (match_operand 3 "register_operand" "")])
11157 (match_operand 4 "" "")
11158 (match_operand 5 "" "")))
11159 (clobber (reg:CCFP FPSR_REG))
11160 (clobber (reg:CCFP FLAGS_REG))
11161 (clobber (match_scratch:HI 6 "=a"))]
11165 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11167 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11168 operands[3], operands[7],
11169 operands[4], operands[5], operands[6], NULL_RTX);
11173 ;; %%% Kill this when reload knows how to do it.
11177 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11178 [(match_operator 1 "float_operator"
11179 [(match_operand:X87MODEI12 2 "register_operand" "")])
11180 (match_operand 3 "register_operand" "")])
11181 (match_operand 4 "" "")
11182 (match_operand 5 "" "")))
11183 (clobber (reg:CCFP FPSR_REG))
11184 (clobber (reg:CCFP FLAGS_REG))
11185 (clobber (match_scratch:HI 6 "=a"))]
11189 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11190 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11192 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11193 operands[3], operands[7],
11194 operands[4], operands[5], operands[6], operands[2]);
11198 ;; Unconditional and other jump instructions
11200 (define_insn "jump"
11202 (label_ref (match_operand 0 "" "")))]
11205 [(set_attr "type" "ibr")
11206 (set (attr "length")
11207 (if_then_else (and (ge (minus (match_dup 0) (pc))
11209 (lt (minus (match_dup 0) (pc))
11213 (set_attr "modrm" "0")])
11215 (define_expand "indirect_jump"
11216 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11220 (define_insn "*indirect_jump"
11221 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11224 [(set_attr "type" "ibr")
11225 (set_attr "length_immediate" "0")])
11227 (define_expand "tablejump"
11228 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11229 (use (label_ref (match_operand 1 "" "")))])]
11232 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11233 relative. Convert the relative address to an absolute address. */
11237 enum rtx_code code;
11239 /* We can't use @GOTOFF for text labels on VxWorks;
11240 see gotoff_operand. */
11241 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11245 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11247 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11251 op1 = pic_offset_table_rtx;
11256 op0 = pic_offset_table_rtx;
11260 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11265 (define_insn "*tablejump_1"
11266 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11267 (use (label_ref (match_operand 1 "" "")))]
11270 [(set_attr "type" "ibr")
11271 (set_attr "length_immediate" "0")])
11273 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11276 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11277 (set (match_operand:QI 1 "register_operand" "")
11278 (match_operator:QI 2 "ix86_comparison_operator"
11279 [(reg FLAGS_REG) (const_int 0)]))
11280 (set (match_operand 3 "q_regs_operand" "")
11281 (zero_extend (match_dup 1)))]
11282 "(peep2_reg_dead_p (3, operands[1])
11283 || operands_match_p (operands[1], operands[3]))
11284 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11285 [(set (match_dup 4) (match_dup 0))
11286 (set (strict_low_part (match_dup 5))
11289 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11290 operands[5] = gen_lowpart (QImode, operands[3]);
11291 ix86_expand_clear (operands[3]);
11294 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11297 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11298 (set (match_operand:QI 1 "register_operand" "")
11299 (match_operator:QI 2 "ix86_comparison_operator"
11300 [(reg FLAGS_REG) (const_int 0)]))
11301 (parallel [(set (match_operand 3 "q_regs_operand" "")
11302 (zero_extend (match_dup 1)))
11303 (clobber (reg:CC FLAGS_REG))])]
11304 "(peep2_reg_dead_p (3, operands[1])
11305 || operands_match_p (operands[1], operands[3]))
11306 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11307 [(set (match_dup 4) (match_dup 0))
11308 (set (strict_low_part (match_dup 5))
11311 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11312 operands[5] = gen_lowpart (QImode, operands[3]);
11313 ix86_expand_clear (operands[3]);
11316 ;; Call instructions.
11318 ;; The predicates normally associated with named expanders are not properly
11319 ;; checked for calls. This is a bug in the generic code, but it isn't that
11320 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11322 ;; P6 processors will jump to the address after the decrement when %esp
11323 ;; is used as a call operand, so they will execute return address as a code.
11324 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11326 ;; Call subroutine returning no value.
11328 (define_expand "call_pop"
11329 [(parallel [(call (match_operand:QI 0 "" "")
11330 (match_operand:SI 1 "" ""))
11331 (set (reg:SI SP_REG)
11332 (plus:SI (reg:SI SP_REG)
11333 (match_operand:SI 3 "" "")))])]
11336 ix86_expand_call (NULL, operands[0], operands[1],
11337 operands[2], operands[3], 0);
11341 (define_insn_and_split "*call_pop_0_vzeroupper"
11343 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11344 (match_operand:SI 1 "" ""))
11345 (set (reg:SI SP_REG)
11346 (plus:SI (reg:SI SP_REG)
11347 (match_operand:SI 2 "immediate_operand" "")))])
11348 (unspec [(match_operand 3 "const_int_operand" "")]
11349 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11350 "TARGET_VZEROUPPER && !TARGET_64BIT"
11352 "&& reload_completed"
11354 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11355 [(set_attr "type" "call")])
11357 (define_insn "*call_pop_0"
11358 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11359 (match_operand:SI 1 "" ""))
11360 (set (reg:SI SP_REG)
11361 (plus:SI (reg:SI SP_REG)
11362 (match_operand:SI 2 "immediate_operand" "")))]
11365 if (SIBLING_CALL_P (insn))
11368 return "call\t%P0";
11370 [(set_attr "type" "call")])
11372 (define_insn_and_split "*call_pop_1_vzeroupper"
11374 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11375 (match_operand:SI 1 "" ""))
11376 (set (reg:SI SP_REG)
11377 (plus:SI (reg:SI SP_REG)
11378 (match_operand:SI 2 "immediate_operand" "i")))])
11379 (unspec [(match_operand 3 "const_int_operand" "")]
11380 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11381 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11383 "&& reload_completed"
11385 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11386 [(set_attr "type" "call")])
11388 (define_insn "*call_pop_1"
11389 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11390 (match_operand:SI 1 "" ""))
11391 (set (reg:SI SP_REG)
11392 (plus:SI (reg:SI SP_REG)
11393 (match_operand:SI 2 "immediate_operand" "i")))]
11394 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11396 if (constant_call_address_operand (operands[0], Pmode))
11397 return "call\t%P0";
11398 return "call\t%A0";
11400 [(set_attr "type" "call")])
11402 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11404 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11405 (match_operand:SI 1 "" ""))
11406 (set (reg:SI SP_REG)
11407 (plus:SI (reg:SI SP_REG)
11408 (match_operand:SI 2 "immediate_operand" "i,i")))])
11409 (unspec [(match_operand 3 "const_int_operand" "")]
11410 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11411 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11413 "&& reload_completed"
11415 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11416 [(set_attr "type" "call")])
11418 (define_insn "*sibcall_pop_1"
11419 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11420 (match_operand:SI 1 "" ""))
11421 (set (reg:SI SP_REG)
11422 (plus:SI (reg:SI SP_REG)
11423 (match_operand:SI 2 "immediate_operand" "i,i")))]
11424 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11428 [(set_attr "type" "call")])
11430 (define_expand "call"
11431 [(call (match_operand:QI 0 "" "")
11432 (match_operand 1 "" ""))
11433 (use (match_operand 2 "" ""))]
11436 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11440 (define_expand "sibcall"
11441 [(call (match_operand:QI 0 "" "")
11442 (match_operand 1 "" ""))
11443 (use (match_operand 2 "" ""))]
11446 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11450 (define_insn_and_split "*call_0_vzeroupper"
11451 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11452 (match_operand 1 "" ""))
11453 (unspec [(match_operand 2 "const_int_operand" "")]
11454 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11455 "TARGET_VZEROUPPER"
11457 "&& reload_completed"
11459 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11460 [(set_attr "type" "call")])
11462 (define_insn "*call_0"
11463 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11464 (match_operand 1 "" ""))]
11466 { return ix86_output_call_insn (insn, operands[0], 0); }
11467 [(set_attr "type" "call")])
11469 (define_insn_and_split "*call_1_vzeroupper"
11470 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11471 (match_operand 1 "" ""))
11472 (unspec [(match_operand 2 "const_int_operand" "")]
11473 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11474 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11476 "&& reload_completed"
11478 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11479 [(set_attr "type" "call")])
11481 (define_insn "*call_1"
11482 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11483 (match_operand 1 "" ""))]
11484 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11485 { return ix86_output_call_insn (insn, operands[0], 0); }
11486 [(set_attr "type" "call")])
11488 (define_insn_and_split "*sibcall_1_vzeroupper"
11489 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11490 (match_operand 1 "" ""))
11491 (unspec [(match_operand 2 "const_int_operand" "")]
11492 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11493 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11495 "&& reload_completed"
11497 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11498 [(set_attr "type" "call")])
11500 (define_insn "*sibcall_1"
11501 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11502 (match_operand 1 "" ""))]
11503 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11504 { return ix86_output_call_insn (insn, operands[0], 0); }
11505 [(set_attr "type" "call")])
11507 (define_insn_and_split "*call_1_rex64_vzeroupper"
11508 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11509 (match_operand 1 "" ""))
11510 (unspec [(match_operand 2 "const_int_operand" "")]
11511 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11512 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11513 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11515 "&& reload_completed"
11517 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11518 [(set_attr "type" "call")])
11520 (define_insn "*call_1_rex64"
11521 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11522 (match_operand 1 "" ""))]
11523 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11524 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11525 { return ix86_output_call_insn (insn, operands[0], 0); }
11526 [(set_attr "type" "call")])
11528 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11530 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11531 (match_operand 1 "" ""))
11532 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11533 (clobber (reg:TI XMM6_REG))
11534 (clobber (reg:TI XMM7_REG))
11535 (clobber (reg:TI XMM8_REG))
11536 (clobber (reg:TI XMM9_REG))
11537 (clobber (reg:TI XMM10_REG))
11538 (clobber (reg:TI XMM11_REG))
11539 (clobber (reg:TI XMM12_REG))
11540 (clobber (reg:TI XMM13_REG))
11541 (clobber (reg:TI XMM14_REG))
11542 (clobber (reg:TI XMM15_REG))
11543 (clobber (reg:DI SI_REG))
11544 (clobber (reg:DI DI_REG))])
11545 (unspec [(match_operand 2 "const_int_operand" "")]
11546 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11547 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11549 "&& reload_completed"
11551 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11552 [(set_attr "type" "call")])
11554 (define_insn "*call_1_rex64_ms_sysv"
11555 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11556 (match_operand 1 "" ""))
11557 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11558 (clobber (reg:TI XMM6_REG))
11559 (clobber (reg:TI XMM7_REG))
11560 (clobber (reg:TI XMM8_REG))
11561 (clobber (reg:TI XMM9_REG))
11562 (clobber (reg:TI XMM10_REG))
11563 (clobber (reg:TI XMM11_REG))
11564 (clobber (reg:TI XMM12_REG))
11565 (clobber (reg:TI XMM13_REG))
11566 (clobber (reg:TI XMM14_REG))
11567 (clobber (reg:TI XMM15_REG))
11568 (clobber (reg:DI SI_REG))
11569 (clobber (reg:DI DI_REG))]
11570 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11571 { return ix86_output_call_insn (insn, operands[0], 0); }
11572 [(set_attr "type" "call")])
11574 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11575 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11576 (match_operand 1 "" ""))
11577 (unspec [(match_operand 2 "const_int_operand" "")]
11578 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11579 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11581 "&& reload_completed"
11583 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11584 [(set_attr "type" "call")])
11586 (define_insn "*call_1_rex64_large"
11587 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11588 (match_operand 1 "" ""))]
11589 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11590 { return ix86_output_call_insn (insn, operands[0], 0); }
11591 [(set_attr "type" "call")])
11593 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11594 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11595 (match_operand 1 "" ""))
11596 (unspec [(match_operand 2 "const_int_operand" "")]
11597 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11598 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11600 "&& reload_completed"
11602 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11603 [(set_attr "type" "call")])
11605 (define_insn "*sibcall_1_rex64"
11606 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11607 (match_operand 1 "" ""))]
11608 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11609 { return ix86_output_call_insn (insn, operands[0], 0); }
11610 [(set_attr "type" "call")])
11612 ;; Call subroutine, returning value in operand 0
11613 (define_expand "call_value_pop"
11614 [(parallel [(set (match_operand 0 "" "")
11615 (call (match_operand:QI 1 "" "")
11616 (match_operand:SI 2 "" "")))
11617 (set (reg:SI SP_REG)
11618 (plus:SI (reg:SI SP_REG)
11619 (match_operand:SI 4 "" "")))])]
11622 ix86_expand_call (operands[0], operands[1], operands[2],
11623 operands[3], operands[4], 0);
11627 (define_expand "call_value"
11628 [(set (match_operand 0 "" "")
11629 (call (match_operand:QI 1 "" "")
11630 (match_operand:SI 2 "" "")))
11631 (use (match_operand:SI 3 "" ""))]
11632 ;; Operand 3 is not used on the i386.
11635 ix86_expand_call (operands[0], operands[1], operands[2],
11636 operands[3], NULL, 0);
11640 (define_expand "sibcall_value"
11641 [(set (match_operand 0 "" "")
11642 (call (match_operand:QI 1 "" "")
11643 (match_operand:SI 2 "" "")))
11644 (use (match_operand:SI 3 "" ""))]
11645 ;; Operand 3 is not used on the i386.
11648 ix86_expand_call (operands[0], operands[1], operands[2],
11649 operands[3], NULL, 1);
11653 ;; Call subroutine returning any type.
11655 (define_expand "untyped_call"
11656 [(parallel [(call (match_operand 0 "" "")
11658 (match_operand 1 "" "")
11659 (match_operand 2 "" "")])]
11664 /* In order to give reg-stack an easier job in validating two
11665 coprocessor registers as containing a possible return value,
11666 simply pretend the untyped call returns a complex long double
11669 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11670 and should have the default ABI. */
11672 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11673 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11674 operands[0], const0_rtx,
11675 GEN_INT ((TARGET_64BIT
11676 ? (ix86_abi == SYSV_ABI
11677 ? X86_64_SSE_REGPARM_MAX
11678 : X86_64_MS_SSE_REGPARM_MAX)
11679 : X86_32_SSE_REGPARM_MAX)
11683 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11685 rtx set = XVECEXP (operands[2], 0, i);
11686 emit_move_insn (SET_DEST (set), SET_SRC (set));
11689 /* The optimizer does not know that the call sets the function value
11690 registers we stored in the result block. We avoid problems by
11691 claiming that all hard registers are used and clobbered at this
11693 emit_insn (gen_blockage ());
11698 ;; Prologue and epilogue instructions
11700 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11701 ;; all of memory. This blocks insns from being moved across this point.
11703 (define_insn "blockage"
11704 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11707 [(set_attr "length" "0")])
11709 ;; Do not schedule instructions accessing memory across this point.
11711 (define_expand "memory_blockage"
11712 [(set (match_dup 0)
11713 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11716 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11717 MEM_VOLATILE_P (operands[0]) = 1;
11720 (define_insn "*memory_blockage"
11721 [(set (match_operand:BLK 0 "" "")
11722 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11725 [(set_attr "length" "0")])
11727 ;; As USE insns aren't meaningful after reload, this is used instead
11728 ;; to prevent deleting instructions setting registers for PIC code
11729 (define_insn "prologue_use"
11730 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11733 [(set_attr "length" "0")])
11735 ;; Insn emitted into the body of a function to return from a function.
11736 ;; This is only done if the function's epilogue is known to be simple.
11737 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11739 (define_expand "return"
11741 "ix86_can_use_return_insn_p ()"
11743 if (crtl->args.pops_args)
11745 rtx popc = GEN_INT (crtl->args.pops_args);
11746 emit_jump_insn (gen_return_pop_internal (popc));
11751 (define_insn "return_internal"
11755 [(set_attr "length" "1")
11756 (set_attr "atom_unit" "jeu")
11757 (set_attr "length_immediate" "0")
11758 (set_attr "modrm" "0")])
11760 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11761 ;; instruction Athlon and K8 have.
11763 (define_insn "return_internal_long"
11765 (unspec [(const_int 0)] UNSPEC_REP)]
11768 [(set_attr "length" "2")
11769 (set_attr "atom_unit" "jeu")
11770 (set_attr "length_immediate" "0")
11771 (set_attr "prefix_rep" "1")
11772 (set_attr "modrm" "0")])
11774 (define_insn "return_pop_internal"
11776 (use (match_operand:SI 0 "const_int_operand" ""))]
11779 [(set_attr "length" "3")
11780 (set_attr "atom_unit" "jeu")
11781 (set_attr "length_immediate" "2")
11782 (set_attr "modrm" "0")])
11784 (define_insn "return_indirect_internal"
11786 (use (match_operand:SI 0 "register_operand" "r"))]
11789 [(set_attr "type" "ibr")
11790 (set_attr "length_immediate" "0")])
11796 [(set_attr "length" "1")
11797 (set_attr "length_immediate" "0")
11798 (set_attr "modrm" "0")])
11800 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11801 (define_insn "nops"
11802 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11806 int num = INTVAL (operands[0]);
11808 gcc_assert (num >= 1 && num <= 8);
11811 fputs ("\tnop\n", asm_out_file);
11815 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11816 (set_attr "length_immediate" "0")
11817 (set_attr "modrm" "0")])
11819 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11820 ;; branch prediction penalty for the third jump in a 16-byte
11824 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11827 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11828 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11830 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11831 The align insn is used to avoid 3 jump instructions in the row to improve
11832 branch prediction and the benefits hardly outweigh the cost of extra 8
11833 nops on the average inserted by full alignment pseudo operation. */
11837 [(set_attr "length" "16")])
11839 (define_expand "prologue"
11842 "ix86_expand_prologue (); DONE;")
11844 (define_insn "set_got"
11845 [(set (match_operand:SI 0 "register_operand" "=r")
11846 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11847 (clobber (reg:CC FLAGS_REG))]
11849 "* return output_set_got (operands[0], NULL_RTX);"
11850 [(set_attr "type" "multi")
11851 (set_attr "length" "12")])
11853 (define_insn "set_got_labelled"
11854 [(set (match_operand:SI 0 "register_operand" "=r")
11855 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11857 (clobber (reg:CC FLAGS_REG))]
11859 "* return output_set_got (operands[0], operands[1]);"
11860 [(set_attr "type" "multi")
11861 (set_attr "length" "12")])
11863 (define_insn "set_got_rex64"
11864 [(set (match_operand:DI 0 "register_operand" "=r")
11865 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11867 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11868 [(set_attr "type" "lea")
11869 (set_attr "length_address" "4")
11870 (set_attr "mode" "DI")])
11872 (define_insn "set_rip_rex64"
11873 [(set (match_operand:DI 0 "register_operand" "=r")
11874 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11876 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11877 [(set_attr "type" "lea")
11878 (set_attr "length_address" "4")
11879 (set_attr "mode" "DI")])
11881 (define_insn "set_got_offset_rex64"
11882 [(set (match_operand:DI 0 "register_operand" "=r")
11884 [(label_ref (match_operand 1 "" ""))]
11885 UNSPEC_SET_GOT_OFFSET))]
11887 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11888 [(set_attr "type" "imov")
11889 (set_attr "length_immediate" "0")
11890 (set_attr "length_address" "8")
11891 (set_attr "mode" "DI")])
11893 (define_expand "epilogue"
11896 "ix86_expand_epilogue (1); DONE;")
11898 (define_expand "sibcall_epilogue"
11901 "ix86_expand_epilogue (0); DONE;")
11903 (define_expand "eh_return"
11904 [(use (match_operand 0 "register_operand" ""))]
11907 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11909 /* Tricky bit: we write the address of the handler to which we will
11910 be returning into someone else's stack frame, one word below the
11911 stack address we wish to restore. */
11912 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11913 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11914 tmp = gen_rtx_MEM (Pmode, tmp);
11915 emit_move_insn (tmp, ra);
11917 emit_jump_insn (gen_eh_return_internal ());
11922 (define_insn_and_split "eh_return_internal"
11926 "epilogue_completed"
11928 "ix86_expand_epilogue (2); DONE;")
11930 (define_insn "leave"
11931 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11932 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11933 (clobber (mem:BLK (scratch)))]
11936 [(set_attr "type" "leave")])
11938 (define_insn "leave_rex64"
11939 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11940 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11941 (clobber (mem:BLK (scratch)))]
11944 [(set_attr "type" "leave")])
11946 ;; Handle -fsplit-stack.
11948 (define_expand "split_stack_prologue"
11952 ix86_expand_split_stack_prologue ();
11956 ;; In order to support the call/return predictor, we use a return
11957 ;; instruction which the middle-end doesn't see.
11958 (define_insn "split_stack_return"
11959 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11960 UNSPECV_SPLIT_STACK_RETURN)]
11963 if (operands[0] == const0_rtx)
11968 [(set_attr "atom_unit" "jeu")
11969 (set_attr "modrm" "0")
11970 (set (attr "length")
11971 (if_then_else (match_operand:SI 0 "const0_operand" "")
11974 (set (attr "length_immediate")
11975 (if_then_else (match_operand:SI 0 "const0_operand" "")
11979 ;; If there are operand 0 bytes available on the stack, jump to
11982 (define_expand "split_stack_space_check"
11983 [(set (pc) (if_then_else
11984 (ltu (minus (reg SP_REG)
11985 (match_operand 0 "register_operand" ""))
11986 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11987 (label_ref (match_operand 1 "" ""))
11991 rtx reg, size, limit;
11993 reg = gen_reg_rtx (Pmode);
11994 size = force_reg (Pmode, operands[0]);
11995 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11996 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11997 UNSPEC_STACK_CHECK);
11998 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11999 ix86_expand_branch (GEU, reg, limit, operands[1]);
12004 ;; Bit manipulation instructions.
12006 (define_expand "ffs<mode>2"
12007 [(set (match_dup 2) (const_int -1))
12008 (parallel [(set (reg:CCZ FLAGS_REG)
12010 (match_operand:SWI48 1 "nonimmediate_operand" "")
12012 (set (match_operand:SWI48 0 "register_operand" "")
12013 (ctz:SWI48 (match_dup 1)))])
12014 (set (match_dup 0) (if_then_else:SWI48
12015 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12018 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12019 (clobber (reg:CC FLAGS_REG))])]
12022 if (<MODE>mode == SImode && !TARGET_CMOVE)
12024 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12027 operands[2] = gen_reg_rtx (<MODE>mode);
12030 (define_insn_and_split "ffssi2_no_cmove"
12031 [(set (match_operand:SI 0 "register_operand" "=r")
12032 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12033 (clobber (match_scratch:SI 2 "=&q"))
12034 (clobber (reg:CC FLAGS_REG))]
12037 "&& reload_completed"
12038 [(parallel [(set (reg:CCZ FLAGS_REG)
12039 (compare:CCZ (match_dup 1) (const_int 0)))
12040 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12041 (set (strict_low_part (match_dup 3))
12042 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12043 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12044 (clobber (reg:CC FLAGS_REG))])
12045 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12046 (clobber (reg:CC FLAGS_REG))])
12047 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12048 (clobber (reg:CC FLAGS_REG))])]
12050 operands[3] = gen_lowpart (QImode, operands[2]);
12051 ix86_expand_clear (operands[2]);
12054 (define_insn "*ffs<mode>_1"
12055 [(set (reg:CCZ FLAGS_REG)
12056 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12058 (set (match_operand:SWI48 0 "register_operand" "=r")
12059 (ctz:SWI48 (match_dup 1)))]
12061 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12062 [(set_attr "type" "alu1")
12063 (set_attr "prefix_0f" "1")
12064 (set_attr "mode" "<MODE>")])
12066 (define_insn "ctz<mode>2"
12067 [(set (match_operand:SWI248 0 "register_operand" "=r")
12068 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12069 (clobber (reg:CC FLAGS_REG))]
12073 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12075 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12077 [(set_attr "type" "alu1")
12078 (set_attr "prefix_0f" "1")
12079 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12080 (set_attr "mode" "<MODE>")])
12082 (define_expand "clz<mode>2"
12084 [(set (match_operand:SWI248 0 "register_operand" "")
12087 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12088 (clobber (reg:CC FLAGS_REG))])
12090 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12091 (clobber (reg:CC FLAGS_REG))])]
12096 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12099 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12102 (define_insn "clz<mode>2_abm"
12103 [(set (match_operand:SWI248 0 "register_operand" "=r")
12104 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12105 (clobber (reg:CC FLAGS_REG))]
12106 "TARGET_ABM || TARGET_BMI"
12107 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12108 [(set_attr "prefix_rep" "1")
12109 (set_attr "type" "bitmanip")
12110 (set_attr "mode" "<MODE>")])
12112 ;; BMI instructions.
12113 (define_insn "*bmi_andn_<mode>"
12114 [(set (match_operand:SWI48 0 "register_operand" "=r")
12117 (match_operand:SWI48 1 "register_operand" "r"))
12118 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12119 (clobber (reg:CC FLAGS_REG))]
12121 "andn\t{%2, %1, %0|%0, %1, %2}"
12122 [(set_attr "type" "bitmanip")
12123 (set_attr "mode" "<MODE>")])
12125 (define_insn "bmi_bextr_<mode>"
12126 [(set (match_operand:SWI48 0 "register_operand" "=r")
12127 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12128 (match_operand:SWI48 2 "register_operand" "r")]
12130 (clobber (reg:CC FLAGS_REG))]
12132 "bextr\t{%2, %1, %0|%0, %1, %2}"
12133 [(set_attr "type" "bitmanip")
12134 (set_attr "mode" "<MODE>")])
12136 (define_insn "*bmi_blsi_<mode>"
12137 [(set (match_operand:SWI48 0 "register_operand" "=r")
12140 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12142 (clobber (reg:CC FLAGS_REG))]
12144 "blsi\t{%1, %0|%0, %1}"
12145 [(set_attr "type" "bitmanip")
12146 (set_attr "mode" "<MODE>")])
12148 (define_insn "*bmi_blsmsk_<mode>"
12149 [(set (match_operand:SWI48 0 "register_operand" "=r")
12152 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12155 (clobber (reg:CC FLAGS_REG))]
12157 "blsmsk\t{%1, %0|%0, %1}"
12158 [(set_attr "type" "bitmanip")
12159 (set_attr "mode" "<MODE>")])
12161 (define_insn "*bmi_blsr_<mode>"
12162 [(set (match_operand:SWI48 0 "register_operand" "=r")
12165 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12168 (clobber (reg:CC FLAGS_REG))]
12170 "blsr\t{%1, %0|%0, %1}"
12171 [(set_attr "type" "bitmanip")
12172 (set_attr "mode" "<MODE>")])
12174 ;; TBM instructions.
12175 (define_insn "tbm_bextri_<mode>"
12176 [(set (match_operand:SWI48 0 "register_operand" "=r")
12177 (zero_extract:SWI48
12178 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12179 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12180 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12181 (clobber (reg:CC FLAGS_REG))]
12184 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12185 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12187 [(set_attr "type" "bitmanip")
12188 (set_attr "mode" "<MODE>")])
12190 (define_insn "*tbm_blcfill_<mode>"
12191 [(set (match_operand:SWI48 0 "register_operand" "=r")
12194 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12197 (clobber (reg:CC FLAGS_REG))]
12199 "blcfill\t{%1, %0|%0, %1}"
12200 [(set_attr "type" "bitmanip")
12201 (set_attr "mode" "<MODE>")])
12203 (define_insn "*tbm_blci_<mode>"
12204 [(set (match_operand:SWI48 0 "register_operand" "=r")
12208 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12211 (clobber (reg:CC FLAGS_REG))]
12213 "blci\t{%1, %0|%0, %1}"
12214 [(set_attr "type" "bitmanip")
12215 (set_attr "mode" "<MODE>")])
12217 (define_insn "*tbm_blcic_<mode>"
12218 [(set (match_operand:SWI48 0 "register_operand" "=r")
12221 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12225 (clobber (reg:CC FLAGS_REG))]
12227 "blcic\t{%1, %0|%0, %1}"
12228 [(set_attr "type" "bitmanip")
12229 (set_attr "mode" "<MODE>")])
12231 (define_insn "*tbm_blcmsk_<mode>"
12232 [(set (match_operand:SWI48 0 "register_operand" "=r")
12235 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12238 (clobber (reg:CC FLAGS_REG))]
12240 "blcmsk\t{%1, %0|%0, %1}"
12241 [(set_attr "type" "bitmanip")
12242 (set_attr "mode" "<MODE>")])
12244 (define_insn "*tbm_blcs_<mode>"
12245 [(set (match_operand:SWI48 0 "register_operand" "=r")
12248 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12251 (clobber (reg:CC FLAGS_REG))]
12253 "blcs\t{%1, %0|%0, %1}"
12254 [(set_attr "type" "bitmanip")
12255 (set_attr "mode" "<MODE>")])
12257 (define_insn "*tbm_blsfill_<mode>"
12258 [(set (match_operand:SWI48 0 "register_operand" "=r")
12261 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12264 (clobber (reg:CC FLAGS_REG))]
12266 "blsfill\t{%1, %0|%0, %1}"
12267 [(set_attr "type" "bitmanip")
12268 (set_attr "mode" "<MODE>")])
12270 (define_insn "*tbm_blsic_<mode>"
12271 [(set (match_operand:SWI48 0 "register_operand" "=r")
12274 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12278 (clobber (reg:CC FLAGS_REG))]
12280 "blsic\t{%1, %0|%0, %1}"
12281 [(set_attr "type" "bitmanip")
12282 (set_attr "mode" "<MODE>")])
12284 (define_insn "*tbm_t1mskc_<mode>"
12285 [(set (match_operand:SWI48 0 "register_operand" "=r")
12288 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12292 (clobber (reg:CC FLAGS_REG))]
12294 "t1mskc\t{%1, %0|%0, %1}"
12295 [(set_attr "type" "bitmanip")
12296 (set_attr "mode" "<MODE>")])
12298 (define_insn "*tbm_tzmsk_<mode>"
12299 [(set (match_operand:SWI48 0 "register_operand" "=r")
12302 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12306 (clobber (reg:CC FLAGS_REG))]
12308 "tzmsk\t{%1, %0|%0, %1}"
12309 [(set_attr "type" "bitmanip")
12310 (set_attr "mode" "<MODE>")])
12312 (define_insn "bsr_rex64"
12313 [(set (match_operand:DI 0 "register_operand" "=r")
12314 (minus:DI (const_int 63)
12315 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12316 (clobber (reg:CC FLAGS_REG))]
12318 "bsr{q}\t{%1, %0|%0, %1}"
12319 [(set_attr "type" "alu1")
12320 (set_attr "prefix_0f" "1")
12321 (set_attr "mode" "DI")])
12324 [(set (match_operand:SI 0 "register_operand" "=r")
12325 (minus:SI (const_int 31)
12326 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12327 (clobber (reg:CC FLAGS_REG))]
12329 "bsr{l}\t{%1, %0|%0, %1}"
12330 [(set_attr "type" "alu1")
12331 (set_attr "prefix_0f" "1")
12332 (set_attr "mode" "SI")])
12334 (define_insn "*bsrhi"
12335 [(set (match_operand:HI 0 "register_operand" "=r")
12336 (minus:HI (const_int 15)
12337 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12338 (clobber (reg:CC FLAGS_REG))]
12340 "bsr{w}\t{%1, %0|%0, %1}"
12341 [(set_attr "type" "alu1")
12342 (set_attr "prefix_0f" "1")
12343 (set_attr "mode" "HI")])
12345 (define_insn "popcount<mode>2"
12346 [(set (match_operand:SWI248 0 "register_operand" "=r")
12348 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12349 (clobber (reg:CC FLAGS_REG))]
12353 return "popcnt\t{%1, %0|%0, %1}";
12355 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12358 [(set_attr "prefix_rep" "1")
12359 (set_attr "type" "bitmanip")
12360 (set_attr "mode" "<MODE>")])
12362 (define_insn "*popcount<mode>2_cmp"
12363 [(set (reg FLAGS_REG)
12366 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12368 (set (match_operand:SWI248 0 "register_operand" "=r")
12369 (popcount:SWI248 (match_dup 1)))]
12370 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12373 return "popcnt\t{%1, %0|%0, %1}";
12375 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12378 [(set_attr "prefix_rep" "1")
12379 (set_attr "type" "bitmanip")
12380 (set_attr "mode" "<MODE>")])
12382 (define_insn "*popcountsi2_cmp_zext"
12383 [(set (reg FLAGS_REG)
12385 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12387 (set (match_operand:DI 0 "register_operand" "=r")
12388 (zero_extend:DI(popcount:SI (match_dup 1))))]
12389 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12392 return "popcnt\t{%1, %0|%0, %1}";
12394 return "popcnt{l}\t{%1, %0|%0, %1}";
12397 [(set_attr "prefix_rep" "1")
12398 (set_attr "type" "bitmanip")
12399 (set_attr "mode" "SI")])
12401 (define_expand "bswap<mode>2"
12402 [(set (match_operand:SWI48 0 "register_operand" "")
12403 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12406 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12408 rtx x = operands[0];
12410 emit_move_insn (x, operands[1]);
12411 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12412 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12413 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12418 (define_insn "*bswap<mode>2_movbe"
12419 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12420 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12422 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12425 movbe\t{%1, %0|%0, %1}
12426 movbe\t{%1, %0|%0, %1}"
12427 [(set_attr "type" "bitmanip,imov,imov")
12428 (set_attr "modrm" "0,1,1")
12429 (set_attr "prefix_0f" "*,1,1")
12430 (set_attr "prefix_extra" "*,1,1")
12431 (set_attr "mode" "<MODE>")])
12433 (define_insn "*bswap<mode>2_1"
12434 [(set (match_operand:SWI48 0 "register_operand" "=r")
12435 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12438 [(set_attr "type" "bitmanip")
12439 (set_attr "modrm" "0")
12440 (set_attr "mode" "<MODE>")])
12442 (define_insn "*bswaphi_lowpart_1"
12443 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12444 (bswap:HI (match_dup 0)))
12445 (clobber (reg:CC FLAGS_REG))]
12446 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12448 xchg{b}\t{%h0, %b0|%b0, %h0}
12449 rol{w}\t{$8, %0|%0, 8}"
12450 [(set_attr "length" "2,4")
12451 (set_attr "mode" "QI,HI")])
12453 (define_insn "bswaphi_lowpart"
12454 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12455 (bswap:HI (match_dup 0)))
12456 (clobber (reg:CC FLAGS_REG))]
12458 "rol{w}\t{$8, %0|%0, 8}"
12459 [(set_attr "length" "4")
12460 (set_attr "mode" "HI")])
12462 (define_expand "paritydi2"
12463 [(set (match_operand:DI 0 "register_operand" "")
12464 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12467 rtx scratch = gen_reg_rtx (QImode);
12470 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12471 NULL_RTX, operands[1]));
12473 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12474 gen_rtx_REG (CCmode, FLAGS_REG),
12476 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12479 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12482 rtx tmp = gen_reg_rtx (SImode);
12484 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12485 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12490 (define_expand "paritysi2"
12491 [(set (match_operand:SI 0 "register_operand" "")
12492 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12495 rtx scratch = gen_reg_rtx (QImode);
12498 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12500 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12501 gen_rtx_REG (CCmode, FLAGS_REG),
12503 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12505 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12509 (define_insn_and_split "paritydi2_cmp"
12510 [(set (reg:CC FLAGS_REG)
12511 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12513 (clobber (match_scratch:DI 0 "=r"))
12514 (clobber (match_scratch:SI 1 "=&r"))
12515 (clobber (match_scratch:HI 2 "=Q"))]
12518 "&& reload_completed"
12520 [(set (match_dup 1)
12521 (xor:SI (match_dup 1) (match_dup 4)))
12522 (clobber (reg:CC FLAGS_REG))])
12524 [(set (reg:CC FLAGS_REG)
12525 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12526 (clobber (match_dup 1))
12527 (clobber (match_dup 2))])]
12529 operands[4] = gen_lowpart (SImode, operands[3]);
12533 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12534 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12537 operands[1] = gen_highpart (SImode, operands[3]);
12540 (define_insn_and_split "paritysi2_cmp"
12541 [(set (reg:CC FLAGS_REG)
12542 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12544 (clobber (match_scratch:SI 0 "=r"))
12545 (clobber (match_scratch:HI 1 "=&Q"))]
12548 "&& reload_completed"
12550 [(set (match_dup 1)
12551 (xor:HI (match_dup 1) (match_dup 3)))
12552 (clobber (reg:CC FLAGS_REG))])
12554 [(set (reg:CC FLAGS_REG)
12555 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12556 (clobber (match_dup 1))])]
12558 operands[3] = gen_lowpart (HImode, operands[2]);
12560 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12561 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12564 (define_insn "*parityhi2_cmp"
12565 [(set (reg:CC FLAGS_REG)
12566 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12568 (clobber (match_scratch:HI 0 "=Q"))]
12570 "xor{b}\t{%h0, %b0|%b0, %h0}"
12571 [(set_attr "length" "2")
12572 (set_attr "mode" "HI")])
12574 ;; Thread-local storage patterns for ELF.
12576 ;; Note that these code sequences must appear exactly as shown
12577 ;; in order to allow linker relaxation.
12579 (define_insn "*tls_global_dynamic_32_gnu"
12580 [(set (match_operand:SI 0 "register_operand" "=a")
12581 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12582 (match_operand:SI 2 "tls_symbolic_operand" "")
12583 (match_operand:SI 3 "call_insn_operand" "")]
12585 (clobber (match_scratch:SI 4 "=d"))
12586 (clobber (match_scratch:SI 5 "=c"))
12587 (clobber (reg:CC FLAGS_REG))]
12588 "!TARGET_64BIT && TARGET_GNU_TLS"
12589 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12590 [(set_attr "type" "multi")
12591 (set_attr "length" "12")])
12593 (define_expand "tls_global_dynamic_32"
12594 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12597 (match_operand:SI 1 "tls_symbolic_operand" "")
12600 (clobber (match_scratch:SI 4 ""))
12601 (clobber (match_scratch:SI 5 ""))
12602 (clobber (reg:CC FLAGS_REG))])]
12606 operands[2] = pic_offset_table_rtx;
12609 operands[2] = gen_reg_rtx (Pmode);
12610 emit_insn (gen_set_got (operands[2]));
12612 if (TARGET_GNU2_TLS)
12614 emit_insn (gen_tls_dynamic_gnu2_32
12615 (operands[0], operands[1], operands[2]));
12618 operands[3] = ix86_tls_get_addr ();
12621 (define_insn "*tls_global_dynamic_64"
12622 [(set (match_operand:DI 0 "register_operand" "=a")
12623 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12624 (match_operand:DI 3 "" "")))
12625 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12628 { 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"; }
12629 [(set_attr "type" "multi")
12630 (set_attr "length" "16")])
12632 (define_expand "tls_global_dynamic_64"
12633 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12634 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12635 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12639 if (TARGET_GNU2_TLS)
12641 emit_insn (gen_tls_dynamic_gnu2_64
12642 (operands[0], operands[1]));
12645 operands[2] = ix86_tls_get_addr ();
12648 (define_insn "*tls_local_dynamic_base_32_gnu"
12649 [(set (match_operand:SI 0 "register_operand" "=a")
12650 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12651 (match_operand:SI 2 "call_insn_operand" "")]
12652 UNSPEC_TLS_LD_BASE))
12653 (clobber (match_scratch:SI 3 "=d"))
12654 (clobber (match_scratch:SI 4 "=c"))
12655 (clobber (reg:CC FLAGS_REG))]
12656 "!TARGET_64BIT && TARGET_GNU_TLS"
12657 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12658 [(set_attr "type" "multi")
12659 (set_attr "length" "11")])
12661 (define_expand "tls_local_dynamic_base_32"
12662 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12663 (unspec:SI [(match_dup 1) (match_dup 2)]
12664 UNSPEC_TLS_LD_BASE))
12665 (clobber (match_scratch:SI 3 ""))
12666 (clobber (match_scratch:SI 4 ""))
12667 (clobber (reg:CC FLAGS_REG))])]
12671 operands[1] = pic_offset_table_rtx;
12674 operands[1] = gen_reg_rtx (Pmode);
12675 emit_insn (gen_set_got (operands[1]));
12677 if (TARGET_GNU2_TLS)
12679 emit_insn (gen_tls_dynamic_gnu2_32
12680 (operands[0], ix86_tls_module_base (), operands[1]));
12683 operands[2] = ix86_tls_get_addr ();
12686 (define_insn "*tls_local_dynamic_base_64"
12687 [(set (match_operand:DI 0 "register_operand" "=a")
12688 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12689 (match_operand:DI 2 "" "")))
12690 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12692 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12693 [(set_attr "type" "multi")
12694 (set_attr "length" "12")])
12696 (define_expand "tls_local_dynamic_base_64"
12697 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12698 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12699 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12702 if (TARGET_GNU2_TLS)
12704 emit_insn (gen_tls_dynamic_gnu2_64
12705 (operands[0], ix86_tls_module_base ()));
12708 operands[1] = ix86_tls_get_addr ();
12711 ;; Local dynamic of a single variable is a lose. Show combine how
12712 ;; to convert that back to global dynamic.
12714 (define_insn_and_split "*tls_local_dynamic_32_once"
12715 [(set (match_operand:SI 0 "register_operand" "=a")
12716 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12717 (match_operand:SI 2 "call_insn_operand" "")]
12718 UNSPEC_TLS_LD_BASE)
12719 (const:SI (unspec:SI
12720 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12722 (clobber (match_scratch:SI 4 "=d"))
12723 (clobber (match_scratch:SI 5 "=c"))
12724 (clobber (reg:CC FLAGS_REG))]
12728 [(parallel [(set (match_dup 0)
12729 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12731 (clobber (match_dup 4))
12732 (clobber (match_dup 5))
12733 (clobber (reg:CC FLAGS_REG))])])
12735 ;; Segment register for the thread base ptr load
12736 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12738 ;; Load and add the thread base pointer from %gs:0.
12739 (define_insn "*load_tp_<mode>"
12740 [(set (match_operand:P 0 "register_operand" "=r")
12741 (unspec:P [(const_int 0)] UNSPEC_TP))]
12743 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12744 [(set_attr "type" "imov")
12745 (set_attr "modrm" "0")
12746 (set_attr "length" "7")
12747 (set_attr "memory" "load")
12748 (set_attr "imm_disp" "false")])
12750 (define_insn "*add_tp_<mode>"
12751 [(set (match_operand:P 0 "register_operand" "=r")
12752 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12753 (match_operand:P 1 "register_operand" "0")))
12754 (clobber (reg:CC FLAGS_REG))]
12756 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12757 [(set_attr "type" "alu")
12758 (set_attr "modrm" "0")
12759 (set_attr "length" "7")
12760 (set_attr "memory" "load")
12761 (set_attr "imm_disp" "false")])
12763 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12764 ;; %rax as destination of the initial executable code sequence.
12765 (define_insn "tls_initial_exec_64_sun"
12766 [(set (match_operand:DI 0 "register_operand" "=a")
12768 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12769 UNSPEC_TLS_IE_SUN))
12770 (clobber (reg:CC FLAGS_REG))]
12771 "TARGET_64BIT && TARGET_SUN_TLS"
12772 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12773 [(set_attr "type" "multi")])
12775 ;; GNU2 TLS patterns can be split.
12777 (define_expand "tls_dynamic_gnu2_32"
12778 [(set (match_dup 3)
12779 (plus:SI (match_operand:SI 2 "register_operand" "")
12781 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12784 [(set (match_operand:SI 0 "register_operand" "")
12785 (unspec:SI [(match_dup 1) (match_dup 3)
12786 (match_dup 2) (reg:SI SP_REG)]
12788 (clobber (reg:CC FLAGS_REG))])]
12789 "!TARGET_64BIT && TARGET_GNU2_TLS"
12791 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12792 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12795 (define_insn "*tls_dynamic_lea_32"
12796 [(set (match_operand:SI 0 "register_operand" "=r")
12797 (plus:SI (match_operand:SI 1 "register_operand" "b")
12799 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12800 UNSPEC_TLSDESC))))]
12801 "!TARGET_64BIT && TARGET_GNU2_TLS"
12802 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12803 [(set_attr "type" "lea")
12804 (set_attr "mode" "SI")
12805 (set_attr "length" "6")
12806 (set_attr "length_address" "4")])
12808 (define_insn "*tls_dynamic_call_32"
12809 [(set (match_operand:SI 0 "register_operand" "=a")
12810 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12811 (match_operand:SI 2 "register_operand" "0")
12812 ;; we have to make sure %ebx still points to the GOT
12813 (match_operand:SI 3 "register_operand" "b")
12816 (clobber (reg:CC FLAGS_REG))]
12817 "!TARGET_64BIT && TARGET_GNU2_TLS"
12818 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12819 [(set_attr "type" "call")
12820 (set_attr "length" "2")
12821 (set_attr "length_address" "0")])
12823 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12824 [(set (match_operand:SI 0 "register_operand" "=&a")
12826 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12827 (match_operand:SI 4 "" "")
12828 (match_operand:SI 2 "register_operand" "b")
12831 (const:SI (unspec:SI
12832 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12834 (clobber (reg:CC FLAGS_REG))]
12835 "!TARGET_64BIT && TARGET_GNU2_TLS"
12838 [(set (match_dup 0) (match_dup 5))]
12840 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12841 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12844 (define_expand "tls_dynamic_gnu2_64"
12845 [(set (match_dup 2)
12846 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12849 [(set (match_operand:DI 0 "register_operand" "")
12850 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12852 (clobber (reg:CC FLAGS_REG))])]
12853 "TARGET_64BIT && TARGET_GNU2_TLS"
12855 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12856 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12859 (define_insn "*tls_dynamic_lea_64"
12860 [(set (match_operand:DI 0 "register_operand" "=r")
12861 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12863 "TARGET_64BIT && TARGET_GNU2_TLS"
12864 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12865 [(set_attr "type" "lea")
12866 (set_attr "mode" "DI")
12867 (set_attr "length" "7")
12868 (set_attr "length_address" "4")])
12870 (define_insn "*tls_dynamic_call_64"
12871 [(set (match_operand:DI 0 "register_operand" "=a")
12872 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12873 (match_operand:DI 2 "register_operand" "0")
12876 (clobber (reg:CC FLAGS_REG))]
12877 "TARGET_64BIT && TARGET_GNU2_TLS"
12878 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12879 [(set_attr "type" "call")
12880 (set_attr "length" "2")
12881 (set_attr "length_address" "0")])
12883 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12884 [(set (match_operand:DI 0 "register_operand" "=&a")
12886 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12887 (match_operand:DI 3 "" "")
12890 (const:DI (unspec:DI
12891 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12893 (clobber (reg:CC FLAGS_REG))]
12894 "TARGET_64BIT && TARGET_GNU2_TLS"
12897 [(set (match_dup 0) (match_dup 4))]
12899 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12900 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12903 ;; These patterns match the binary 387 instructions for addM3, subM3,
12904 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12905 ;; SFmode. The first is the normal insn, the second the same insn but
12906 ;; with one operand a conversion, and the third the same insn but with
12907 ;; the other operand a conversion. The conversion may be SFmode or
12908 ;; SImode if the target mode DFmode, but only SImode if the target mode
12911 ;; Gcc is slightly more smart about handling normal two address instructions
12912 ;; so use special patterns for add and mull.
12914 (define_insn "*fop_<mode>_comm_mixed"
12915 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12916 (match_operator:MODEF 3 "binary_fp_operator"
12917 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12918 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12919 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12920 && COMMUTATIVE_ARITH_P (operands[3])
12921 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12922 "* return output_387_binary_op (insn, operands);"
12923 [(set (attr "type")
12924 (if_then_else (eq_attr "alternative" "1,2")
12925 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12926 (const_string "ssemul")
12927 (const_string "sseadd"))
12928 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12929 (const_string "fmul")
12930 (const_string "fop"))))
12931 (set_attr "isa" "base,noavx,avx")
12932 (set_attr "prefix" "orig,orig,vex")
12933 (set_attr "mode" "<MODE>")])
12935 (define_insn "*fop_<mode>_comm_sse"
12936 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12937 (match_operator:MODEF 3 "binary_fp_operator"
12938 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12939 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12940 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12941 && COMMUTATIVE_ARITH_P (operands[3])
12942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12943 "* return output_387_binary_op (insn, operands);"
12944 [(set (attr "type")
12945 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12946 (const_string "ssemul")
12947 (const_string "sseadd")))
12948 (set_attr "isa" "noavx,avx")
12949 (set_attr "prefix" "orig,vex")
12950 (set_attr "mode" "<MODE>")])
12952 (define_insn "*fop_<mode>_comm_i387"
12953 [(set (match_operand:MODEF 0 "register_operand" "=f")
12954 (match_operator:MODEF 3 "binary_fp_operator"
12955 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12956 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12957 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12958 && COMMUTATIVE_ARITH_P (operands[3])
12959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12960 "* return output_387_binary_op (insn, operands);"
12961 [(set (attr "type")
12962 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12963 (const_string "fmul")
12964 (const_string "fop")))
12965 (set_attr "mode" "<MODE>")])
12967 (define_insn "*fop_<mode>_1_mixed"
12968 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12969 (match_operator:MODEF 3 "binary_fp_operator"
12970 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12971 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12972 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12973 && !COMMUTATIVE_ARITH_P (operands[3])
12974 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12975 "* return output_387_binary_op (insn, operands);"
12976 [(set (attr "type")
12977 (cond [(and (eq_attr "alternative" "2,3")
12978 (match_operand:MODEF 3 "mult_operator" ""))
12979 (const_string "ssemul")
12980 (and (eq_attr "alternative" "2,3")
12981 (match_operand:MODEF 3 "div_operator" ""))
12982 (const_string "ssediv")
12983 (eq_attr "alternative" "2,3")
12984 (const_string "sseadd")
12985 (match_operand:MODEF 3 "mult_operator" "")
12986 (const_string "fmul")
12987 (match_operand:MODEF 3 "div_operator" "")
12988 (const_string "fdiv")
12990 (const_string "fop")))
12991 (set_attr "isa" "base,base,noavx,avx")
12992 (set_attr "prefix" "orig,orig,orig,vex")
12993 (set_attr "mode" "<MODE>")])
12995 (define_insn "*rcpsf2_sse"
12996 [(set (match_operand:SF 0 "register_operand" "=x")
12997 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13000 "%vrcpss\t{%1, %d0|%d0, %1}"
13001 [(set_attr "type" "sse")
13002 (set_attr "atom_sse_attr" "rcp")
13003 (set_attr "prefix" "maybe_vex")
13004 (set_attr "mode" "SF")])
13006 (define_insn "*fop_<mode>_1_sse"
13007 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13008 (match_operator:MODEF 3 "binary_fp_operator"
13009 [(match_operand:MODEF 1 "register_operand" "0,x")
13010 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13011 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13012 && !COMMUTATIVE_ARITH_P (operands[3])"
13013 "* return output_387_binary_op (insn, operands);"
13014 [(set (attr "type")
13015 (cond [(match_operand:MODEF 3 "mult_operator" "")
13016 (const_string "ssemul")
13017 (match_operand:MODEF 3 "div_operator" "")
13018 (const_string "ssediv")
13020 (const_string "sseadd")))
13021 (set_attr "isa" "noavx,avx")
13022 (set_attr "prefix" "orig,vex")
13023 (set_attr "mode" "<MODE>")])
13025 ;; This pattern is not fully shadowed by the pattern above.
13026 (define_insn "*fop_<mode>_1_i387"
13027 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13028 (match_operator:MODEF 3 "binary_fp_operator"
13029 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13030 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13031 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13032 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13033 && !COMMUTATIVE_ARITH_P (operands[3])
13034 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13035 "* return 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 "mode" "<MODE>")])
13045 ;; ??? Add SSE splitters for these!
13046 (define_insn "*fop_<MODEF:mode>_2_i387"
13047 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13048 (match_operator:MODEF 3 "binary_fp_operator"
13050 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13051 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13052 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13053 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13054 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13055 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13056 [(set (attr "type")
13057 (cond [(match_operand:MODEF 3 "mult_operator" "")
13058 (const_string "fmul")
13059 (match_operand:MODEF 3 "div_operator" "")
13060 (const_string "fdiv")
13062 (const_string "fop")))
13063 (set_attr "fp_int_src" "true")
13064 (set_attr "mode" "<X87MODEI12:MODE>")])
13066 (define_insn "*fop_<MODEF:mode>_3_i387"
13067 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13068 (match_operator:MODEF 3 "binary_fp_operator"
13069 [(match_operand:MODEF 1 "register_operand" "0,0")
13071 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13072 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13073 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13074 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13075 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13076 [(set (attr "type")
13077 (cond [(match_operand:MODEF 3 "mult_operator" "")
13078 (const_string "fmul")
13079 (match_operand:MODEF 3 "div_operator" "")
13080 (const_string "fdiv")
13082 (const_string "fop")))
13083 (set_attr "fp_int_src" "true")
13084 (set_attr "mode" "<MODE>")])
13086 (define_insn "*fop_df_4_i387"
13087 [(set (match_operand:DF 0 "register_operand" "=f,f")
13088 (match_operator:DF 3 "binary_fp_operator"
13090 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13091 (match_operand:DF 2 "register_operand" "0,f")]))]
13092 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13093 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13094 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13095 "* return output_387_binary_op (insn, operands);"
13096 [(set (attr "type")
13097 (cond [(match_operand:DF 3 "mult_operator" "")
13098 (const_string "fmul")
13099 (match_operand:DF 3 "div_operator" "")
13100 (const_string "fdiv")
13102 (const_string "fop")))
13103 (set_attr "mode" "SF")])
13105 (define_insn "*fop_df_5_i387"
13106 [(set (match_operand:DF 0 "register_operand" "=f,f")
13107 (match_operator:DF 3 "binary_fp_operator"
13108 [(match_operand:DF 1 "register_operand" "0,f")
13110 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13111 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13112 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13113 "* return output_387_binary_op (insn, operands);"
13114 [(set (attr "type")
13115 (cond [(match_operand:DF 3 "mult_operator" "")
13116 (const_string "fmul")
13117 (match_operand:DF 3 "div_operator" "")
13118 (const_string "fdiv")
13120 (const_string "fop")))
13121 (set_attr "mode" "SF")])
13123 (define_insn "*fop_df_6_i387"
13124 [(set (match_operand:DF 0 "register_operand" "=f,f")
13125 (match_operator:DF 3 "binary_fp_operator"
13127 (match_operand:SF 1 "register_operand" "0,f"))
13129 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13130 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13131 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13132 "* return output_387_binary_op (insn, operands);"
13133 [(set (attr "type")
13134 (cond [(match_operand:DF 3 "mult_operator" "")
13135 (const_string "fmul")
13136 (match_operand:DF 3 "div_operator" "")
13137 (const_string "fdiv")
13139 (const_string "fop")))
13140 (set_attr "mode" "SF")])
13142 (define_insn "*fop_xf_comm_i387"
13143 [(set (match_operand:XF 0 "register_operand" "=f")
13144 (match_operator:XF 3 "binary_fp_operator"
13145 [(match_operand:XF 1 "register_operand" "%0")
13146 (match_operand:XF 2 "register_operand" "f")]))]
13148 && COMMUTATIVE_ARITH_P (operands[3])"
13149 "* return output_387_binary_op (insn, operands);"
13150 [(set (attr "type")
13151 (if_then_else (match_operand:XF 3 "mult_operator" "")
13152 (const_string "fmul")
13153 (const_string "fop")))
13154 (set_attr "mode" "XF")])
13156 (define_insn "*fop_xf_1_i387"
13157 [(set (match_operand:XF 0 "register_operand" "=f,f")
13158 (match_operator:XF 3 "binary_fp_operator"
13159 [(match_operand:XF 1 "register_operand" "0,f")
13160 (match_operand:XF 2 "register_operand" "f,0")]))]
13162 && !COMMUTATIVE_ARITH_P (operands[3])"
13163 "* return output_387_binary_op (insn, operands);"
13164 [(set (attr "type")
13165 (cond [(match_operand:XF 3 "mult_operator" "")
13166 (const_string "fmul")
13167 (match_operand:XF 3 "div_operator" "")
13168 (const_string "fdiv")
13170 (const_string "fop")))
13171 (set_attr "mode" "XF")])
13173 (define_insn "*fop_xf_2_i387"
13174 [(set (match_operand:XF 0 "register_operand" "=f,f")
13175 (match_operator:XF 3 "binary_fp_operator"
13177 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13178 (match_operand:XF 2 "register_operand" "0,0")]))]
13179 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13180 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13181 [(set (attr "type")
13182 (cond [(match_operand:XF 3 "mult_operator" "")
13183 (const_string "fmul")
13184 (match_operand:XF 3 "div_operator" "")
13185 (const_string "fdiv")
13187 (const_string "fop")))
13188 (set_attr "fp_int_src" "true")
13189 (set_attr "mode" "<MODE>")])
13191 (define_insn "*fop_xf_3_i387"
13192 [(set (match_operand:XF 0 "register_operand" "=f,f")
13193 (match_operator:XF 3 "binary_fp_operator"
13194 [(match_operand:XF 1 "register_operand" "0,0")
13196 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13197 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13198 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13199 [(set (attr "type")
13200 (cond [(match_operand:XF 3 "mult_operator" "")
13201 (const_string "fmul")
13202 (match_operand:XF 3 "div_operator" "")
13203 (const_string "fdiv")
13205 (const_string "fop")))
13206 (set_attr "fp_int_src" "true")
13207 (set_attr "mode" "<MODE>")])
13209 (define_insn "*fop_xf_4_i387"
13210 [(set (match_operand:XF 0 "register_operand" "=f,f")
13211 (match_operator:XF 3 "binary_fp_operator"
13213 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13214 (match_operand:XF 2 "register_operand" "0,f")]))]
13216 "* return output_387_binary_op (insn, operands);"
13217 [(set (attr "type")
13218 (cond [(match_operand:XF 3 "mult_operator" "")
13219 (const_string "fmul")
13220 (match_operand:XF 3 "div_operator" "")
13221 (const_string "fdiv")
13223 (const_string "fop")))
13224 (set_attr "mode" "<MODE>")])
13226 (define_insn "*fop_xf_5_i387"
13227 [(set (match_operand:XF 0 "register_operand" "=f,f")
13228 (match_operator:XF 3 "binary_fp_operator"
13229 [(match_operand:XF 1 "register_operand" "0,f")
13231 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13233 "* return output_387_binary_op (insn, operands);"
13234 [(set (attr "type")
13235 (cond [(match_operand:XF 3 "mult_operator" "")
13236 (const_string "fmul")
13237 (match_operand:XF 3 "div_operator" "")
13238 (const_string "fdiv")
13240 (const_string "fop")))
13241 (set_attr "mode" "<MODE>")])
13243 (define_insn "*fop_xf_6_i387"
13244 [(set (match_operand:XF 0 "register_operand" "=f,f")
13245 (match_operator:XF 3 "binary_fp_operator"
13247 (match_operand:MODEF 1 "register_operand" "0,f"))
13249 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13251 "* return output_387_binary_op (insn, operands);"
13252 [(set (attr "type")
13253 (cond [(match_operand:XF 3 "mult_operator" "")
13254 (const_string "fmul")
13255 (match_operand:XF 3 "div_operator" "")
13256 (const_string "fdiv")
13258 (const_string "fop")))
13259 (set_attr "mode" "<MODE>")])
13262 [(set (match_operand 0 "register_operand" "")
13263 (match_operator 3 "binary_fp_operator"
13264 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13265 (match_operand 2 "register_operand" "")]))]
13267 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13268 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13271 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13272 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13273 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13274 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13275 GET_MODE (operands[3]),
13278 ix86_free_from_memory (GET_MODE (operands[1]));
13283 [(set (match_operand 0 "register_operand" "")
13284 (match_operator 3 "binary_fp_operator"
13285 [(match_operand 1 "register_operand" "")
13286 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13288 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13289 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13292 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13293 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13294 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13295 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13296 GET_MODE (operands[3]),
13299 ix86_free_from_memory (GET_MODE (operands[2]));
13303 ;; FPU special functions.
13305 ;; This pattern implements a no-op XFmode truncation for
13306 ;; all fancy i386 XFmode math functions.
13308 (define_insn "truncxf<mode>2_i387_noop_unspec"
13309 [(set (match_operand:MODEF 0 "register_operand" "=f")
13310 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13311 UNSPEC_TRUNC_NOOP))]
13312 "TARGET_USE_FANCY_MATH_387"
13313 "* return output_387_reg_move (insn, operands);"
13314 [(set_attr "type" "fmov")
13315 (set_attr "mode" "<MODE>")])
13317 (define_insn "sqrtxf2"
13318 [(set (match_operand:XF 0 "register_operand" "=f")
13319 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13320 "TARGET_USE_FANCY_MATH_387"
13322 [(set_attr "type" "fpspc")
13323 (set_attr "mode" "XF")
13324 (set_attr "athlon_decode" "direct")
13325 (set_attr "amdfam10_decode" "direct")
13326 (set_attr "bdver1_decode" "direct")])
13328 (define_insn "sqrt_extend<mode>xf2_i387"
13329 [(set (match_operand:XF 0 "register_operand" "=f")
13332 (match_operand:MODEF 1 "register_operand" "0"))))]
13333 "TARGET_USE_FANCY_MATH_387"
13335 [(set_attr "type" "fpspc")
13336 (set_attr "mode" "XF")
13337 (set_attr "athlon_decode" "direct")
13338 (set_attr "amdfam10_decode" "direct")
13339 (set_attr "bdver1_decode" "direct")])
13341 (define_insn "*rsqrtsf2_sse"
13342 [(set (match_operand:SF 0 "register_operand" "=x")
13343 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13346 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13347 [(set_attr "type" "sse")
13348 (set_attr "atom_sse_attr" "rcp")
13349 (set_attr "prefix" "maybe_vex")
13350 (set_attr "mode" "SF")])
13352 (define_expand "rsqrtsf2"
13353 [(set (match_operand:SF 0 "register_operand" "")
13354 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13358 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13362 (define_insn "*sqrt<mode>2_sse"
13363 [(set (match_operand:MODEF 0 "register_operand" "=x")
13365 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13366 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13367 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13368 [(set_attr "type" "sse")
13369 (set_attr "atom_sse_attr" "sqrt")
13370 (set_attr "prefix" "maybe_vex")
13371 (set_attr "mode" "<MODE>")
13372 (set_attr "athlon_decode" "*")
13373 (set_attr "amdfam10_decode" "*")
13374 (set_attr "bdver1_decode" "*")])
13376 (define_expand "sqrt<mode>2"
13377 [(set (match_operand:MODEF 0 "register_operand" "")
13379 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13380 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13381 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13383 if (<MODE>mode == SFmode
13384 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13385 && flag_finite_math_only && !flag_trapping_math
13386 && flag_unsafe_math_optimizations)
13388 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13392 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13394 rtx op0 = gen_reg_rtx (XFmode);
13395 rtx op1 = force_reg (<MODE>mode, operands[1]);
13397 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13398 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13403 (define_insn "fpremxf4_i387"
13404 [(set (match_operand:XF 0 "register_operand" "=f")
13405 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13406 (match_operand:XF 3 "register_operand" "1")]
13408 (set (match_operand:XF 1 "register_operand" "=u")
13409 (unspec:XF [(match_dup 2) (match_dup 3)]
13411 (set (reg:CCFP FPSR_REG)
13412 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13414 "TARGET_USE_FANCY_MATH_387"
13416 [(set_attr "type" "fpspc")
13417 (set_attr "mode" "XF")])
13419 (define_expand "fmodxf3"
13420 [(use (match_operand:XF 0 "register_operand" ""))
13421 (use (match_operand:XF 1 "general_operand" ""))
13422 (use (match_operand:XF 2 "general_operand" ""))]
13423 "TARGET_USE_FANCY_MATH_387"
13425 rtx label = gen_label_rtx ();
13427 rtx op1 = gen_reg_rtx (XFmode);
13428 rtx op2 = gen_reg_rtx (XFmode);
13430 emit_move_insn (op2, operands[2]);
13431 emit_move_insn (op1, operands[1]);
13433 emit_label (label);
13434 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13435 ix86_emit_fp_unordered_jump (label);
13436 LABEL_NUSES (label) = 1;
13438 emit_move_insn (operands[0], op1);
13442 (define_expand "fmod<mode>3"
13443 [(use (match_operand:MODEF 0 "register_operand" ""))
13444 (use (match_operand:MODEF 1 "general_operand" ""))
13445 (use (match_operand:MODEF 2 "general_operand" ""))]
13446 "TARGET_USE_FANCY_MATH_387"
13448 rtx (*gen_truncxf) (rtx, rtx);
13450 rtx label = gen_label_rtx ();
13452 rtx op1 = gen_reg_rtx (XFmode);
13453 rtx op2 = gen_reg_rtx (XFmode);
13455 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13458 emit_label (label);
13459 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13460 ix86_emit_fp_unordered_jump (label);
13461 LABEL_NUSES (label) = 1;
13463 /* Truncate the result properly for strict SSE math. */
13464 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13465 && !TARGET_MIX_SSE_I387)
13466 gen_truncxf = gen_truncxf<mode>2;
13468 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13470 emit_insn (gen_truncxf (operands[0], op1));
13474 (define_insn "fprem1xf4_i387"
13475 [(set (match_operand:XF 0 "register_operand" "=f")
13476 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13477 (match_operand:XF 3 "register_operand" "1")]
13479 (set (match_operand:XF 1 "register_operand" "=u")
13480 (unspec:XF [(match_dup 2) (match_dup 3)]
13482 (set (reg:CCFP FPSR_REG)
13483 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13485 "TARGET_USE_FANCY_MATH_387"
13487 [(set_attr "type" "fpspc")
13488 (set_attr "mode" "XF")])
13490 (define_expand "remainderxf3"
13491 [(use (match_operand:XF 0 "register_operand" ""))
13492 (use (match_operand:XF 1 "general_operand" ""))
13493 (use (match_operand:XF 2 "general_operand" ""))]
13494 "TARGET_USE_FANCY_MATH_387"
13496 rtx label = gen_label_rtx ();
13498 rtx op1 = gen_reg_rtx (XFmode);
13499 rtx op2 = gen_reg_rtx (XFmode);
13501 emit_move_insn (op2, operands[2]);
13502 emit_move_insn (op1, operands[1]);
13504 emit_label (label);
13505 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13506 ix86_emit_fp_unordered_jump (label);
13507 LABEL_NUSES (label) = 1;
13509 emit_move_insn (operands[0], op1);
13513 (define_expand "remainder<mode>3"
13514 [(use (match_operand:MODEF 0 "register_operand" ""))
13515 (use (match_operand:MODEF 1 "general_operand" ""))
13516 (use (match_operand:MODEF 2 "general_operand" ""))]
13517 "TARGET_USE_FANCY_MATH_387"
13519 rtx (*gen_truncxf) (rtx, rtx);
13521 rtx label = gen_label_rtx ();
13523 rtx op1 = gen_reg_rtx (XFmode);
13524 rtx op2 = gen_reg_rtx (XFmode);
13526 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13527 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13529 emit_label (label);
13531 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13532 ix86_emit_fp_unordered_jump (label);
13533 LABEL_NUSES (label) = 1;
13535 /* Truncate the result properly for strict SSE math. */
13536 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13537 && !TARGET_MIX_SSE_I387)
13538 gen_truncxf = gen_truncxf<mode>2;
13540 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13542 emit_insn (gen_truncxf (operands[0], op1));
13546 (define_insn "*sinxf2_i387"
13547 [(set (match_operand:XF 0 "register_operand" "=f")
13548 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13549 "TARGET_USE_FANCY_MATH_387
13550 && flag_unsafe_math_optimizations"
13552 [(set_attr "type" "fpspc")
13553 (set_attr "mode" "XF")])
13555 (define_insn "*sin_extend<mode>xf2_i387"
13556 [(set (match_operand:XF 0 "register_operand" "=f")
13557 (unspec:XF [(float_extend:XF
13558 (match_operand:MODEF 1 "register_operand" "0"))]
13560 "TARGET_USE_FANCY_MATH_387
13561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13562 || TARGET_MIX_SSE_I387)
13563 && flag_unsafe_math_optimizations"
13565 [(set_attr "type" "fpspc")
13566 (set_attr "mode" "XF")])
13568 (define_insn "*cosxf2_i387"
13569 [(set (match_operand:XF 0 "register_operand" "=f")
13570 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13571 "TARGET_USE_FANCY_MATH_387
13572 && flag_unsafe_math_optimizations"
13574 [(set_attr "type" "fpspc")
13575 (set_attr "mode" "XF")])
13577 (define_insn "*cos_extend<mode>xf2_i387"
13578 [(set (match_operand:XF 0 "register_operand" "=f")
13579 (unspec:XF [(float_extend:XF
13580 (match_operand:MODEF 1 "register_operand" "0"))]
13582 "TARGET_USE_FANCY_MATH_387
13583 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13584 || TARGET_MIX_SSE_I387)
13585 && flag_unsafe_math_optimizations"
13587 [(set_attr "type" "fpspc")
13588 (set_attr "mode" "XF")])
13590 ;; When sincos pattern is defined, sin and cos builtin functions will be
13591 ;; expanded to sincos pattern with one of its outputs left unused.
13592 ;; CSE pass will figure out if two sincos patterns can be combined,
13593 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13594 ;; depending on the unused output.
13596 (define_insn "sincosxf3"
13597 [(set (match_operand:XF 0 "register_operand" "=f")
13598 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13599 UNSPEC_SINCOS_COS))
13600 (set (match_operand:XF 1 "register_operand" "=u")
13601 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13602 "TARGET_USE_FANCY_MATH_387
13603 && flag_unsafe_math_optimizations"
13605 [(set_attr "type" "fpspc")
13606 (set_attr "mode" "XF")])
13609 [(set (match_operand:XF 0 "register_operand" "")
13610 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13611 UNSPEC_SINCOS_COS))
13612 (set (match_operand:XF 1 "register_operand" "")
13613 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13614 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13615 && !(reload_completed || reload_in_progress)"
13616 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13619 [(set (match_operand:XF 0 "register_operand" "")
13620 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13621 UNSPEC_SINCOS_COS))
13622 (set (match_operand:XF 1 "register_operand" "")
13623 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13624 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13625 && !(reload_completed || reload_in_progress)"
13626 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13628 (define_insn "sincos_extend<mode>xf3_i387"
13629 [(set (match_operand:XF 0 "register_operand" "=f")
13630 (unspec:XF [(float_extend:XF
13631 (match_operand:MODEF 2 "register_operand" "0"))]
13632 UNSPEC_SINCOS_COS))
13633 (set (match_operand:XF 1 "register_operand" "=u")
13634 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13635 "TARGET_USE_FANCY_MATH_387
13636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13637 || TARGET_MIX_SSE_I387)
13638 && flag_unsafe_math_optimizations"
13640 [(set_attr "type" "fpspc")
13641 (set_attr "mode" "XF")])
13644 [(set (match_operand:XF 0 "register_operand" "")
13645 (unspec:XF [(float_extend:XF
13646 (match_operand:MODEF 2 "register_operand" ""))]
13647 UNSPEC_SINCOS_COS))
13648 (set (match_operand:XF 1 "register_operand" "")
13649 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13650 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13651 && !(reload_completed || reload_in_progress)"
13652 [(set (match_dup 1)
13653 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13656 [(set (match_operand:XF 0 "register_operand" "")
13657 (unspec:XF [(float_extend:XF
13658 (match_operand:MODEF 2 "register_operand" ""))]
13659 UNSPEC_SINCOS_COS))
13660 (set (match_operand:XF 1 "register_operand" "")
13661 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13662 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13663 && !(reload_completed || reload_in_progress)"
13664 [(set (match_dup 0)
13665 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13667 (define_expand "sincos<mode>3"
13668 [(use (match_operand:MODEF 0 "register_operand" ""))
13669 (use (match_operand:MODEF 1 "register_operand" ""))
13670 (use (match_operand:MODEF 2 "register_operand" ""))]
13671 "TARGET_USE_FANCY_MATH_387
13672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13673 || TARGET_MIX_SSE_I387)
13674 && flag_unsafe_math_optimizations"
13676 rtx op0 = gen_reg_rtx (XFmode);
13677 rtx op1 = gen_reg_rtx (XFmode);
13679 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13680 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13685 (define_insn "fptanxf4_i387"
13686 [(set (match_operand:XF 0 "register_operand" "=f")
13687 (match_operand:XF 3 "const_double_operand" "F"))
13688 (set (match_operand:XF 1 "register_operand" "=u")
13689 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13691 "TARGET_USE_FANCY_MATH_387
13692 && flag_unsafe_math_optimizations
13693 && standard_80387_constant_p (operands[3]) == 2"
13695 [(set_attr "type" "fpspc")
13696 (set_attr "mode" "XF")])
13698 (define_insn "fptan_extend<mode>xf4_i387"
13699 [(set (match_operand:MODEF 0 "register_operand" "=f")
13700 (match_operand:MODEF 3 "const_double_operand" "F"))
13701 (set (match_operand:XF 1 "register_operand" "=u")
13702 (unspec:XF [(float_extend:XF
13703 (match_operand:MODEF 2 "register_operand" "0"))]
13705 "TARGET_USE_FANCY_MATH_387
13706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13707 || TARGET_MIX_SSE_I387)
13708 && flag_unsafe_math_optimizations
13709 && standard_80387_constant_p (operands[3]) == 2"
13711 [(set_attr "type" "fpspc")
13712 (set_attr "mode" "XF")])
13714 (define_expand "tanxf2"
13715 [(use (match_operand:XF 0 "register_operand" ""))
13716 (use (match_operand:XF 1 "register_operand" ""))]
13717 "TARGET_USE_FANCY_MATH_387
13718 && flag_unsafe_math_optimizations"
13720 rtx one = gen_reg_rtx (XFmode);
13721 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13723 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13727 (define_expand "tan<mode>2"
13728 [(use (match_operand:MODEF 0 "register_operand" ""))
13729 (use (match_operand:MODEF 1 "register_operand" ""))]
13730 "TARGET_USE_FANCY_MATH_387
13731 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13732 || TARGET_MIX_SSE_I387)
13733 && flag_unsafe_math_optimizations"
13735 rtx op0 = gen_reg_rtx (XFmode);
13737 rtx one = gen_reg_rtx (<MODE>mode);
13738 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13740 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13741 operands[1], op2));
13742 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13746 (define_insn "*fpatanxf3_i387"
13747 [(set (match_operand:XF 0 "register_operand" "=f")
13748 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13749 (match_operand:XF 2 "register_operand" "u")]
13751 (clobber (match_scratch:XF 3 "=2"))]
13752 "TARGET_USE_FANCY_MATH_387
13753 && flag_unsafe_math_optimizations"
13755 [(set_attr "type" "fpspc")
13756 (set_attr "mode" "XF")])
13758 (define_insn "fpatan_extend<mode>xf3_i387"
13759 [(set (match_operand:XF 0 "register_operand" "=f")
13760 (unspec:XF [(float_extend:XF
13761 (match_operand:MODEF 1 "register_operand" "0"))
13763 (match_operand:MODEF 2 "register_operand" "u"))]
13765 (clobber (match_scratch:XF 3 "=2"))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13768 || TARGET_MIX_SSE_I387)
13769 && flag_unsafe_math_optimizations"
13771 [(set_attr "type" "fpspc")
13772 (set_attr "mode" "XF")])
13774 (define_expand "atan2xf3"
13775 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13776 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13777 (match_operand:XF 1 "register_operand" "")]
13779 (clobber (match_scratch:XF 3 ""))])]
13780 "TARGET_USE_FANCY_MATH_387
13781 && flag_unsafe_math_optimizations")
13783 (define_expand "atan2<mode>3"
13784 [(use (match_operand:MODEF 0 "register_operand" ""))
13785 (use (match_operand:MODEF 1 "register_operand" ""))
13786 (use (match_operand:MODEF 2 "register_operand" ""))]
13787 "TARGET_USE_FANCY_MATH_387
13788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13789 || TARGET_MIX_SSE_I387)
13790 && flag_unsafe_math_optimizations"
13792 rtx op0 = gen_reg_rtx (XFmode);
13794 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13795 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13799 (define_expand "atanxf2"
13800 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13801 (unspec:XF [(match_dup 2)
13802 (match_operand:XF 1 "register_operand" "")]
13804 (clobber (match_scratch:XF 3 ""))])]
13805 "TARGET_USE_FANCY_MATH_387
13806 && flag_unsafe_math_optimizations"
13808 operands[2] = gen_reg_rtx (XFmode);
13809 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13812 (define_expand "atan<mode>2"
13813 [(use (match_operand:MODEF 0 "register_operand" ""))
13814 (use (match_operand:MODEF 1 "register_operand" ""))]
13815 "TARGET_USE_FANCY_MATH_387
13816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13817 || TARGET_MIX_SSE_I387)
13818 && flag_unsafe_math_optimizations"
13820 rtx op0 = gen_reg_rtx (XFmode);
13822 rtx op2 = gen_reg_rtx (<MODE>mode);
13823 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13825 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13826 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13830 (define_expand "asinxf2"
13831 [(set (match_dup 2)
13832 (mult:XF (match_operand:XF 1 "register_operand" "")
13834 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13835 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13836 (parallel [(set (match_operand:XF 0 "register_operand" "")
13837 (unspec:XF [(match_dup 5) (match_dup 1)]
13839 (clobber (match_scratch:XF 6 ""))])]
13840 "TARGET_USE_FANCY_MATH_387
13841 && flag_unsafe_math_optimizations"
13845 if (optimize_insn_for_size_p ())
13848 for (i = 2; i < 6; i++)
13849 operands[i] = gen_reg_rtx (XFmode);
13851 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13854 (define_expand "asin<mode>2"
13855 [(use (match_operand:MODEF 0 "register_operand" ""))
13856 (use (match_operand:MODEF 1 "general_operand" ""))]
13857 "TARGET_USE_FANCY_MATH_387
13858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13859 || TARGET_MIX_SSE_I387)
13860 && flag_unsafe_math_optimizations"
13862 rtx op0 = gen_reg_rtx (XFmode);
13863 rtx op1 = gen_reg_rtx (XFmode);
13865 if (optimize_insn_for_size_p ())
13868 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13869 emit_insn (gen_asinxf2 (op0, op1));
13870 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13874 (define_expand "acosxf2"
13875 [(set (match_dup 2)
13876 (mult:XF (match_operand:XF 1 "register_operand" "")
13878 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13879 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13880 (parallel [(set (match_operand:XF 0 "register_operand" "")
13881 (unspec:XF [(match_dup 1) (match_dup 5)]
13883 (clobber (match_scratch:XF 6 ""))])]
13884 "TARGET_USE_FANCY_MATH_387
13885 && flag_unsafe_math_optimizations"
13889 if (optimize_insn_for_size_p ())
13892 for (i = 2; i < 6; i++)
13893 operands[i] = gen_reg_rtx (XFmode);
13895 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13898 (define_expand "acos<mode>2"
13899 [(use (match_operand:MODEF 0 "register_operand" ""))
13900 (use (match_operand:MODEF 1 "general_operand" ""))]
13901 "TARGET_USE_FANCY_MATH_387
13902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13903 || TARGET_MIX_SSE_I387)
13904 && flag_unsafe_math_optimizations"
13906 rtx op0 = gen_reg_rtx (XFmode);
13907 rtx op1 = gen_reg_rtx (XFmode);
13909 if (optimize_insn_for_size_p ())
13912 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13913 emit_insn (gen_acosxf2 (op0, op1));
13914 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13918 (define_insn "fyl2xxf3_i387"
13919 [(set (match_operand:XF 0 "register_operand" "=f")
13920 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13921 (match_operand:XF 2 "register_operand" "u")]
13923 (clobber (match_scratch:XF 3 "=2"))]
13924 "TARGET_USE_FANCY_MATH_387
13925 && flag_unsafe_math_optimizations"
13927 [(set_attr "type" "fpspc")
13928 (set_attr "mode" "XF")])
13930 (define_insn "fyl2x_extend<mode>xf3_i387"
13931 [(set (match_operand:XF 0 "register_operand" "=f")
13932 (unspec:XF [(float_extend:XF
13933 (match_operand:MODEF 1 "register_operand" "0"))
13934 (match_operand:XF 2 "register_operand" "u")]
13936 (clobber (match_scratch:XF 3 "=2"))]
13937 "TARGET_USE_FANCY_MATH_387
13938 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13939 || TARGET_MIX_SSE_I387)
13940 && flag_unsafe_math_optimizations"
13942 [(set_attr "type" "fpspc")
13943 (set_attr "mode" "XF")])
13945 (define_expand "logxf2"
13946 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13947 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13948 (match_dup 2)] UNSPEC_FYL2X))
13949 (clobber (match_scratch:XF 3 ""))])]
13950 "TARGET_USE_FANCY_MATH_387
13951 && flag_unsafe_math_optimizations"
13953 operands[2] = gen_reg_rtx (XFmode);
13954 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13957 (define_expand "log<mode>2"
13958 [(use (match_operand:MODEF 0 "register_operand" ""))
13959 (use (match_operand:MODEF 1 "register_operand" ""))]
13960 "TARGET_USE_FANCY_MATH_387
13961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13962 || TARGET_MIX_SSE_I387)
13963 && flag_unsafe_math_optimizations"
13965 rtx op0 = gen_reg_rtx (XFmode);
13967 rtx op2 = gen_reg_rtx (XFmode);
13968 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13970 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13971 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13975 (define_expand "log10xf2"
13976 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13977 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13978 (match_dup 2)] UNSPEC_FYL2X))
13979 (clobber (match_scratch:XF 3 ""))])]
13980 "TARGET_USE_FANCY_MATH_387
13981 && flag_unsafe_math_optimizations"
13983 operands[2] = gen_reg_rtx (XFmode);
13984 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13987 (define_expand "log10<mode>2"
13988 [(use (match_operand:MODEF 0 "register_operand" ""))
13989 (use (match_operand:MODEF 1 "register_operand" ""))]
13990 "TARGET_USE_FANCY_MATH_387
13991 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13992 || TARGET_MIX_SSE_I387)
13993 && flag_unsafe_math_optimizations"
13995 rtx op0 = gen_reg_rtx (XFmode);
13997 rtx op2 = gen_reg_rtx (XFmode);
13998 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14000 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14001 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14005 (define_expand "log2xf2"
14006 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14007 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14008 (match_dup 2)] UNSPEC_FYL2X))
14009 (clobber (match_scratch:XF 3 ""))])]
14010 "TARGET_USE_FANCY_MATH_387
14011 && flag_unsafe_math_optimizations"
14013 operands[2] = gen_reg_rtx (XFmode);
14014 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14017 (define_expand "log2<mode>2"
14018 [(use (match_operand:MODEF 0 "register_operand" ""))
14019 (use (match_operand:MODEF 1 "register_operand" ""))]
14020 "TARGET_USE_FANCY_MATH_387
14021 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14022 || TARGET_MIX_SSE_I387)
14023 && flag_unsafe_math_optimizations"
14025 rtx op0 = gen_reg_rtx (XFmode);
14027 rtx op2 = gen_reg_rtx (XFmode);
14028 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14030 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14031 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14035 (define_insn "fyl2xp1xf3_i387"
14036 [(set (match_operand:XF 0 "register_operand" "=f")
14037 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14038 (match_operand:XF 2 "register_operand" "u")]
14040 (clobber (match_scratch:XF 3 "=2"))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14044 [(set_attr "type" "fpspc")
14045 (set_attr "mode" "XF")])
14047 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14048 [(set (match_operand:XF 0 "register_operand" "=f")
14049 (unspec:XF [(float_extend:XF
14050 (match_operand:MODEF 1 "register_operand" "0"))
14051 (match_operand:XF 2 "register_operand" "u")]
14053 (clobber (match_scratch:XF 3 "=2"))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14059 [(set_attr "type" "fpspc")
14060 (set_attr "mode" "XF")])
14062 (define_expand "log1pxf2"
14063 [(use (match_operand:XF 0 "register_operand" ""))
14064 (use (match_operand:XF 1 "register_operand" ""))]
14065 "TARGET_USE_FANCY_MATH_387
14066 && flag_unsafe_math_optimizations"
14068 if (optimize_insn_for_size_p ())
14071 ix86_emit_i387_log1p (operands[0], operands[1]);
14075 (define_expand "log1p<mode>2"
14076 [(use (match_operand:MODEF 0 "register_operand" ""))
14077 (use (match_operand:MODEF 1 "register_operand" ""))]
14078 "TARGET_USE_FANCY_MATH_387
14079 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14080 || TARGET_MIX_SSE_I387)
14081 && flag_unsafe_math_optimizations"
14085 if (optimize_insn_for_size_p ())
14088 op0 = gen_reg_rtx (XFmode);
14090 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14092 ix86_emit_i387_log1p (op0, operands[1]);
14093 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14097 (define_insn "fxtractxf3_i387"
14098 [(set (match_operand:XF 0 "register_operand" "=f")
14099 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14100 UNSPEC_XTRACT_FRACT))
14101 (set (match_operand:XF 1 "register_operand" "=u")
14102 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14103 "TARGET_USE_FANCY_MATH_387
14104 && flag_unsafe_math_optimizations"
14106 [(set_attr "type" "fpspc")
14107 (set_attr "mode" "XF")])
14109 (define_insn "fxtract_extend<mode>xf3_i387"
14110 [(set (match_operand:XF 0 "register_operand" "=f")
14111 (unspec:XF [(float_extend:XF
14112 (match_operand:MODEF 2 "register_operand" "0"))]
14113 UNSPEC_XTRACT_FRACT))
14114 (set (match_operand:XF 1 "register_operand" "=u")
14115 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118 || TARGET_MIX_SSE_I387)
14119 && flag_unsafe_math_optimizations"
14121 [(set_attr "type" "fpspc")
14122 (set_attr "mode" "XF")])
14124 (define_expand "logbxf2"
14125 [(parallel [(set (match_dup 2)
14126 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14127 UNSPEC_XTRACT_FRACT))
14128 (set (match_operand:XF 0 "register_operand" "")
14129 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14130 "TARGET_USE_FANCY_MATH_387
14131 && flag_unsafe_math_optimizations"
14132 "operands[2] = gen_reg_rtx (XFmode);")
14134 (define_expand "logb<mode>2"
14135 [(use (match_operand:MODEF 0 "register_operand" ""))
14136 (use (match_operand:MODEF 1 "register_operand" ""))]
14137 "TARGET_USE_FANCY_MATH_387
14138 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14139 || TARGET_MIX_SSE_I387)
14140 && flag_unsafe_math_optimizations"
14142 rtx op0 = gen_reg_rtx (XFmode);
14143 rtx op1 = gen_reg_rtx (XFmode);
14145 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14150 (define_expand "ilogbxf2"
14151 [(use (match_operand:SI 0 "register_operand" ""))
14152 (use (match_operand:XF 1 "register_operand" ""))]
14153 "TARGET_USE_FANCY_MATH_387
14154 && flag_unsafe_math_optimizations"
14158 if (optimize_insn_for_size_p ())
14161 op0 = gen_reg_rtx (XFmode);
14162 op1 = gen_reg_rtx (XFmode);
14164 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14165 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14169 (define_expand "ilogb<mode>2"
14170 [(use (match_operand:SI 0 "register_operand" ""))
14171 (use (match_operand:MODEF 1 "register_operand" ""))]
14172 "TARGET_USE_FANCY_MATH_387
14173 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14174 || TARGET_MIX_SSE_I387)
14175 && flag_unsafe_math_optimizations"
14179 if (optimize_insn_for_size_p ())
14182 op0 = gen_reg_rtx (XFmode);
14183 op1 = gen_reg_rtx (XFmode);
14185 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14186 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14190 (define_insn "*f2xm1xf2_i387"
14191 [(set (match_operand:XF 0 "register_operand" "=f")
14192 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations"
14197 [(set_attr "type" "fpspc")
14198 (set_attr "mode" "XF")])
14200 (define_insn "*fscalexf4_i387"
14201 [(set (match_operand:XF 0 "register_operand" "=f")
14202 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14203 (match_operand:XF 3 "register_operand" "1")]
14204 UNSPEC_FSCALE_FRACT))
14205 (set (match_operand:XF 1 "register_operand" "=u")
14206 (unspec:XF [(match_dup 2) (match_dup 3)]
14207 UNSPEC_FSCALE_EXP))]
14208 "TARGET_USE_FANCY_MATH_387
14209 && flag_unsafe_math_optimizations"
14211 [(set_attr "type" "fpspc")
14212 (set_attr "mode" "XF")])
14214 (define_expand "expNcorexf3"
14215 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14216 (match_operand:XF 2 "register_operand" "")))
14217 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14218 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14219 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14220 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14221 (parallel [(set (match_operand:XF 0 "register_operand" "")
14222 (unspec:XF [(match_dup 8) (match_dup 4)]
14223 UNSPEC_FSCALE_FRACT))
14225 (unspec:XF [(match_dup 8) (match_dup 4)]
14226 UNSPEC_FSCALE_EXP))])]
14227 "TARGET_USE_FANCY_MATH_387
14228 && flag_unsafe_math_optimizations"
14232 if (optimize_insn_for_size_p ())
14235 for (i = 3; i < 10; i++)
14236 operands[i] = gen_reg_rtx (XFmode);
14238 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14241 (define_expand "expxf2"
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 (5)); /* fldl2e */
14255 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14259 (define_expand "exp<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_expxf2 (op0, op1));
14277 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14281 (define_expand "exp10xf2"
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, standard_80387_constant_rtx (6)); /* fldl2t */
14295 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14299 (define_expand "exp10<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_exp10xf2 (op0, op1));
14317 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14321 (define_expand "exp2xf2"
14322 [(use (match_operand:XF 0 "register_operand" ""))
14323 (use (match_operand:XF 1 "register_operand" ""))]
14324 "TARGET_USE_FANCY_MATH_387
14325 && flag_unsafe_math_optimizations"
14329 if (optimize_insn_for_size_p ())
14332 op2 = gen_reg_rtx (XFmode);
14333 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14335 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14339 (define_expand "exp2<mode>2"
14340 [(use (match_operand:MODEF 0 "register_operand" ""))
14341 (use (match_operand:MODEF 1 "general_operand" ""))]
14342 "TARGET_USE_FANCY_MATH_387
14343 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14344 || TARGET_MIX_SSE_I387)
14345 && flag_unsafe_math_optimizations"
14349 if (optimize_insn_for_size_p ())
14352 op0 = gen_reg_rtx (XFmode);
14353 op1 = gen_reg_rtx (XFmode);
14355 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14356 emit_insn (gen_exp2xf2 (op0, op1));
14357 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14361 (define_expand "expm1xf2"
14362 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14364 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14365 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14366 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14367 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14368 (parallel [(set (match_dup 7)
14369 (unspec:XF [(match_dup 6) (match_dup 4)]
14370 UNSPEC_FSCALE_FRACT))
14372 (unspec:XF [(match_dup 6) (match_dup 4)]
14373 UNSPEC_FSCALE_EXP))])
14374 (parallel [(set (match_dup 10)
14375 (unspec:XF [(match_dup 9) (match_dup 8)]
14376 UNSPEC_FSCALE_FRACT))
14377 (set (match_dup 11)
14378 (unspec:XF [(match_dup 9) (match_dup 8)]
14379 UNSPEC_FSCALE_EXP))])
14380 (set (match_dup 12) (minus:XF (match_dup 10)
14381 (float_extend:XF (match_dup 13))))
14382 (set (match_operand:XF 0 "register_operand" "")
14383 (plus:XF (match_dup 12) (match_dup 7)))]
14384 "TARGET_USE_FANCY_MATH_387
14385 && flag_unsafe_math_optimizations"
14389 if (optimize_insn_for_size_p ())
14392 for (i = 2; i < 13; i++)
14393 operands[i] = gen_reg_rtx (XFmode);
14396 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14398 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14401 (define_expand "expm1<mode>2"
14402 [(use (match_operand:MODEF 0 "register_operand" ""))
14403 (use (match_operand:MODEF 1 "general_operand" ""))]
14404 "TARGET_USE_FANCY_MATH_387
14405 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14406 || TARGET_MIX_SSE_I387)
14407 && flag_unsafe_math_optimizations"
14411 if (optimize_insn_for_size_p ())
14414 op0 = gen_reg_rtx (XFmode);
14415 op1 = gen_reg_rtx (XFmode);
14417 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14418 emit_insn (gen_expm1xf2 (op0, op1));
14419 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14423 (define_expand "ldexpxf3"
14424 [(set (match_dup 3)
14425 (float:XF (match_operand:SI 2 "register_operand" "")))
14426 (parallel [(set (match_operand:XF 0 " register_operand" "")
14427 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14429 UNSPEC_FSCALE_FRACT))
14431 (unspec:XF [(match_dup 1) (match_dup 3)]
14432 UNSPEC_FSCALE_EXP))])]
14433 "TARGET_USE_FANCY_MATH_387
14434 && flag_unsafe_math_optimizations"
14436 if (optimize_insn_for_size_p ())
14439 operands[3] = gen_reg_rtx (XFmode);
14440 operands[4] = gen_reg_rtx (XFmode);
14443 (define_expand "ldexp<mode>3"
14444 [(use (match_operand:MODEF 0 "register_operand" ""))
14445 (use (match_operand:MODEF 1 "general_operand" ""))
14446 (use (match_operand:SI 2 "register_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);
14460 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14461 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14462 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14466 (define_expand "scalbxf3"
14467 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14468 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14469 (match_operand:XF 2 "register_operand" "")]
14470 UNSPEC_FSCALE_FRACT))
14472 (unspec:XF [(match_dup 1) (match_dup 2)]
14473 UNSPEC_FSCALE_EXP))])]
14474 "TARGET_USE_FANCY_MATH_387
14475 && flag_unsafe_math_optimizations"
14477 if (optimize_insn_for_size_p ())
14480 operands[3] = gen_reg_rtx (XFmode);
14483 (define_expand "scalb<mode>3"
14484 [(use (match_operand:MODEF 0 "register_operand" ""))
14485 (use (match_operand:MODEF 1 "general_operand" ""))
14486 (use (match_operand:MODEF 2 "general_operand" ""))]
14487 "TARGET_USE_FANCY_MATH_387
14488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14489 || TARGET_MIX_SSE_I387)
14490 && flag_unsafe_math_optimizations"
14494 if (optimize_insn_for_size_p ())
14497 op0 = gen_reg_rtx (XFmode);
14498 op1 = gen_reg_rtx (XFmode);
14499 op2 = gen_reg_rtx (XFmode);
14501 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14502 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14503 emit_insn (gen_scalbxf3 (op0, op1, op2));
14504 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14508 (define_expand "significandxf2"
14509 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14510 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14511 UNSPEC_XTRACT_FRACT))
14513 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14514 "TARGET_USE_FANCY_MATH_387
14515 && flag_unsafe_math_optimizations"
14516 "operands[2] = gen_reg_rtx (XFmode);")
14518 (define_expand "significand<mode>2"
14519 [(use (match_operand:MODEF 0 "register_operand" ""))
14520 (use (match_operand:MODEF 1 "register_operand" ""))]
14521 "TARGET_USE_FANCY_MATH_387
14522 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14523 || TARGET_MIX_SSE_I387)
14524 && flag_unsafe_math_optimizations"
14526 rtx op0 = gen_reg_rtx (XFmode);
14527 rtx op1 = gen_reg_rtx (XFmode);
14529 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14530 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14535 (define_insn "sse4_1_round<mode>2"
14536 [(set (match_operand:MODEF 0 "register_operand" "=x")
14537 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14538 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14541 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14542 [(set_attr "type" "ssecvt")
14543 (set_attr "prefix_extra" "1")
14544 (set_attr "prefix" "maybe_vex")
14545 (set_attr "mode" "<MODE>")])
14547 (define_insn "rintxf2"
14548 [(set (match_operand:XF 0 "register_operand" "=f")
14549 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14551 "TARGET_USE_FANCY_MATH_387
14552 && flag_unsafe_math_optimizations"
14554 [(set_attr "type" "fpspc")
14555 (set_attr "mode" "XF")])
14557 (define_expand "rint<mode>2"
14558 [(use (match_operand:MODEF 0 "register_operand" ""))
14559 (use (match_operand:MODEF 1 "register_operand" ""))]
14560 "(TARGET_USE_FANCY_MATH_387
14561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14562 || TARGET_MIX_SSE_I387)
14563 && flag_unsafe_math_optimizations)
14564 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14565 && !flag_trapping_math)"
14567 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14568 && !flag_trapping_math)
14570 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14573 emit_insn (gen_sse4_1_round<mode>2
14574 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14576 ix86_expand_rint (operand0, operand1);
14580 rtx op0 = gen_reg_rtx (XFmode);
14581 rtx op1 = gen_reg_rtx (XFmode);
14583 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14584 emit_insn (gen_rintxf2 (op0, op1));
14586 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14591 (define_expand "round<mode>2"
14592 [(match_operand:MODEF 0 "register_operand" "")
14593 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14594 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14595 && !flag_trapping_math && !flag_rounding_math"
14597 if (optimize_insn_for_size_p ())
14599 if (TARGET_64BIT || (<MODE>mode != DFmode))
14600 ix86_expand_round (operand0, operand1);
14602 ix86_expand_rounddf_32 (operand0, operand1);
14606 (define_insn_and_split "*fistdi2_1"
14607 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14608 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14610 "TARGET_USE_FANCY_MATH_387
14611 && can_create_pseudo_p ()"
14616 if (memory_operand (operands[0], VOIDmode))
14617 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14620 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14621 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14626 [(set_attr "type" "fpspc")
14627 (set_attr "mode" "DI")])
14629 (define_insn "fistdi2"
14630 [(set (match_operand:DI 0 "memory_operand" "=m")
14631 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14633 (clobber (match_scratch:XF 2 "=&1f"))]
14634 "TARGET_USE_FANCY_MATH_387"
14635 "* return output_fix_trunc (insn, operands, 0);"
14636 [(set_attr "type" "fpspc")
14637 (set_attr "mode" "DI")])
14639 (define_insn "fistdi2_with_temp"
14640 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14641 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14643 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14644 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14645 "TARGET_USE_FANCY_MATH_387"
14647 [(set_attr "type" "fpspc")
14648 (set_attr "mode" "DI")])
14651 [(set (match_operand:DI 0 "register_operand" "")
14652 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14654 (clobber (match_operand:DI 2 "memory_operand" ""))
14655 (clobber (match_scratch 3 ""))]
14657 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14658 (clobber (match_dup 3))])
14659 (set (match_dup 0) (match_dup 2))])
14662 [(set (match_operand:DI 0 "memory_operand" "")
14663 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14665 (clobber (match_operand:DI 2 "memory_operand" ""))
14666 (clobber (match_scratch 3 ""))]
14668 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14669 (clobber (match_dup 3))])])
14671 (define_insn_and_split "*fist<mode>2_1"
14672 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14673 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14675 "TARGET_USE_FANCY_MATH_387
14676 && can_create_pseudo_p ()"
14681 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14682 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14686 [(set_attr "type" "fpspc")
14687 (set_attr "mode" "<MODE>")])
14689 (define_insn "fist<mode>2"
14690 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14691 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14693 "TARGET_USE_FANCY_MATH_387"
14694 "* return output_fix_trunc (insn, operands, 0);"
14695 [(set_attr "type" "fpspc")
14696 (set_attr "mode" "<MODE>")])
14698 (define_insn "fist<mode>2_with_temp"
14699 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14700 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14702 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14703 "TARGET_USE_FANCY_MATH_387"
14705 [(set_attr "type" "fpspc")
14706 (set_attr "mode" "<MODE>")])
14709 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14710 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14712 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14714 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14715 (set (match_dup 0) (match_dup 2))])
14718 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14719 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14721 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14723 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14725 (define_expand "lrintxf<mode>2"
14726 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14727 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14729 "TARGET_USE_FANCY_MATH_387")
14731 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14732 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14733 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14734 UNSPEC_FIX_NOTRUNC))]
14735 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14736 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14738 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14739 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14740 (match_operand:MODEF 1 "register_operand" "")]
14741 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14742 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14743 && !flag_trapping_math && !flag_rounding_math"
14745 if (optimize_insn_for_size_p ())
14747 ix86_expand_lround (operand0, operand1);
14751 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14752 (define_insn_and_split "frndintxf2_floor"
14753 [(set (match_operand:XF 0 "register_operand" "")
14754 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14755 UNSPEC_FRNDINT_FLOOR))
14756 (clobber (reg:CC FLAGS_REG))]
14757 "TARGET_USE_FANCY_MATH_387
14758 && flag_unsafe_math_optimizations
14759 && can_create_pseudo_p ()"
14764 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14766 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14767 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14769 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14770 operands[2], operands[3]));
14773 [(set_attr "type" "frndint")
14774 (set_attr "i387_cw" "floor")
14775 (set_attr "mode" "XF")])
14777 (define_insn "frndintxf2_floor_i387"
14778 [(set (match_operand:XF 0 "register_operand" "=f")
14779 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14780 UNSPEC_FRNDINT_FLOOR))
14781 (use (match_operand:HI 2 "memory_operand" "m"))
14782 (use (match_operand:HI 3 "memory_operand" "m"))]
14783 "TARGET_USE_FANCY_MATH_387
14784 && flag_unsafe_math_optimizations"
14785 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14786 [(set_attr "type" "frndint")
14787 (set_attr "i387_cw" "floor")
14788 (set_attr "mode" "XF")])
14790 (define_expand "floorxf2"
14791 [(use (match_operand:XF 0 "register_operand" ""))
14792 (use (match_operand:XF 1 "register_operand" ""))]
14793 "TARGET_USE_FANCY_MATH_387
14794 && flag_unsafe_math_optimizations"
14796 if (optimize_insn_for_size_p ())
14798 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14802 (define_expand "floor<mode>2"
14803 [(use (match_operand:MODEF 0 "register_operand" ""))
14804 (use (match_operand:MODEF 1 "register_operand" ""))]
14805 "(TARGET_USE_FANCY_MATH_387
14806 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14807 || TARGET_MIX_SSE_I387)
14808 && flag_unsafe_math_optimizations)
14809 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14810 && !flag_trapping_math)"
14812 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14813 && !flag_trapping_math
14814 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14816 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14819 emit_insn (gen_sse4_1_round<mode>2
14820 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14821 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14822 ix86_expand_floorceil (operand0, operand1, true);
14824 ix86_expand_floorceildf_32 (operand0, operand1, true);
14830 if (optimize_insn_for_size_p ())
14833 op0 = gen_reg_rtx (XFmode);
14834 op1 = gen_reg_rtx (XFmode);
14835 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14836 emit_insn (gen_frndintxf2_floor (op0, op1));
14838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14843 (define_insn_and_split "*fist<mode>2_floor_1"
14844 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14845 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14846 UNSPEC_FIST_FLOOR))
14847 (clobber (reg:CC FLAGS_REG))]
14848 "TARGET_USE_FANCY_MATH_387
14849 && flag_unsafe_math_optimizations
14850 && can_create_pseudo_p ()"
14855 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14857 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14858 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14859 if (memory_operand (operands[0], VOIDmode))
14860 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14861 operands[2], operands[3]));
14864 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14865 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14866 operands[2], operands[3],
14871 [(set_attr "type" "fistp")
14872 (set_attr "i387_cw" "floor")
14873 (set_attr "mode" "<MODE>")])
14875 (define_insn "fistdi2_floor"
14876 [(set (match_operand:DI 0 "memory_operand" "=m")
14877 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14878 UNSPEC_FIST_FLOOR))
14879 (use (match_operand:HI 2 "memory_operand" "m"))
14880 (use (match_operand:HI 3 "memory_operand" "m"))
14881 (clobber (match_scratch:XF 4 "=&1f"))]
14882 "TARGET_USE_FANCY_MATH_387
14883 && flag_unsafe_math_optimizations"
14884 "* return output_fix_trunc (insn, operands, 0);"
14885 [(set_attr "type" "fistp")
14886 (set_attr "i387_cw" "floor")
14887 (set_attr "mode" "DI")])
14889 (define_insn "fistdi2_floor_with_temp"
14890 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14891 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14892 UNSPEC_FIST_FLOOR))
14893 (use (match_operand:HI 2 "memory_operand" "m,m"))
14894 (use (match_operand:HI 3 "memory_operand" "m,m"))
14895 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14896 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14897 "TARGET_USE_FANCY_MATH_387
14898 && flag_unsafe_math_optimizations"
14900 [(set_attr "type" "fistp")
14901 (set_attr "i387_cw" "floor")
14902 (set_attr "mode" "DI")])
14905 [(set (match_operand:DI 0 "register_operand" "")
14906 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14907 UNSPEC_FIST_FLOOR))
14908 (use (match_operand:HI 2 "memory_operand" ""))
14909 (use (match_operand:HI 3 "memory_operand" ""))
14910 (clobber (match_operand:DI 4 "memory_operand" ""))
14911 (clobber (match_scratch 5 ""))]
14913 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14914 (use (match_dup 2))
14915 (use (match_dup 3))
14916 (clobber (match_dup 5))])
14917 (set (match_dup 0) (match_dup 4))])
14920 [(set (match_operand:DI 0 "memory_operand" "")
14921 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14922 UNSPEC_FIST_FLOOR))
14923 (use (match_operand:HI 2 "memory_operand" ""))
14924 (use (match_operand:HI 3 "memory_operand" ""))
14925 (clobber (match_operand:DI 4 "memory_operand" ""))
14926 (clobber (match_scratch 5 ""))]
14928 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14929 (use (match_dup 2))
14930 (use (match_dup 3))
14931 (clobber (match_dup 5))])])
14933 (define_insn "fist<mode>2_floor"
14934 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14935 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14936 UNSPEC_FIST_FLOOR))
14937 (use (match_operand:HI 2 "memory_operand" "m"))
14938 (use (match_operand:HI 3 "memory_operand" "m"))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && flag_unsafe_math_optimizations"
14941 "* return output_fix_trunc (insn, operands, 0);"
14942 [(set_attr "type" "fistp")
14943 (set_attr "i387_cw" "floor")
14944 (set_attr "mode" "<MODE>")])
14946 (define_insn "fist<mode>2_floor_with_temp"
14947 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14948 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14949 UNSPEC_FIST_FLOOR))
14950 (use (match_operand:HI 2 "memory_operand" "m,m"))
14951 (use (match_operand:HI 3 "memory_operand" "m,m"))
14952 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14953 "TARGET_USE_FANCY_MATH_387
14954 && flag_unsafe_math_optimizations"
14956 [(set_attr "type" "fistp")
14957 (set_attr "i387_cw" "floor")
14958 (set_attr "mode" "<MODE>")])
14961 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14962 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14963 UNSPEC_FIST_FLOOR))
14964 (use (match_operand:HI 2 "memory_operand" ""))
14965 (use (match_operand:HI 3 "memory_operand" ""))
14966 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14968 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14969 UNSPEC_FIST_FLOOR))
14970 (use (match_dup 2))
14971 (use (match_dup 3))])
14972 (set (match_dup 0) (match_dup 4))])
14975 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14976 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14977 UNSPEC_FIST_FLOOR))
14978 (use (match_operand:HI 2 "memory_operand" ""))
14979 (use (match_operand:HI 3 "memory_operand" ""))
14980 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14982 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14983 UNSPEC_FIST_FLOOR))
14984 (use (match_dup 2))
14985 (use (match_dup 3))])])
14987 (define_expand "lfloorxf<mode>2"
14988 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14989 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14990 UNSPEC_FIST_FLOOR))
14991 (clobber (reg:CC FLAGS_REG))])]
14992 "TARGET_USE_FANCY_MATH_387
14993 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14994 && flag_unsafe_math_optimizations")
14996 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14997 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14998 (match_operand:MODEF 1 "register_operand" "")]
14999 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15000 && !flag_trapping_math"
15002 if (TARGET_64BIT && optimize_insn_for_size_p ())
15004 ix86_expand_lfloorceil (operand0, operand1, true);
15008 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15009 (define_insn_and_split "frndintxf2_ceil"
15010 [(set (match_operand:XF 0 "register_operand" "")
15011 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15012 UNSPEC_FRNDINT_CEIL))
15013 (clobber (reg:CC FLAGS_REG))]
15014 "TARGET_USE_FANCY_MATH_387
15015 && flag_unsafe_math_optimizations
15016 && can_create_pseudo_p ()"
15021 ix86_optimize_mode_switching[I387_CEIL] = 1;
15023 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15024 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15026 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15027 operands[2], operands[3]));
15030 [(set_attr "type" "frndint")
15031 (set_attr "i387_cw" "ceil")
15032 (set_attr "mode" "XF")])
15034 (define_insn "frndintxf2_ceil_i387"
15035 [(set (match_operand:XF 0 "register_operand" "=f")
15036 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15037 UNSPEC_FRNDINT_CEIL))
15038 (use (match_operand:HI 2 "memory_operand" "m"))
15039 (use (match_operand:HI 3 "memory_operand" "m"))]
15040 "TARGET_USE_FANCY_MATH_387
15041 && flag_unsafe_math_optimizations"
15042 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15043 [(set_attr "type" "frndint")
15044 (set_attr "i387_cw" "ceil")
15045 (set_attr "mode" "XF")])
15047 (define_expand "ceilxf2"
15048 [(use (match_operand:XF 0 "register_operand" ""))
15049 (use (match_operand:XF 1 "register_operand" ""))]
15050 "TARGET_USE_FANCY_MATH_387
15051 && flag_unsafe_math_optimizations"
15053 if (optimize_insn_for_size_p ())
15055 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15059 (define_expand "ceil<mode>2"
15060 [(use (match_operand:MODEF 0 "register_operand" ""))
15061 (use (match_operand:MODEF 1 "register_operand" ""))]
15062 "(TARGET_USE_FANCY_MATH_387
15063 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15064 || TARGET_MIX_SSE_I387)
15065 && flag_unsafe_math_optimizations)
15066 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15067 && !flag_trapping_math)"
15069 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15070 && !flag_trapping_math
15071 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15074 emit_insn (gen_sse4_1_round<mode>2
15075 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15076 else if (optimize_insn_for_size_p ())
15078 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15079 ix86_expand_floorceil (operand0, operand1, false);
15081 ix86_expand_floorceildf_32 (operand0, operand1, false);
15087 if (optimize_insn_for_size_p ())
15090 op0 = gen_reg_rtx (XFmode);
15091 op1 = gen_reg_rtx (XFmode);
15092 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15093 emit_insn (gen_frndintxf2_ceil (op0, op1));
15095 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15100 (define_insn_and_split "*fist<mode>2_ceil_1"
15101 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15102 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15104 (clobber (reg:CC FLAGS_REG))]
15105 "TARGET_USE_FANCY_MATH_387
15106 && flag_unsafe_math_optimizations
15107 && can_create_pseudo_p ()"
15112 ix86_optimize_mode_switching[I387_CEIL] = 1;
15114 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15115 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15116 if (memory_operand (operands[0], VOIDmode))
15117 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15118 operands[2], operands[3]));
15121 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15122 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15123 operands[2], operands[3],
15128 [(set_attr "type" "fistp")
15129 (set_attr "i387_cw" "ceil")
15130 (set_attr "mode" "<MODE>")])
15132 (define_insn "fistdi2_ceil"
15133 [(set (match_operand:DI 0 "memory_operand" "=m")
15134 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15136 (use (match_operand:HI 2 "memory_operand" "m"))
15137 (use (match_operand:HI 3 "memory_operand" "m"))
15138 (clobber (match_scratch:XF 4 "=&1f"))]
15139 "TARGET_USE_FANCY_MATH_387
15140 && flag_unsafe_math_optimizations"
15141 "* return output_fix_trunc (insn, operands, 0);"
15142 [(set_attr "type" "fistp")
15143 (set_attr "i387_cw" "ceil")
15144 (set_attr "mode" "DI")])
15146 (define_insn "fistdi2_ceil_with_temp"
15147 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15148 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15150 (use (match_operand:HI 2 "memory_operand" "m,m"))
15151 (use (match_operand:HI 3 "memory_operand" "m,m"))
15152 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15153 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15154 "TARGET_USE_FANCY_MATH_387
15155 && flag_unsafe_math_optimizations"
15157 [(set_attr "type" "fistp")
15158 (set_attr "i387_cw" "ceil")
15159 (set_attr "mode" "DI")])
15162 [(set (match_operand:DI 0 "register_operand" "")
15163 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15165 (use (match_operand:HI 2 "memory_operand" ""))
15166 (use (match_operand:HI 3 "memory_operand" ""))
15167 (clobber (match_operand:DI 4 "memory_operand" ""))
15168 (clobber (match_scratch 5 ""))]
15170 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15171 (use (match_dup 2))
15172 (use (match_dup 3))
15173 (clobber (match_dup 5))])
15174 (set (match_dup 0) (match_dup 4))])
15177 [(set (match_operand:DI 0 "memory_operand" "")
15178 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15180 (use (match_operand:HI 2 "memory_operand" ""))
15181 (use (match_operand:HI 3 "memory_operand" ""))
15182 (clobber (match_operand:DI 4 "memory_operand" ""))
15183 (clobber (match_scratch 5 ""))]
15185 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15186 (use (match_dup 2))
15187 (use (match_dup 3))
15188 (clobber (match_dup 5))])])
15190 (define_insn "fist<mode>2_ceil"
15191 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15192 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15194 (use (match_operand:HI 2 "memory_operand" "m"))
15195 (use (match_operand:HI 3 "memory_operand" "m"))]
15196 "TARGET_USE_FANCY_MATH_387
15197 && flag_unsafe_math_optimizations"
15198 "* return output_fix_trunc (insn, operands, 0);"
15199 [(set_attr "type" "fistp")
15200 (set_attr "i387_cw" "ceil")
15201 (set_attr "mode" "<MODE>")])
15203 (define_insn "fist<mode>2_ceil_with_temp"
15204 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15205 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15207 (use (match_operand:HI 2 "memory_operand" "m,m"))
15208 (use (match_operand:HI 3 "memory_operand" "m,m"))
15209 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15210 "TARGET_USE_FANCY_MATH_387
15211 && flag_unsafe_math_optimizations"
15213 [(set_attr "type" "fistp")
15214 (set_attr "i387_cw" "ceil")
15215 (set_attr "mode" "<MODE>")])
15218 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15219 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15221 (use (match_operand:HI 2 "memory_operand" ""))
15222 (use (match_operand:HI 3 "memory_operand" ""))
15223 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15225 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15227 (use (match_dup 2))
15228 (use (match_dup 3))])
15229 (set (match_dup 0) (match_dup 4))])
15232 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15233 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15235 (use (match_operand:HI 2 "memory_operand" ""))
15236 (use (match_operand:HI 3 "memory_operand" ""))
15237 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15239 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15241 (use (match_dup 2))
15242 (use (match_dup 3))])])
15244 (define_expand "lceilxf<mode>2"
15245 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15246 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15248 (clobber (reg:CC FLAGS_REG))])]
15249 "TARGET_USE_FANCY_MATH_387
15250 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15251 && flag_unsafe_math_optimizations")
15253 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15254 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15255 (match_operand:MODEF 1 "register_operand" "")]
15256 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15257 && !flag_trapping_math"
15259 ix86_expand_lfloorceil (operand0, operand1, false);
15263 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15264 (define_insn_and_split "frndintxf2_trunc"
15265 [(set (match_operand:XF 0 "register_operand" "")
15266 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15267 UNSPEC_FRNDINT_TRUNC))
15268 (clobber (reg:CC FLAGS_REG))]
15269 "TARGET_USE_FANCY_MATH_387
15270 && flag_unsafe_math_optimizations
15271 && can_create_pseudo_p ()"
15276 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15278 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15279 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15281 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15282 operands[2], operands[3]));
15285 [(set_attr "type" "frndint")
15286 (set_attr "i387_cw" "trunc")
15287 (set_attr "mode" "XF")])
15289 (define_insn "frndintxf2_trunc_i387"
15290 [(set (match_operand:XF 0 "register_operand" "=f")
15291 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15292 UNSPEC_FRNDINT_TRUNC))
15293 (use (match_operand:HI 2 "memory_operand" "m"))
15294 (use (match_operand:HI 3 "memory_operand" "m"))]
15295 "TARGET_USE_FANCY_MATH_387
15296 && flag_unsafe_math_optimizations"
15297 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15298 [(set_attr "type" "frndint")
15299 (set_attr "i387_cw" "trunc")
15300 (set_attr "mode" "XF")])
15302 (define_expand "btruncxf2"
15303 [(use (match_operand:XF 0 "register_operand" ""))
15304 (use (match_operand:XF 1 "register_operand" ""))]
15305 "TARGET_USE_FANCY_MATH_387
15306 && flag_unsafe_math_optimizations"
15308 if (optimize_insn_for_size_p ())
15310 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15314 (define_expand "btrunc<mode>2"
15315 [(use (match_operand:MODEF 0 "register_operand" ""))
15316 (use (match_operand:MODEF 1 "register_operand" ""))]
15317 "(TARGET_USE_FANCY_MATH_387
15318 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15319 || TARGET_MIX_SSE_I387)
15320 && flag_unsafe_math_optimizations)
15321 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15322 && !flag_trapping_math)"
15324 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15325 && !flag_trapping_math
15326 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15329 emit_insn (gen_sse4_1_round<mode>2
15330 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15331 else if (optimize_insn_for_size_p ())
15333 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15334 ix86_expand_trunc (operand0, operand1);
15336 ix86_expand_truncdf_32 (operand0, operand1);
15342 if (optimize_insn_for_size_p ())
15345 op0 = gen_reg_rtx (XFmode);
15346 op1 = gen_reg_rtx (XFmode);
15347 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15348 emit_insn (gen_frndintxf2_trunc (op0, op1));
15350 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15355 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15356 (define_insn_and_split "frndintxf2_mask_pm"
15357 [(set (match_operand:XF 0 "register_operand" "")
15358 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15359 UNSPEC_FRNDINT_MASK_PM))
15360 (clobber (reg:CC FLAGS_REG))]
15361 "TARGET_USE_FANCY_MATH_387
15362 && flag_unsafe_math_optimizations
15363 && can_create_pseudo_p ()"
15368 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15370 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15371 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15373 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15374 operands[2], operands[3]));
15377 [(set_attr "type" "frndint")
15378 (set_attr "i387_cw" "mask_pm")
15379 (set_attr "mode" "XF")])
15381 (define_insn "frndintxf2_mask_pm_i387"
15382 [(set (match_operand:XF 0 "register_operand" "=f")
15383 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15384 UNSPEC_FRNDINT_MASK_PM))
15385 (use (match_operand:HI 2 "memory_operand" "m"))
15386 (use (match_operand:HI 3 "memory_operand" "m"))]
15387 "TARGET_USE_FANCY_MATH_387
15388 && flag_unsafe_math_optimizations"
15389 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15390 [(set_attr "type" "frndint")
15391 (set_attr "i387_cw" "mask_pm")
15392 (set_attr "mode" "XF")])
15394 (define_expand "nearbyintxf2"
15395 [(use (match_operand:XF 0 "register_operand" ""))
15396 (use (match_operand:XF 1 "register_operand" ""))]
15397 "TARGET_USE_FANCY_MATH_387
15398 && flag_unsafe_math_optimizations"
15400 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15404 (define_expand "nearbyint<mode>2"
15405 [(use (match_operand:MODEF 0 "register_operand" ""))
15406 (use (match_operand:MODEF 1 "register_operand" ""))]
15407 "TARGET_USE_FANCY_MATH_387
15408 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15409 || TARGET_MIX_SSE_I387)
15410 && flag_unsafe_math_optimizations"
15412 rtx op0 = gen_reg_rtx (XFmode);
15413 rtx op1 = gen_reg_rtx (XFmode);
15415 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15416 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15418 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15422 (define_insn "fxam<mode>2_i387"
15423 [(set (match_operand:HI 0 "register_operand" "=a")
15425 [(match_operand:X87MODEF 1 "register_operand" "f")]
15427 "TARGET_USE_FANCY_MATH_387"
15428 "fxam\n\tfnstsw\t%0"
15429 [(set_attr "type" "multi")
15430 (set_attr "length" "4")
15431 (set_attr "unit" "i387")
15432 (set_attr "mode" "<MODE>")])
15434 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15435 [(set (match_operand:HI 0 "register_operand" "")
15437 [(match_operand:MODEF 1 "memory_operand" "")]
15439 "TARGET_USE_FANCY_MATH_387
15440 && can_create_pseudo_p ()"
15443 [(set (match_dup 2)(match_dup 1))
15445 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15447 operands[2] = gen_reg_rtx (<MODE>mode);
15449 MEM_VOLATILE_P (operands[1]) = 1;
15451 [(set_attr "type" "multi")
15452 (set_attr "unit" "i387")
15453 (set_attr "mode" "<MODE>")])
15455 (define_expand "isinfxf2"
15456 [(use (match_operand:SI 0 "register_operand" ""))
15457 (use (match_operand:XF 1 "register_operand" ""))]
15458 "TARGET_USE_FANCY_MATH_387
15459 && TARGET_C99_FUNCTIONS"
15461 rtx mask = GEN_INT (0x45);
15462 rtx val = GEN_INT (0x05);
15466 rtx scratch = gen_reg_rtx (HImode);
15467 rtx res = gen_reg_rtx (QImode);
15469 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15471 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15472 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15473 cond = gen_rtx_fmt_ee (EQ, QImode,
15474 gen_rtx_REG (CCmode, FLAGS_REG),
15476 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15477 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15481 (define_expand "isinf<mode>2"
15482 [(use (match_operand:SI 0 "register_operand" ""))
15483 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15484 "TARGET_USE_FANCY_MATH_387
15485 && TARGET_C99_FUNCTIONS
15486 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15488 rtx mask = GEN_INT (0x45);
15489 rtx val = GEN_INT (0x05);
15493 rtx scratch = gen_reg_rtx (HImode);
15494 rtx res = gen_reg_rtx (QImode);
15496 /* Remove excess precision by forcing value through memory. */
15497 if (memory_operand (operands[1], VOIDmode))
15498 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15501 enum ix86_stack_slot slot = (virtuals_instantiated
15504 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15506 emit_move_insn (temp, operands[1]);
15507 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15510 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15511 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15512 cond = gen_rtx_fmt_ee (EQ, QImode,
15513 gen_rtx_REG (CCmode, FLAGS_REG),
15515 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15516 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15520 (define_expand "signbitxf2"
15521 [(use (match_operand:SI 0 "register_operand" ""))
15522 (use (match_operand:XF 1 "register_operand" ""))]
15523 "TARGET_USE_FANCY_MATH_387"
15525 rtx scratch = gen_reg_rtx (HImode);
15527 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15528 emit_insn (gen_andsi3 (operands[0],
15529 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15533 (define_insn "movmsk_df"
15534 [(set (match_operand:SI 0 "register_operand" "=r")
15536 [(match_operand:DF 1 "register_operand" "x")]
15538 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15539 "%vmovmskpd\t{%1, %0|%0, %1}"
15540 [(set_attr "type" "ssemov")
15541 (set_attr "prefix" "maybe_vex")
15542 (set_attr "mode" "DF")])
15544 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15545 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15546 (define_expand "signbitdf2"
15547 [(use (match_operand:SI 0 "register_operand" ""))
15548 (use (match_operand:DF 1 "register_operand" ""))]
15549 "TARGET_USE_FANCY_MATH_387
15550 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15552 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15554 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15555 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15559 rtx scratch = gen_reg_rtx (HImode);
15561 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15562 emit_insn (gen_andsi3 (operands[0],
15563 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15568 (define_expand "signbitsf2"
15569 [(use (match_operand:SI 0 "register_operand" ""))
15570 (use (match_operand:SF 1 "register_operand" ""))]
15571 "TARGET_USE_FANCY_MATH_387
15572 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15574 rtx scratch = gen_reg_rtx (HImode);
15576 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15577 emit_insn (gen_andsi3 (operands[0],
15578 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15582 ;; Block operation instructions
15585 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15588 [(set_attr "length" "1")
15589 (set_attr "length_immediate" "0")
15590 (set_attr "modrm" "0")])
15592 (define_expand "movmem<mode>"
15593 [(use (match_operand:BLK 0 "memory_operand" ""))
15594 (use (match_operand:BLK 1 "memory_operand" ""))
15595 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15596 (use (match_operand:SWI48 3 "const_int_operand" ""))
15597 (use (match_operand:SI 4 "const_int_operand" ""))
15598 (use (match_operand:SI 5 "const_int_operand" ""))]
15601 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15602 operands[4], operands[5]))
15608 ;; Most CPUs don't like single string operations
15609 ;; Handle this case here to simplify previous expander.
15611 (define_expand "strmov"
15612 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15613 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15614 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15615 (clobber (reg:CC FLAGS_REG))])
15616 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15617 (clobber (reg:CC FLAGS_REG))])]
15620 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15622 /* If .md ever supports :P for Pmode, these can be directly
15623 in the pattern above. */
15624 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15625 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15627 /* Can't use this if the user has appropriated esi or edi. */
15628 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15629 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15631 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15632 operands[2], operands[3],
15633 operands[5], operands[6]));
15637 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15640 (define_expand "strmov_singleop"
15641 [(parallel [(set (match_operand 1 "memory_operand" "")
15642 (match_operand 3 "memory_operand" ""))
15643 (set (match_operand 0 "register_operand" "")
15644 (match_operand 4 "" ""))
15645 (set (match_operand 2 "register_operand" "")
15646 (match_operand 5 "" ""))])]
15648 "ix86_current_function_needs_cld = 1;")
15650 (define_insn "*strmovdi_rex_1"
15651 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15652 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15653 (set (match_operand:DI 0 "register_operand" "=D")
15654 (plus:DI (match_dup 2)
15656 (set (match_operand:DI 1 "register_operand" "=S")
15657 (plus:DI (match_dup 3)
15661 [(set_attr "type" "str")
15662 (set_attr "memory" "both")
15663 (set_attr "mode" "DI")])
15665 (define_insn "*strmovsi_1"
15666 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15667 (mem:SI (match_operand:P 3 "register_operand" "1")))
15668 (set (match_operand:P 0 "register_operand" "=D")
15669 (plus:P (match_dup 2)
15671 (set (match_operand:P 1 "register_operand" "=S")
15672 (plus:P (match_dup 3)
15676 [(set_attr "type" "str")
15677 (set_attr "memory" "both")
15678 (set_attr "mode" "SI")])
15680 (define_insn "*strmovhi_1"
15681 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15682 (mem:HI (match_operand:P 3 "register_operand" "1")))
15683 (set (match_operand:P 0 "register_operand" "=D")
15684 (plus:P (match_dup 2)
15686 (set (match_operand:P 1 "register_operand" "=S")
15687 (plus:P (match_dup 3)
15691 [(set_attr "type" "str")
15692 (set_attr "memory" "both")
15693 (set_attr "mode" "HI")])
15695 (define_insn "*strmovqi_1"
15696 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15697 (mem:QI (match_operand:P 3 "register_operand" "1")))
15698 (set (match_operand:P 0 "register_operand" "=D")
15699 (plus:P (match_dup 2)
15701 (set (match_operand:P 1 "register_operand" "=S")
15702 (plus:P (match_dup 3)
15706 [(set_attr "type" "str")
15707 (set_attr "memory" "both")
15708 (set (attr "prefix_rex")
15710 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15712 (const_string "*")))
15713 (set_attr "mode" "QI")])
15715 (define_expand "rep_mov"
15716 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15717 (set (match_operand 0 "register_operand" "")
15718 (match_operand 5 "" ""))
15719 (set (match_operand 2 "register_operand" "")
15720 (match_operand 6 "" ""))
15721 (set (match_operand 1 "memory_operand" "")
15722 (match_operand 3 "memory_operand" ""))
15723 (use (match_dup 4))])]
15725 "ix86_current_function_needs_cld = 1;")
15727 (define_insn "*rep_movdi_rex64"
15728 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15729 (set (match_operand:DI 0 "register_operand" "=D")
15730 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15732 (match_operand:DI 3 "register_operand" "0")))
15733 (set (match_operand:DI 1 "register_operand" "=S")
15734 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15735 (match_operand:DI 4 "register_operand" "1")))
15736 (set (mem:BLK (match_dup 3))
15737 (mem:BLK (match_dup 4)))
15738 (use (match_dup 5))]
15741 [(set_attr "type" "str")
15742 (set_attr "prefix_rep" "1")
15743 (set_attr "memory" "both")
15744 (set_attr "mode" "DI")])
15746 (define_insn "*rep_movsi"
15747 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15748 (set (match_operand:P 0 "register_operand" "=D")
15749 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15751 (match_operand:P 3 "register_operand" "0")))
15752 (set (match_operand:P 1 "register_operand" "=S")
15753 (plus:P (ashift:P (match_dup 5) (const_int 2))
15754 (match_operand:P 4 "register_operand" "1")))
15755 (set (mem:BLK (match_dup 3))
15756 (mem:BLK (match_dup 4)))
15757 (use (match_dup 5))]
15759 "rep{%;} movs{l|d}"
15760 [(set_attr "type" "str")
15761 (set_attr "prefix_rep" "1")
15762 (set_attr "memory" "both")
15763 (set_attr "mode" "SI")])
15765 (define_insn "*rep_movqi"
15766 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15767 (set (match_operand:P 0 "register_operand" "=D")
15768 (plus:P (match_operand:P 3 "register_operand" "0")
15769 (match_operand:P 5 "register_operand" "2")))
15770 (set (match_operand:P 1 "register_operand" "=S")
15771 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15772 (set (mem:BLK (match_dup 3))
15773 (mem:BLK (match_dup 4)))
15774 (use (match_dup 5))]
15777 [(set_attr "type" "str")
15778 (set_attr "prefix_rep" "1")
15779 (set_attr "memory" "both")
15780 (set_attr "mode" "QI")])
15782 (define_expand "setmem<mode>"
15783 [(use (match_operand:BLK 0 "memory_operand" ""))
15784 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15785 (use (match_operand:QI 2 "nonmemory_operand" ""))
15786 (use (match_operand 3 "const_int_operand" ""))
15787 (use (match_operand:SI 4 "const_int_operand" ""))
15788 (use (match_operand:SI 5 "const_int_operand" ""))]
15791 if (ix86_expand_setmem (operands[0], operands[1],
15792 operands[2], operands[3],
15793 operands[4], operands[5]))
15799 ;; Most CPUs don't like single string operations
15800 ;; Handle this case here to simplify previous expander.
15802 (define_expand "strset"
15803 [(set (match_operand 1 "memory_operand" "")
15804 (match_operand 2 "register_operand" ""))
15805 (parallel [(set (match_operand 0 "register_operand" "")
15807 (clobber (reg:CC FLAGS_REG))])]
15810 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15811 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15813 /* If .md ever supports :P for Pmode, this can be directly
15814 in the pattern above. */
15815 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15816 GEN_INT (GET_MODE_SIZE (GET_MODE
15818 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15820 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15826 (define_expand "strset_singleop"
15827 [(parallel [(set (match_operand 1 "memory_operand" "")
15828 (match_operand 2 "register_operand" ""))
15829 (set (match_operand 0 "register_operand" "")
15830 (match_operand 3 "" ""))])]
15832 "ix86_current_function_needs_cld = 1;")
15834 (define_insn "*strsetdi_rex_1"
15835 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15836 (match_operand:DI 2 "register_operand" "a"))
15837 (set (match_operand:DI 0 "register_operand" "=D")
15838 (plus:DI (match_dup 1)
15842 [(set_attr "type" "str")
15843 (set_attr "memory" "store")
15844 (set_attr "mode" "DI")])
15846 (define_insn "*strsetsi_1"
15847 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15848 (match_operand:SI 2 "register_operand" "a"))
15849 (set (match_operand:P 0 "register_operand" "=D")
15850 (plus:P (match_dup 1)
15854 [(set_attr "type" "str")
15855 (set_attr "memory" "store")
15856 (set_attr "mode" "SI")])
15858 (define_insn "*strsethi_1"
15859 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15860 (match_operand:HI 2 "register_operand" "a"))
15861 (set (match_operand:P 0 "register_operand" "=D")
15862 (plus:P (match_dup 1)
15866 [(set_attr "type" "str")
15867 (set_attr "memory" "store")
15868 (set_attr "mode" "HI")])
15870 (define_insn "*strsetqi_1"
15871 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15872 (match_operand:QI 2 "register_operand" "a"))
15873 (set (match_operand:P 0 "register_operand" "=D")
15874 (plus:P (match_dup 1)
15878 [(set_attr "type" "str")
15879 (set_attr "memory" "store")
15880 (set (attr "prefix_rex")
15882 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15884 (const_string "*")))
15885 (set_attr "mode" "QI")])
15887 (define_expand "rep_stos"
15888 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15889 (set (match_operand 0 "register_operand" "")
15890 (match_operand 4 "" ""))
15891 (set (match_operand 2 "memory_operand" "") (const_int 0))
15892 (use (match_operand 3 "register_operand" ""))
15893 (use (match_dup 1))])]
15895 "ix86_current_function_needs_cld = 1;")
15897 (define_insn "*rep_stosdi_rex64"
15898 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15899 (set (match_operand:DI 0 "register_operand" "=D")
15900 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15902 (match_operand:DI 3 "register_operand" "0")))
15903 (set (mem:BLK (match_dup 3))
15905 (use (match_operand:DI 2 "register_operand" "a"))
15906 (use (match_dup 4))]
15909 [(set_attr "type" "str")
15910 (set_attr "prefix_rep" "1")
15911 (set_attr "memory" "store")
15912 (set_attr "mode" "DI")])
15914 (define_insn "*rep_stossi"
15915 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15916 (set (match_operand:P 0 "register_operand" "=D")
15917 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15919 (match_operand:P 3 "register_operand" "0")))
15920 (set (mem:BLK (match_dup 3))
15922 (use (match_operand:SI 2 "register_operand" "a"))
15923 (use (match_dup 4))]
15925 "rep{%;} stos{l|d}"
15926 [(set_attr "type" "str")
15927 (set_attr "prefix_rep" "1")
15928 (set_attr "memory" "store")
15929 (set_attr "mode" "SI")])
15931 (define_insn "*rep_stosqi"
15932 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15933 (set (match_operand:P 0 "register_operand" "=D")
15934 (plus:P (match_operand:P 3 "register_operand" "0")
15935 (match_operand:P 4 "register_operand" "1")))
15936 (set (mem:BLK (match_dup 3))
15938 (use (match_operand:QI 2 "register_operand" "a"))
15939 (use (match_dup 4))]
15942 [(set_attr "type" "str")
15943 (set_attr "prefix_rep" "1")
15944 (set_attr "memory" "store")
15945 (set (attr "prefix_rex")
15947 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15949 (const_string "*")))
15950 (set_attr "mode" "QI")])
15952 (define_expand "cmpstrnsi"
15953 [(set (match_operand:SI 0 "register_operand" "")
15954 (compare:SI (match_operand:BLK 1 "general_operand" "")
15955 (match_operand:BLK 2 "general_operand" "")))
15956 (use (match_operand 3 "general_operand" ""))
15957 (use (match_operand 4 "immediate_operand" ""))]
15960 rtx addr1, addr2, out, outlow, count, countreg, align;
15962 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15965 /* Can't use this if the user has appropriated esi or edi. */
15966 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15971 out = gen_reg_rtx (SImode);
15973 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15974 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15975 if (addr1 != XEXP (operands[1], 0))
15976 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15977 if (addr2 != XEXP (operands[2], 0))
15978 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15980 count = operands[3];
15981 countreg = ix86_zero_extend_to_Pmode (count);
15983 /* %%% Iff we are testing strict equality, we can use known alignment
15984 to good advantage. This may be possible with combine, particularly
15985 once cc0 is dead. */
15986 align = operands[4];
15988 if (CONST_INT_P (count))
15990 if (INTVAL (count) == 0)
15992 emit_move_insn (operands[0], const0_rtx);
15995 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15996 operands[1], operands[2]));
16000 rtx (*gen_cmp) (rtx, rtx);
16002 gen_cmp = (TARGET_64BIT
16003 ? gen_cmpdi_1 : gen_cmpsi_1);
16005 emit_insn (gen_cmp (countreg, countreg));
16006 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16007 operands[1], operands[2]));
16010 outlow = gen_lowpart (QImode, out);
16011 emit_insn (gen_cmpintqi (outlow));
16012 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16014 if (operands[0] != out)
16015 emit_move_insn (operands[0], out);
16020 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16022 (define_expand "cmpintqi"
16023 [(set (match_dup 1)
16024 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16026 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16027 (parallel [(set (match_operand:QI 0 "register_operand" "")
16028 (minus:QI (match_dup 1)
16030 (clobber (reg:CC FLAGS_REG))])]
16033 operands[1] = gen_reg_rtx (QImode);
16034 operands[2] = gen_reg_rtx (QImode);
16037 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16038 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16040 (define_expand "cmpstrnqi_nz_1"
16041 [(parallel [(set (reg:CC FLAGS_REG)
16042 (compare:CC (match_operand 4 "memory_operand" "")
16043 (match_operand 5 "memory_operand" "")))
16044 (use (match_operand 2 "register_operand" ""))
16045 (use (match_operand:SI 3 "immediate_operand" ""))
16046 (clobber (match_operand 0 "register_operand" ""))
16047 (clobber (match_operand 1 "register_operand" ""))
16048 (clobber (match_dup 2))])]
16050 "ix86_current_function_needs_cld = 1;")
16052 (define_insn "*cmpstrnqi_nz_1"
16053 [(set (reg:CC FLAGS_REG)
16054 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16055 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16056 (use (match_operand:P 6 "register_operand" "2"))
16057 (use (match_operand:SI 3 "immediate_operand" "i"))
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 ;; The same, but the count is not known to not be zero.
16074 (define_expand "cmpstrnqi_1"
16075 [(parallel [(set (reg:CC FLAGS_REG)
16076 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16078 (compare:CC (match_operand 4 "memory_operand" "")
16079 (match_operand 5 "memory_operand" ""))
16081 (use (match_operand:SI 3 "immediate_operand" ""))
16082 (use (reg:CC FLAGS_REG))
16083 (clobber (match_operand 0 "register_operand" ""))
16084 (clobber (match_operand 1 "register_operand" ""))
16085 (clobber (match_dup 2))])]
16087 "ix86_current_function_needs_cld = 1;")
16089 (define_insn "*cmpstrnqi_1"
16090 [(set (reg:CC FLAGS_REG)
16091 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16093 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16094 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16096 (use (match_operand:SI 3 "immediate_operand" "i"))
16097 (use (reg:CC FLAGS_REG))
16098 (clobber (match_operand:P 0 "register_operand" "=S"))
16099 (clobber (match_operand:P 1 "register_operand" "=D"))
16100 (clobber (match_operand:P 2 "register_operand" "=c"))]
16103 [(set_attr "type" "str")
16104 (set_attr "mode" "QI")
16105 (set (attr "prefix_rex")
16107 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16109 (const_string "*")))
16110 (set_attr "prefix_rep" "1")])
16112 (define_expand "strlen<mode>"
16113 [(set (match_operand:SWI48x 0 "register_operand" "")
16114 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16115 (match_operand:QI 2 "immediate_operand" "")
16116 (match_operand 3 "immediate_operand" "")]
16120 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16126 (define_expand "strlenqi_1"
16127 [(parallel [(set (match_operand 0 "register_operand" "")
16128 (match_operand 2 "" ""))
16129 (clobber (match_operand 1 "register_operand" ""))
16130 (clobber (reg:CC FLAGS_REG))])]
16132 "ix86_current_function_needs_cld = 1;")
16134 (define_insn "*strlenqi_1"
16135 [(set (match_operand:P 0 "register_operand" "=&c")
16136 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16137 (match_operand:QI 2 "register_operand" "a")
16138 (match_operand:P 3 "immediate_operand" "i")
16139 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16140 (clobber (match_operand:P 1 "register_operand" "=D"))
16141 (clobber (reg:CC FLAGS_REG))]
16144 [(set_attr "type" "str")
16145 (set_attr "mode" "QI")
16146 (set (attr "prefix_rex")
16148 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16150 (const_string "*")))
16151 (set_attr "prefix_rep" "1")])
16153 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16154 ;; handled in combine, but it is not currently up to the task.
16155 ;; When used for their truth value, the cmpstrn* expanders generate
16164 ;; The intermediate three instructions are unnecessary.
16166 ;; This one handles cmpstrn*_nz_1...
16169 (set (reg:CC FLAGS_REG)
16170 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16171 (mem:BLK (match_operand 5 "register_operand" ""))))
16172 (use (match_operand 6 "register_operand" ""))
16173 (use (match_operand:SI 3 "immediate_operand" ""))
16174 (clobber (match_operand 0 "register_operand" ""))
16175 (clobber (match_operand 1 "register_operand" ""))
16176 (clobber (match_operand 2 "register_operand" ""))])
16177 (set (match_operand:QI 7 "register_operand" "")
16178 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16179 (set (match_operand:QI 8 "register_operand" "")
16180 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16181 (set (reg FLAGS_REG)
16182 (compare (match_dup 7) (match_dup 8)))
16184 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16186 (set (reg:CC FLAGS_REG)
16187 (compare:CC (mem:BLK (match_dup 4))
16188 (mem:BLK (match_dup 5))))
16189 (use (match_dup 6))
16190 (use (match_dup 3))
16191 (clobber (match_dup 0))
16192 (clobber (match_dup 1))
16193 (clobber (match_dup 2))])])
16195 ;; ...and this one handles cmpstrn*_1.
16198 (set (reg:CC FLAGS_REG)
16199 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16201 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16202 (mem:BLK (match_operand 5 "register_operand" "")))
16204 (use (match_operand:SI 3 "immediate_operand" ""))
16205 (use (reg:CC FLAGS_REG))
16206 (clobber (match_operand 0 "register_operand" ""))
16207 (clobber (match_operand 1 "register_operand" ""))
16208 (clobber (match_operand 2 "register_operand" ""))])
16209 (set (match_operand:QI 7 "register_operand" "")
16210 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16211 (set (match_operand:QI 8 "register_operand" "")
16212 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16213 (set (reg FLAGS_REG)
16214 (compare (match_dup 7) (match_dup 8)))
16216 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16218 (set (reg:CC FLAGS_REG)
16219 (if_then_else:CC (ne (match_dup 6)
16221 (compare:CC (mem:BLK (match_dup 4))
16222 (mem:BLK (match_dup 5)))
16224 (use (match_dup 3))
16225 (use (reg:CC FLAGS_REG))
16226 (clobber (match_dup 0))
16227 (clobber (match_dup 1))
16228 (clobber (match_dup 2))])])
16230 ;; Conditional move instructions.
16232 (define_expand "mov<mode>cc"
16233 [(set (match_operand:SWIM 0 "register_operand" "")
16234 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16235 (match_operand:SWIM 2 "general_operand" "")
16236 (match_operand:SWIM 3 "general_operand" "")))]
16238 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16240 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16241 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16242 ;; So just document what we're doing explicitly.
16244 (define_expand "x86_mov<mode>cc_0_m1"
16246 [(set (match_operand:SWI48 0 "register_operand" "")
16247 (if_then_else:SWI48
16248 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16249 [(match_operand 1 "flags_reg_operand" "")
16253 (clobber (reg:CC FLAGS_REG))])])
16255 (define_insn "*x86_mov<mode>cc_0_m1"
16256 [(set (match_operand:SWI48 0 "register_operand" "=r")
16257 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16258 [(reg FLAGS_REG) (const_int 0)])
16261 (clobber (reg:CC FLAGS_REG))]
16263 "sbb{<imodesuffix>}\t%0, %0"
16264 ; Since we don't have the proper number of operands for an alu insn,
16265 ; fill in all the blanks.
16266 [(set_attr "type" "alu")
16267 (set_attr "use_carry" "1")
16268 (set_attr "pent_pair" "pu")
16269 (set_attr "memory" "none")
16270 (set_attr "imm_disp" "false")
16271 (set_attr "mode" "<MODE>")
16272 (set_attr "length_immediate" "0")])
16274 (define_insn "*x86_mov<mode>cc_0_m1_se"
16275 [(set (match_operand:SWI48 0 "register_operand" "=r")
16276 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16277 [(reg FLAGS_REG) (const_int 0)])
16280 (clobber (reg:CC FLAGS_REG))]
16282 "sbb{<imodesuffix>}\t%0, %0"
16283 [(set_attr "type" "alu")
16284 (set_attr "use_carry" "1")
16285 (set_attr "pent_pair" "pu")
16286 (set_attr "memory" "none")
16287 (set_attr "imm_disp" "false")
16288 (set_attr "mode" "<MODE>")
16289 (set_attr "length_immediate" "0")])
16291 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16292 [(set (match_operand:SWI48 0 "register_operand" "=r")
16293 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16294 [(reg FLAGS_REG) (const_int 0)])))]
16296 "sbb{<imodesuffix>}\t%0, %0"
16297 [(set_attr "type" "alu")
16298 (set_attr "use_carry" "1")
16299 (set_attr "pent_pair" "pu")
16300 (set_attr "memory" "none")
16301 (set_attr "imm_disp" "false")
16302 (set_attr "mode" "<MODE>")
16303 (set_attr "length_immediate" "0")])
16305 (define_insn "*mov<mode>cc_noc"
16306 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16307 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16308 [(reg FLAGS_REG) (const_int 0)])
16309 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16310 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16311 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16313 cmov%O2%C1\t{%2, %0|%0, %2}
16314 cmov%O2%c1\t{%3, %0|%0, %3}"
16315 [(set_attr "type" "icmov")
16316 (set_attr "mode" "<MODE>")])
16318 (define_insn_and_split "*movqicc_noc"
16319 [(set (match_operand:QI 0 "register_operand" "=r,r")
16320 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16321 [(match_operand 4 "flags_reg_operand" "")
16323 (match_operand:QI 2 "register_operand" "r,0")
16324 (match_operand:QI 3 "register_operand" "0,r")))]
16325 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16327 "&& reload_completed"
16328 [(set (match_dup 0)
16329 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16332 "operands[0] = gen_lowpart (SImode, operands[0]);
16333 operands[2] = gen_lowpart (SImode, operands[2]);
16334 operands[3] = gen_lowpart (SImode, operands[3]);"
16335 [(set_attr "type" "icmov")
16336 (set_attr "mode" "SI")])
16338 (define_expand "mov<mode>cc"
16339 [(set (match_operand:X87MODEF 0 "register_operand" "")
16340 (if_then_else:X87MODEF
16341 (match_operand 1 "ix86_fp_comparison_operator" "")
16342 (match_operand:X87MODEF 2 "register_operand" "")
16343 (match_operand:X87MODEF 3 "register_operand" "")))]
16344 "(TARGET_80387 && TARGET_CMOVE)
16345 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16346 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16348 (define_insn "*movxfcc_1"
16349 [(set (match_operand:XF 0 "register_operand" "=f,f")
16350 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16351 [(reg FLAGS_REG) (const_int 0)])
16352 (match_operand:XF 2 "register_operand" "f,0")
16353 (match_operand:XF 3 "register_operand" "0,f")))]
16354 "TARGET_80387 && TARGET_CMOVE"
16356 fcmov%F1\t{%2, %0|%0, %2}
16357 fcmov%f1\t{%3, %0|%0, %3}"
16358 [(set_attr "type" "fcmov")
16359 (set_attr "mode" "XF")])
16361 (define_insn "*movdfcc_1_rex64"
16362 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16363 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16364 [(reg FLAGS_REG) (const_int 0)])
16365 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16366 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16367 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16368 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16370 fcmov%F1\t{%2, %0|%0, %2}
16371 fcmov%f1\t{%3, %0|%0, %3}
16372 cmov%O2%C1\t{%2, %0|%0, %2}
16373 cmov%O2%c1\t{%3, %0|%0, %3}"
16374 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16375 (set_attr "mode" "DF,DF,DI,DI")])
16377 (define_insn "*movdfcc_1"
16378 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16379 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16380 [(reg FLAGS_REG) (const_int 0)])
16381 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16382 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16383 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16384 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16386 fcmov%F1\t{%2, %0|%0, %2}
16387 fcmov%f1\t{%3, %0|%0, %3}
16390 [(set_attr "type" "fcmov,fcmov,multi,multi")
16391 (set_attr "mode" "DF,DF,DI,DI")])
16394 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16395 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16396 [(match_operand 4 "flags_reg_operand" "")
16398 (match_operand:DF 2 "nonimmediate_operand" "")
16399 (match_operand:DF 3 "nonimmediate_operand" "")))]
16400 "!TARGET_64BIT && reload_completed"
16401 [(set (match_dup 2)
16402 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16406 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16410 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16411 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16414 (define_insn "*movsfcc_1_387"
16415 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16416 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16417 [(reg FLAGS_REG) (const_int 0)])
16418 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16419 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16420 "TARGET_80387 && TARGET_CMOVE
16421 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16423 fcmov%F1\t{%2, %0|%0, %2}
16424 fcmov%f1\t{%3, %0|%0, %3}
16425 cmov%O2%C1\t{%2, %0|%0, %2}
16426 cmov%O2%c1\t{%3, %0|%0, %3}"
16427 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16428 (set_attr "mode" "SF,SF,SI,SI")])
16430 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16431 ;; the scalar versions to have only XMM registers as operands.
16433 ;; XOP conditional move
16434 (define_insn "*xop_pcmov_<mode>"
16435 [(set (match_operand:MODEF 0 "register_operand" "=x")
16436 (if_then_else:MODEF
16437 (match_operand:MODEF 1 "register_operand" "x")
16438 (match_operand:MODEF 2 "register_operand" "x")
16439 (match_operand:MODEF 3 "register_operand" "x")))]
16441 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16442 [(set_attr "type" "sse4arg")])
16444 ;; These versions of the min/max patterns are intentionally ignorant of
16445 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16446 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16447 ;; are undefined in this condition, we're certain this is correct.
16449 (define_insn "<code><mode>3"
16450 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16452 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16453 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16454 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16456 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16457 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16458 [(set_attr "isa" "noavx,avx")
16459 (set_attr "prefix" "orig,vex")
16460 (set_attr "type" "sseadd")
16461 (set_attr "mode" "<MODE>")])
16463 ;; These versions of the min/max patterns implement exactly the operations
16464 ;; min = (op1 < op2 ? op1 : op2)
16465 ;; max = (!(op1 < op2) ? op1 : op2)
16466 ;; Their operands are not commutative, and thus they may be used in the
16467 ;; presence of -0.0 and NaN.
16469 (define_insn "*ieee_smin<mode>3"
16470 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16472 [(match_operand:MODEF 1 "register_operand" "0,x")
16473 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16475 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16477 min<ssemodesuffix>\t{%2, %0|%0, %2}
16478 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16479 [(set_attr "isa" "noavx,avx")
16480 (set_attr "prefix" "orig,vex")
16481 (set_attr "type" "sseadd")
16482 (set_attr "mode" "<MODE>")])
16484 (define_insn "*ieee_smax<mode>3"
16485 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16487 [(match_operand:MODEF 1 "register_operand" "0,x")
16488 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16490 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16492 max<ssemodesuffix>\t{%2, %0|%0, %2}
16493 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16494 [(set_attr "isa" "noavx,avx")
16495 (set_attr "prefix" "orig,vex")
16496 (set_attr "type" "sseadd")
16497 (set_attr "mode" "<MODE>")])
16499 ;; Make two stack loads independent:
16501 ;; fld %st(0) -> fld bb
16502 ;; fmul bb fmul %st(1), %st
16504 ;; Actually we only match the last two instructions for simplicity.
16506 [(set (match_operand 0 "fp_register_operand" "")
16507 (match_operand 1 "fp_register_operand" ""))
16509 (match_operator 2 "binary_fp_operator"
16511 (match_operand 3 "memory_operand" "")]))]
16512 "REGNO (operands[0]) != REGNO (operands[1])"
16513 [(set (match_dup 0) (match_dup 3))
16514 (set (match_dup 0) (match_dup 4))]
16516 ;; The % modifier is not operational anymore in peephole2's, so we have to
16517 ;; swap the operands manually in the case of addition and multiplication.
16518 "if (COMMUTATIVE_ARITH_P (operands[2]))
16519 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16520 GET_MODE (operands[2]),
16521 operands[0], operands[1]);
16523 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16524 GET_MODE (operands[2]),
16525 operands[1], operands[0]);")
16527 ;; Conditional addition patterns
16528 (define_expand "add<mode>cc"
16529 [(match_operand:SWI 0 "register_operand" "")
16530 (match_operand 1 "ordered_comparison_operator" "")
16531 (match_operand:SWI 2 "register_operand" "")
16532 (match_operand:SWI 3 "const_int_operand" "")]
16534 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16536 ;; Misc patterns (?)
16538 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16539 ;; Otherwise there will be nothing to keep
16541 ;; [(set (reg ebp) (reg esp))]
16542 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16543 ;; (clobber (eflags)]
16544 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16546 ;; in proper program order.
16548 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16549 [(set (match_operand:P 0 "register_operand" "=r,r")
16550 (plus:P (match_operand:P 1 "register_operand" "0,r")
16551 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16552 (clobber (reg:CC FLAGS_REG))
16553 (clobber (mem:BLK (scratch)))]
16556 switch (get_attr_type (insn))
16559 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16562 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16563 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16564 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16566 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16569 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16570 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16573 [(set (attr "type")
16574 (cond [(and (eq_attr "alternative" "0")
16575 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16576 (const_string "alu")
16577 (match_operand:<MODE> 2 "const0_operand" "")
16578 (const_string "imov")
16580 (const_string "lea")))
16581 (set (attr "length_immediate")
16582 (cond [(eq_attr "type" "imov")
16584 (and (eq_attr "type" "alu")
16585 (match_operand 2 "const128_operand" ""))
16588 (const_string "*")))
16589 (set_attr "mode" "<MODE>")])
16591 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16592 [(set (match_operand:P 0 "register_operand" "=r")
16593 (minus:P (match_operand:P 1 "register_operand" "0")
16594 (match_operand:P 2 "register_operand" "r")))
16595 (clobber (reg:CC FLAGS_REG))
16596 (clobber (mem:BLK (scratch)))]
16598 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16599 [(set_attr "type" "alu")
16600 (set_attr "mode" "<MODE>")])
16602 (define_insn "allocate_stack_worker_probe_<mode>"
16603 [(set (match_operand:P 0 "register_operand" "=a")
16604 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16605 UNSPECV_STACK_PROBE))
16606 (clobber (reg:CC FLAGS_REG))]
16607 "ix86_target_stack_probe ()"
16608 "call\t___chkstk_ms"
16609 [(set_attr "type" "multi")
16610 (set_attr "length" "5")])
16612 (define_expand "allocate_stack"
16613 [(match_operand 0 "register_operand" "")
16614 (match_operand 1 "general_operand" "")]
16615 "ix86_target_stack_probe ()"
16619 #ifndef CHECK_STACK_LIMIT
16620 #define CHECK_STACK_LIMIT 0
16623 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16624 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16626 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16627 stack_pointer_rtx, 0, OPTAB_DIRECT);
16628 if (x != stack_pointer_rtx)
16629 emit_move_insn (stack_pointer_rtx, x);
16633 x = copy_to_mode_reg (Pmode, operands[1]);
16635 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16637 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16638 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16639 stack_pointer_rtx, 0, OPTAB_DIRECT);
16640 if (x != stack_pointer_rtx)
16641 emit_move_insn (stack_pointer_rtx, x);
16644 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16648 ;; Use IOR for stack probes, this is shorter.
16649 (define_expand "probe_stack"
16650 [(match_operand 0 "memory_operand" "")]
16653 rtx (*gen_ior3) (rtx, rtx, rtx);
16655 gen_ior3 = (GET_MODE (operands[0]) == DImode
16656 ? gen_iordi3 : gen_iorsi3);
16658 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16662 (define_insn "adjust_stack_and_probe<mode>"
16663 [(set (match_operand:P 0 "register_operand" "=r")
16664 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16665 UNSPECV_PROBE_STACK_RANGE))
16666 (set (reg:P SP_REG)
16667 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16668 (clobber (reg:CC FLAGS_REG))
16669 (clobber (mem:BLK (scratch)))]
16671 "* return output_adjust_stack_and_probe (operands[0]);"
16672 [(set_attr "type" "multi")])
16674 (define_insn "probe_stack_range<mode>"
16675 [(set (match_operand:P 0 "register_operand" "=r")
16676 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16677 (match_operand:P 2 "const_int_operand" "n")]
16678 UNSPECV_PROBE_STACK_RANGE))
16679 (clobber (reg:CC FLAGS_REG))]
16681 "* return output_probe_stack_range (operands[0], operands[2]);"
16682 [(set_attr "type" "multi")])
16684 (define_expand "builtin_setjmp_receiver"
16685 [(label_ref (match_operand 0 "" ""))]
16686 "!TARGET_64BIT && flag_pic"
16692 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16693 rtx label_rtx = gen_label_rtx ();
16694 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16695 xops[0] = xops[1] = picreg;
16696 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16697 ix86_expand_binary_operator (MINUS, SImode, xops);
16701 emit_insn (gen_set_got (pic_offset_table_rtx));
16705 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16708 [(set (match_operand 0 "register_operand" "")
16709 (match_operator 3 "promotable_binary_operator"
16710 [(match_operand 1 "register_operand" "")
16711 (match_operand 2 "aligned_operand" "")]))
16712 (clobber (reg:CC FLAGS_REG))]
16713 "! TARGET_PARTIAL_REG_STALL && reload_completed
16714 && ((GET_MODE (operands[0]) == HImode
16715 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16716 /* ??? next two lines just !satisfies_constraint_K (...) */
16717 || !CONST_INT_P (operands[2])
16718 || satisfies_constraint_K (operands[2])))
16719 || (GET_MODE (operands[0]) == QImode
16720 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16721 [(parallel [(set (match_dup 0)
16722 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16723 (clobber (reg:CC FLAGS_REG))])]
16724 "operands[0] = gen_lowpart (SImode, operands[0]);
16725 operands[1] = gen_lowpart (SImode, operands[1]);
16726 if (GET_CODE (operands[3]) != ASHIFT)
16727 operands[2] = gen_lowpart (SImode, operands[2]);
16728 PUT_MODE (operands[3], SImode);")
16730 ; Promote the QImode tests, as i386 has encoding of the AND
16731 ; instruction with 32-bit sign-extended immediate and thus the
16732 ; instruction size is unchanged, except in the %eax case for
16733 ; which it is increased by one byte, hence the ! optimize_size.
16735 [(set (match_operand 0 "flags_reg_operand" "")
16736 (match_operator 2 "compare_operator"
16737 [(and (match_operand 3 "aligned_operand" "")
16738 (match_operand 4 "const_int_operand" ""))
16740 (set (match_operand 1 "register_operand" "")
16741 (and (match_dup 3) (match_dup 4)))]
16742 "! TARGET_PARTIAL_REG_STALL && reload_completed
16743 && optimize_insn_for_speed_p ()
16744 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16745 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16746 /* Ensure that the operand will remain sign-extended immediate. */
16747 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16748 [(parallel [(set (match_dup 0)
16749 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16752 (and:SI (match_dup 3) (match_dup 4)))])]
16755 = gen_int_mode (INTVAL (operands[4])
16756 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16757 operands[1] = gen_lowpart (SImode, operands[1]);
16758 operands[3] = gen_lowpart (SImode, operands[3]);
16761 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16762 ; the TEST instruction with 32-bit sign-extended immediate and thus
16763 ; the instruction size would at least double, which is not what we
16764 ; want even with ! optimize_size.
16766 [(set (match_operand 0 "flags_reg_operand" "")
16767 (match_operator 1 "compare_operator"
16768 [(and (match_operand:HI 2 "aligned_operand" "")
16769 (match_operand:HI 3 "const_int_operand" ""))
16771 "! TARGET_PARTIAL_REG_STALL && reload_completed
16772 && ! TARGET_FAST_PREFIX
16773 && optimize_insn_for_speed_p ()
16774 /* Ensure that the operand will remain sign-extended immediate. */
16775 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16776 [(set (match_dup 0)
16777 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16781 = gen_int_mode (INTVAL (operands[3])
16782 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16783 operands[2] = gen_lowpart (SImode, operands[2]);
16787 [(set (match_operand 0 "register_operand" "")
16788 (neg (match_operand 1 "register_operand" "")))
16789 (clobber (reg:CC FLAGS_REG))]
16790 "! TARGET_PARTIAL_REG_STALL && reload_completed
16791 && (GET_MODE (operands[0]) == HImode
16792 || (GET_MODE (operands[0]) == QImode
16793 && (TARGET_PROMOTE_QImode
16794 || optimize_insn_for_size_p ())))"
16795 [(parallel [(set (match_dup 0)
16796 (neg:SI (match_dup 1)))
16797 (clobber (reg:CC FLAGS_REG))])]
16798 "operands[0] = gen_lowpart (SImode, operands[0]);
16799 operands[1] = gen_lowpart (SImode, operands[1]);")
16802 [(set (match_operand 0 "register_operand" "")
16803 (not (match_operand 1 "register_operand" "")))]
16804 "! TARGET_PARTIAL_REG_STALL && reload_completed
16805 && (GET_MODE (operands[0]) == HImode
16806 || (GET_MODE (operands[0]) == QImode
16807 && (TARGET_PROMOTE_QImode
16808 || optimize_insn_for_size_p ())))"
16809 [(set (match_dup 0)
16810 (not:SI (match_dup 1)))]
16811 "operands[0] = gen_lowpart (SImode, operands[0]);
16812 operands[1] = gen_lowpart (SImode, operands[1]);")
16815 [(set (match_operand 0 "register_operand" "")
16816 (if_then_else (match_operator 1 "ordered_comparison_operator"
16817 [(reg FLAGS_REG) (const_int 0)])
16818 (match_operand 2 "register_operand" "")
16819 (match_operand 3 "register_operand" "")))]
16820 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16821 && (GET_MODE (operands[0]) == HImode
16822 || (GET_MODE (operands[0]) == QImode
16823 && (TARGET_PROMOTE_QImode
16824 || optimize_insn_for_size_p ())))"
16825 [(set (match_dup 0)
16826 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16827 "operands[0] = gen_lowpart (SImode, operands[0]);
16828 operands[2] = gen_lowpart (SImode, operands[2]);
16829 operands[3] = gen_lowpart (SImode, operands[3]);")
16831 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16832 ;; transform a complex memory operation into two memory to register operations.
16834 ;; Don't push memory operands
16836 [(set (match_operand:SWI 0 "push_operand" "")
16837 (match_operand:SWI 1 "memory_operand" ""))
16838 (match_scratch:SWI 2 "<r>")]
16839 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16840 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16841 [(set (match_dup 2) (match_dup 1))
16842 (set (match_dup 0) (match_dup 2))])
16844 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16847 [(set (match_operand:SF 0 "push_operand" "")
16848 (match_operand:SF 1 "memory_operand" ""))
16849 (match_scratch:SF 2 "r")]
16850 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16851 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16852 [(set (match_dup 2) (match_dup 1))
16853 (set (match_dup 0) (match_dup 2))])
16855 ;; Don't move an immediate directly to memory when the instruction
16858 [(match_scratch:SWI124 1 "<r>")
16859 (set (match_operand:SWI124 0 "memory_operand" "")
16861 "optimize_insn_for_speed_p ()
16862 && !TARGET_USE_MOV0
16863 && TARGET_SPLIT_LONG_MOVES
16864 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16865 && peep2_regno_dead_p (0, FLAGS_REG)"
16866 [(parallel [(set (match_dup 2) (const_int 0))
16867 (clobber (reg:CC FLAGS_REG))])
16868 (set (match_dup 0) (match_dup 1))]
16869 "operands[2] = gen_lowpart (SImode, operands[1]);")
16872 [(match_scratch:SWI124 2 "<r>")
16873 (set (match_operand:SWI124 0 "memory_operand" "")
16874 (match_operand:SWI124 1 "immediate_operand" ""))]
16875 "optimize_insn_for_speed_p ()
16876 && TARGET_SPLIT_LONG_MOVES
16877 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16878 [(set (match_dup 2) (match_dup 1))
16879 (set (match_dup 0) (match_dup 2))])
16881 ;; Don't compare memory with zero, load and use a test instead.
16883 [(set (match_operand 0 "flags_reg_operand" "")
16884 (match_operator 1 "compare_operator"
16885 [(match_operand:SI 2 "memory_operand" "")
16887 (match_scratch:SI 3 "r")]
16888 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16889 [(set (match_dup 3) (match_dup 2))
16890 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16892 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16893 ;; Don't split NOTs with a displacement operand, because resulting XOR
16894 ;; will not be pairable anyway.
16896 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16897 ;; represented using a modRM byte. The XOR replacement is long decoded,
16898 ;; so this split helps here as well.
16900 ;; Note: Can't do this as a regular split because we can't get proper
16901 ;; lifetime information then.
16904 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16905 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16906 "optimize_insn_for_speed_p ()
16907 && ((TARGET_NOT_UNPAIRABLE
16908 && (!MEM_P (operands[0])
16909 || !memory_displacement_operand (operands[0], <MODE>mode)))
16910 || (TARGET_NOT_VECTORMODE
16911 && long_memory_operand (operands[0], <MODE>mode)))
16912 && peep2_regno_dead_p (0, FLAGS_REG)"
16913 [(parallel [(set (match_dup 0)
16914 (xor:SWI124 (match_dup 1) (const_int -1)))
16915 (clobber (reg:CC FLAGS_REG))])])
16917 ;; Non pairable "test imm, reg" instructions can be translated to
16918 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16919 ;; byte opcode instead of two, have a short form for byte operands),
16920 ;; so do it for other CPUs as well. Given that the value was dead,
16921 ;; this should not create any new dependencies. Pass on the sub-word
16922 ;; versions if we're concerned about partial register stalls.
16925 [(set (match_operand 0 "flags_reg_operand" "")
16926 (match_operator 1 "compare_operator"
16927 [(and:SI (match_operand:SI 2 "register_operand" "")
16928 (match_operand:SI 3 "immediate_operand" ""))
16930 "ix86_match_ccmode (insn, CCNOmode)
16931 && (true_regnum (operands[2]) != AX_REG
16932 || satisfies_constraint_K (operands[3]))
16933 && peep2_reg_dead_p (1, operands[2])"
16935 [(set (match_dup 0)
16936 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16939 (and:SI (match_dup 2) (match_dup 3)))])])
16941 ;; We don't need to handle HImode case, because it will be promoted to SImode
16942 ;; on ! TARGET_PARTIAL_REG_STALL
16945 [(set (match_operand 0 "flags_reg_operand" "")
16946 (match_operator 1 "compare_operator"
16947 [(and:QI (match_operand:QI 2 "register_operand" "")
16948 (match_operand:QI 3 "immediate_operand" ""))
16950 "! TARGET_PARTIAL_REG_STALL
16951 && ix86_match_ccmode (insn, CCNOmode)
16952 && true_regnum (operands[2]) != AX_REG
16953 && peep2_reg_dead_p (1, operands[2])"
16955 [(set (match_dup 0)
16956 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16959 (and:QI (match_dup 2) (match_dup 3)))])])
16962 [(set (match_operand 0 "flags_reg_operand" "")
16963 (match_operator 1 "compare_operator"
16966 (match_operand 2 "ext_register_operand" "")
16969 (match_operand 3 "const_int_operand" ""))
16971 "! TARGET_PARTIAL_REG_STALL
16972 && ix86_match_ccmode (insn, CCNOmode)
16973 && true_regnum (operands[2]) != AX_REG
16974 && peep2_reg_dead_p (1, operands[2])"
16975 [(parallel [(set (match_dup 0)
16984 (set (zero_extract:SI (match_dup 2)
16992 (match_dup 3)))])])
16994 ;; Don't do logical operations with memory inputs.
16996 [(match_scratch:SI 2 "r")
16997 (parallel [(set (match_operand:SI 0 "register_operand" "")
16998 (match_operator:SI 3 "arith_or_logical_operator"
17000 (match_operand:SI 1 "memory_operand" "")]))
17001 (clobber (reg:CC FLAGS_REG))])]
17002 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17003 [(set (match_dup 2) (match_dup 1))
17004 (parallel [(set (match_dup 0)
17005 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17006 (clobber (reg:CC FLAGS_REG))])])
17009 [(match_scratch:SI 2 "r")
17010 (parallel [(set (match_operand:SI 0 "register_operand" "")
17011 (match_operator:SI 3 "arith_or_logical_operator"
17012 [(match_operand:SI 1 "memory_operand" "")
17014 (clobber (reg:CC FLAGS_REG))])]
17015 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17016 [(set (match_dup 2) (match_dup 1))
17017 (parallel [(set (match_dup 0)
17018 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17019 (clobber (reg:CC FLAGS_REG))])])
17021 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17022 ;; refers to the destination of the load!
17025 [(set (match_operand:SI 0 "register_operand" "")
17026 (match_operand:SI 1 "register_operand" ""))
17027 (parallel [(set (match_dup 0)
17028 (match_operator:SI 3 "commutative_operator"
17030 (match_operand:SI 2 "memory_operand" "")]))
17031 (clobber (reg:CC FLAGS_REG))])]
17032 "REGNO (operands[0]) != REGNO (operands[1])
17033 && GENERAL_REGNO_P (REGNO (operands[0]))
17034 && GENERAL_REGNO_P (REGNO (operands[1]))"
17035 [(set (match_dup 0) (match_dup 4))
17036 (parallel [(set (match_dup 0)
17037 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17038 (clobber (reg:CC FLAGS_REG))])]
17039 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17042 [(set (match_operand 0 "register_operand" "")
17043 (match_operand 1 "register_operand" ""))
17045 (match_operator 3 "commutative_operator"
17047 (match_operand 2 "memory_operand" "")]))]
17048 "REGNO (operands[0]) != REGNO (operands[1])
17049 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17050 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17051 [(set (match_dup 0) (match_dup 2))
17053 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17055 ; Don't do logical operations with memory outputs
17057 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17058 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17059 ; the same decoder scheduling characteristics as the original.
17062 [(match_scratch:SI 2 "r")
17063 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17064 (match_operator:SI 3 "arith_or_logical_operator"
17066 (match_operand:SI 1 "nonmemory_operand" "")]))
17067 (clobber (reg:CC FLAGS_REG))])]
17068 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17069 /* Do not split stack checking probes. */
17070 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17071 [(set (match_dup 2) (match_dup 0))
17072 (parallel [(set (match_dup 2)
17073 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17074 (clobber (reg:CC FLAGS_REG))])
17075 (set (match_dup 0) (match_dup 2))])
17078 [(match_scratch:SI 2 "r")
17079 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17080 (match_operator:SI 3 "arith_or_logical_operator"
17081 [(match_operand:SI 1 "nonmemory_operand" "")
17083 (clobber (reg:CC FLAGS_REG))])]
17084 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17085 /* Do not split stack checking probes. */
17086 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17087 [(set (match_dup 2) (match_dup 0))
17088 (parallel [(set (match_dup 2)
17089 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17090 (clobber (reg:CC FLAGS_REG))])
17091 (set (match_dup 0) (match_dup 2))])
17093 ;; Attempt to always use XOR for zeroing registers.
17095 [(set (match_operand 0 "register_operand" "")
17096 (match_operand 1 "const0_operand" ""))]
17097 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17098 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17099 && GENERAL_REG_P (operands[0])
17100 && peep2_regno_dead_p (0, FLAGS_REG)"
17101 [(parallel [(set (match_dup 0) (const_int 0))
17102 (clobber (reg:CC FLAGS_REG))])]
17103 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17106 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17108 "(GET_MODE (operands[0]) == QImode
17109 || GET_MODE (operands[0]) == HImode)
17110 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17111 && peep2_regno_dead_p (0, FLAGS_REG)"
17112 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17113 (clobber (reg:CC FLAGS_REG))])])
17115 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17117 [(set (match_operand:SWI248 0 "register_operand" "")
17119 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17120 && peep2_regno_dead_p (0, FLAGS_REG)"
17121 [(parallel [(set (match_dup 0) (const_int -1))
17122 (clobber (reg:CC FLAGS_REG))])]
17124 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17125 operands[0] = gen_lowpart (SImode, operands[0]);
17128 ;; Attempt to convert simple lea to add/shift.
17129 ;; These can be created by move expanders.
17132 [(set (match_operand:SWI48 0 "register_operand" "")
17133 (plus:SWI48 (match_dup 0)
17134 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17135 "peep2_regno_dead_p (0, FLAGS_REG)"
17136 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17137 (clobber (reg:CC FLAGS_REG))])])
17140 [(set (match_operand:SI 0 "register_operand" "")
17141 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17142 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17144 && peep2_regno_dead_p (0, FLAGS_REG)
17145 && REGNO (operands[0]) == REGNO (operands[1])"
17146 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17147 (clobber (reg:CC FLAGS_REG))])]
17148 "operands[2] = gen_lowpart (SImode, operands[2]);")
17151 [(set (match_operand:SWI48 0 "register_operand" "")
17152 (mult:SWI48 (match_dup 0)
17153 (match_operand:SWI48 1 "const_int_operand" "")))]
17154 "exact_log2 (INTVAL (operands[1])) >= 0
17155 && peep2_regno_dead_p (0, FLAGS_REG)"
17156 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17157 (clobber (reg:CC FLAGS_REG))])]
17158 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17161 [(set (match_operand:SI 0 "register_operand" "")
17162 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17163 (match_operand:DI 2 "const_int_operand" "")) 0))]
17165 && exact_log2 (INTVAL (operands[2])) >= 0
17166 && REGNO (operands[0]) == REGNO (operands[1])
17167 && peep2_regno_dead_p (0, FLAGS_REG)"
17168 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17169 (clobber (reg:CC FLAGS_REG))])]
17170 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17172 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17173 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17174 ;; On many CPUs it is also faster, since special hardware to avoid esp
17175 ;; dependencies is present.
17177 ;; While some of these conversions may be done using splitters, we use
17178 ;; peepholes in order to allow combine_stack_adjustments pass to see
17179 ;; nonobfuscated RTL.
17181 ;; Convert prologue esp subtractions to push.
17182 ;; We need register to push. In order to keep verify_flow_info happy we have
17184 ;; - use scratch and clobber it in order to avoid dependencies
17185 ;; - use already live register
17186 ;; We can't use the second way right now, since there is no reliable way how to
17187 ;; verify that given register is live. First choice will also most likely in
17188 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17189 ;; call clobbered registers are dead. We may want to use base pointer as an
17190 ;; alternative when no register is available later.
17193 [(match_scratch:P 1 "r")
17194 (parallel [(set (reg:P SP_REG)
17195 (plus:P (reg:P SP_REG)
17196 (match_operand:P 0 "const_int_operand" "")))
17197 (clobber (reg:CC FLAGS_REG))
17198 (clobber (mem:BLK (scratch)))])]
17199 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17200 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17201 [(clobber (match_dup 1))
17202 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17203 (clobber (mem:BLK (scratch)))])])
17206 [(match_scratch:P 1 "r")
17207 (parallel [(set (reg:P SP_REG)
17208 (plus:P (reg:P SP_REG)
17209 (match_operand:P 0 "const_int_operand" "")))
17210 (clobber (reg:CC FLAGS_REG))
17211 (clobber (mem:BLK (scratch)))])]
17212 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17213 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17214 [(clobber (match_dup 1))
17215 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17216 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17217 (clobber (mem:BLK (scratch)))])])
17219 ;; Convert esp subtractions to push.
17221 [(match_scratch:P 1 "r")
17222 (parallel [(set (reg:P SP_REG)
17223 (plus:P (reg:P SP_REG)
17224 (match_operand:P 0 "const_int_operand" "")))
17225 (clobber (reg:CC FLAGS_REG))])]
17226 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17227 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17228 [(clobber (match_dup 1))
17229 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17232 [(match_scratch:P 1 "r")
17233 (parallel [(set (reg:P SP_REG)
17234 (plus:P (reg:P SP_REG)
17235 (match_operand:P 0 "const_int_operand" "")))
17236 (clobber (reg:CC FLAGS_REG))])]
17237 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17238 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17239 [(clobber (match_dup 1))
17240 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17241 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17243 ;; Convert epilogue deallocator to pop.
17245 [(match_scratch:P 1 "r")
17246 (parallel [(set (reg:P SP_REG)
17247 (plus:P (reg:P SP_REG)
17248 (match_operand:P 0 "const_int_operand" "")))
17249 (clobber (reg:CC FLAGS_REG))
17250 (clobber (mem:BLK (scratch)))])]
17251 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17252 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17253 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17254 (clobber (mem:BLK (scratch)))])])
17256 ;; Two pops case is tricky, since pop causes dependency
17257 ;; on destination register. We use two registers if available.
17259 [(match_scratch:P 1 "r")
17260 (match_scratch:P 2 "r")
17261 (parallel [(set (reg:P SP_REG)
17262 (plus:P (reg:P SP_REG)
17263 (match_operand:P 0 "const_int_operand" "")))
17264 (clobber (reg:CC FLAGS_REG))
17265 (clobber (mem:BLK (scratch)))])]
17266 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17267 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17268 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17269 (clobber (mem:BLK (scratch)))])
17270 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17273 [(match_scratch:P 1 "r")
17274 (parallel [(set (reg:P SP_REG)
17275 (plus:P (reg:P SP_REG)
17276 (match_operand:P 0 "const_int_operand" "")))
17277 (clobber (reg:CC FLAGS_REG))
17278 (clobber (mem:BLK (scratch)))])]
17279 "optimize_insn_for_size_p ()
17280 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17281 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17282 (clobber (mem:BLK (scratch)))])
17283 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17285 ;; Convert esp additions to pop.
17287 [(match_scratch:P 1 "r")
17288 (parallel [(set (reg:P SP_REG)
17289 (plus:P (reg:P SP_REG)
17290 (match_operand:P 0 "const_int_operand" "")))
17291 (clobber (reg:CC FLAGS_REG))])]
17292 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17293 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17295 ;; Two pops case is tricky, since pop causes dependency
17296 ;; on destination register. We use two registers if available.
17298 [(match_scratch:P 1 "r")
17299 (match_scratch:P 2 "r")
17300 (parallel [(set (reg:P SP_REG)
17301 (plus:P (reg:P SP_REG)
17302 (match_operand:P 0 "const_int_operand" "")))
17303 (clobber (reg:CC FLAGS_REG))])]
17304 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17305 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17306 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17309 [(match_scratch:P 1 "r")
17310 (parallel [(set (reg:P SP_REG)
17311 (plus:P (reg:P SP_REG)
17312 (match_operand:P 0 "const_int_operand" "")))
17313 (clobber (reg:CC FLAGS_REG))])]
17314 "optimize_insn_for_size_p ()
17315 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17316 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17317 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17319 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17320 ;; required and register dies. Similarly for 128 to -128.
17322 [(set (match_operand 0 "flags_reg_operand" "")
17323 (match_operator 1 "compare_operator"
17324 [(match_operand 2 "register_operand" "")
17325 (match_operand 3 "const_int_operand" "")]))]
17326 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17327 && incdec_operand (operands[3], GET_MODE (operands[3])))
17328 || (!TARGET_FUSE_CMP_AND_BRANCH
17329 && INTVAL (operands[3]) == 128))
17330 && ix86_match_ccmode (insn, CCGCmode)
17331 && peep2_reg_dead_p (1, operands[2])"
17332 [(parallel [(set (match_dup 0)
17333 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17334 (clobber (match_dup 2))])])
17336 ;; Convert imul by three, five and nine into lea
17339 [(set (match_operand:SWI48 0 "register_operand" "")
17340 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17341 (match_operand:SWI48 2 "const_int_operand" "")))
17342 (clobber (reg:CC FLAGS_REG))])]
17343 "INTVAL (operands[2]) == 3
17344 || INTVAL (operands[2]) == 5
17345 || INTVAL (operands[2]) == 9"
17346 [(set (match_dup 0)
17347 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17349 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17353 [(set (match_operand:SWI48 0 "register_operand" "")
17354 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17355 (match_operand:SWI48 2 "const_int_operand" "")))
17356 (clobber (reg:CC FLAGS_REG))])]
17357 "optimize_insn_for_speed_p ()
17358 && (INTVAL (operands[2]) == 3
17359 || INTVAL (operands[2]) == 5
17360 || INTVAL (operands[2]) == 9)"
17361 [(set (match_dup 0) (match_dup 1))
17363 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17365 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17367 ;; imul $32bit_imm, mem, reg is vector decoded, while
17368 ;; imul $32bit_imm, reg, reg is direct decoded.
17370 [(match_scratch:SWI48 3 "r")
17371 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17372 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17373 (match_operand:SWI48 2 "immediate_operand" "")))
17374 (clobber (reg:CC FLAGS_REG))])]
17375 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17376 && !satisfies_constraint_K (operands[2])"
17377 [(set (match_dup 3) (match_dup 1))
17378 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17379 (clobber (reg:CC FLAGS_REG))])])
17382 [(match_scratch:SI 3 "r")
17383 (parallel [(set (match_operand:DI 0 "register_operand" "")
17385 (mult:SI (match_operand:SI 1 "memory_operand" "")
17386 (match_operand:SI 2 "immediate_operand" ""))))
17387 (clobber (reg:CC FLAGS_REG))])]
17389 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17390 && !satisfies_constraint_K (operands[2])"
17391 [(set (match_dup 3) (match_dup 1))
17392 (parallel [(set (match_dup 0)
17393 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17394 (clobber (reg:CC FLAGS_REG))])])
17396 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17397 ;; Convert it into imul reg, reg
17398 ;; It would be better to force assembler to encode instruction using long
17399 ;; immediate, but there is apparently no way to do so.
17401 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17403 (match_operand:SWI248 1 "nonimmediate_operand" "")
17404 (match_operand:SWI248 2 "const_int_operand" "")))
17405 (clobber (reg:CC FLAGS_REG))])
17406 (match_scratch:SWI248 3 "r")]
17407 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17408 && satisfies_constraint_K (operands[2])"
17409 [(set (match_dup 3) (match_dup 2))
17410 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17411 (clobber (reg:CC FLAGS_REG))])]
17413 if (!rtx_equal_p (operands[0], operands[1]))
17414 emit_move_insn (operands[0], operands[1]);
17417 ;; After splitting up read-modify operations, array accesses with memory
17418 ;; operands might end up in form:
17420 ;; movl 4(%esp), %edx
17422 ;; instead of pre-splitting:
17424 ;; addl 4(%esp), %eax
17426 ;; movl 4(%esp), %edx
17427 ;; leal (%edx,%eax,4), %eax
17430 [(match_scratch:P 5 "r")
17431 (parallel [(set (match_operand 0 "register_operand" "")
17432 (ashift (match_operand 1 "register_operand" "")
17433 (match_operand 2 "const_int_operand" "")))
17434 (clobber (reg:CC FLAGS_REG))])
17435 (parallel [(set (match_operand 3 "register_operand" "")
17436 (plus (match_dup 0)
17437 (match_operand 4 "x86_64_general_operand" "")))
17438 (clobber (reg:CC FLAGS_REG))])]
17439 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17440 /* Validate MODE for lea. */
17441 && ((!TARGET_PARTIAL_REG_STALL
17442 && (GET_MODE (operands[0]) == QImode
17443 || GET_MODE (operands[0]) == HImode))
17444 || GET_MODE (operands[0]) == SImode
17445 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17446 && (rtx_equal_p (operands[0], operands[3])
17447 || peep2_reg_dead_p (2, operands[0]))
17448 /* We reorder load and the shift. */
17449 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17450 [(set (match_dup 5) (match_dup 4))
17451 (set (match_dup 0) (match_dup 1))]
17453 enum machine_mode op1mode = GET_MODE (operands[1]);
17454 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17455 int scale = 1 << INTVAL (operands[2]);
17456 rtx index = gen_lowpart (Pmode, operands[1]);
17457 rtx base = gen_lowpart (Pmode, operands[5]);
17458 rtx dest = gen_lowpart (mode, operands[3]);
17460 operands[1] = gen_rtx_PLUS (Pmode, base,
17461 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17462 operands[5] = base;
17464 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17465 if (op1mode != Pmode)
17466 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17467 operands[0] = dest;
17470 ;; Call-value patterns last so that the wildcard operand does not
17471 ;; disrupt insn-recog's switch tables.
17473 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17475 [(set (match_operand 0 "" "")
17476 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17477 (match_operand:SI 2 "" "")))
17478 (set (reg:SI SP_REG)
17479 (plus:SI (reg:SI SP_REG)
17480 (match_operand:SI 3 "immediate_operand" "")))])
17481 (unspec [(match_operand 4 "const_int_operand" "")]
17482 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17483 "TARGET_VZEROUPPER && !TARGET_64BIT"
17485 "&& reload_completed"
17487 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17488 [(set_attr "type" "callv")])
17490 (define_insn "*call_value_pop_0"
17491 [(set (match_operand 0 "" "")
17492 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
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" "")))]
17498 { return ix86_output_call_insn (insn, operands[1], 1); }
17499 [(set_attr "type" "callv")])
17501 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17503 [(set (match_operand 0 "" "")
17504 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17505 (match_operand:SI 2 "" "")))
17506 (set (reg:SI SP_REG)
17507 (plus:SI (reg:SI SP_REG)
17508 (match_operand:SI 3 "immediate_operand" "i")))])
17509 (unspec [(match_operand 4 "const_int_operand" "")]
17510 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17511 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17513 "&& reload_completed"
17515 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17516 [(set_attr "type" "callv")])
17518 (define_insn "*call_value_pop_1"
17519 [(set (match_operand 0 "" "")
17520 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17521 (match_operand:SI 2 "" "")))
17522 (set (reg:SI SP_REG)
17523 (plus:SI (reg:SI SP_REG)
17524 (match_operand:SI 3 "immediate_operand" "i")))]
17525 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17526 { return ix86_output_call_insn (insn, operands[1], 1); }
17527 [(set_attr "type" "callv")])
17529 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17531 [(set (match_operand 0 "" "")
17532 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17533 (match_operand:SI 2 "" "")))
17534 (set (reg:SI SP_REG)
17535 (plus:SI (reg:SI SP_REG)
17536 (match_operand:SI 3 "immediate_operand" "i,i")))])
17537 (unspec [(match_operand 4 "const_int_operand" "")]
17538 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17539 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17541 "&& reload_completed"
17543 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17544 [(set_attr "type" "callv")])
17546 (define_insn "*sibcall_value_pop_1"
17547 [(set (match_operand 0 "" "")
17548 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17549 (match_operand:SI 2 "" "")))
17550 (set (reg:SI SP_REG)
17551 (plus:SI (reg:SI SP_REG)
17552 (match_operand:SI 3 "immediate_operand" "i,i")))]
17553 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17554 { return ix86_output_call_insn (insn, operands[1], 1); }
17555 [(set_attr "type" "callv")])
17557 (define_insn_and_split "*call_value_0_vzeroupper"
17558 [(set (match_operand 0 "" "")
17559 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17560 (match_operand:SI 2 "" "")))
17561 (unspec [(match_operand 3 "const_int_operand" "")]
17562 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17563 "TARGET_VZEROUPPER && !TARGET_64BIT"
17565 "&& reload_completed"
17567 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17568 [(set_attr "type" "callv")])
17570 (define_insn "*call_value_0"
17571 [(set (match_operand 0 "" "")
17572 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17573 (match_operand:SI 2 "" "")))]
17575 { return ix86_output_call_insn (insn, operands[1], 1); }
17576 [(set_attr "type" "callv")])
17578 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17579 [(set (match_operand 0 "" "")
17580 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17581 (match_operand:DI 2 "const_int_operand" "")))
17582 (unspec [(match_operand 3 "const_int_operand" "")]
17583 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17584 "TARGET_VZEROUPPER && TARGET_64BIT"
17586 "&& reload_completed"
17588 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17589 [(set_attr "type" "callv")])
17591 (define_insn "*call_value_0_rex64"
17592 [(set (match_operand 0 "" "")
17593 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17594 (match_operand:DI 2 "const_int_operand" "")))]
17596 { return ix86_output_call_insn (insn, operands[1], 1); }
17597 [(set_attr "type" "callv")])
17599 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17601 [(set (match_operand 0 "" "")
17602 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17603 (match_operand:DI 2 "const_int_operand" "")))
17604 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17605 (clobber (reg:TI XMM6_REG))
17606 (clobber (reg:TI XMM7_REG))
17607 (clobber (reg:TI XMM8_REG))
17608 (clobber (reg:TI XMM9_REG))
17609 (clobber (reg:TI XMM10_REG))
17610 (clobber (reg:TI XMM11_REG))
17611 (clobber (reg:TI XMM12_REG))
17612 (clobber (reg:TI XMM13_REG))
17613 (clobber (reg:TI XMM14_REG))
17614 (clobber (reg:TI XMM15_REG))
17615 (clobber (reg:DI SI_REG))
17616 (clobber (reg:DI DI_REG))])
17617 (unspec [(match_operand 3 "const_int_operand" "")]
17618 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17619 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17621 "&& reload_completed"
17623 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17624 [(set_attr "type" "callv")])
17626 (define_insn "*call_value_0_rex64_ms_sysv"
17627 [(set (match_operand 0 "" "")
17628 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17629 (match_operand:DI 2 "const_int_operand" "")))
17630 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17631 (clobber (reg:TI XMM6_REG))
17632 (clobber (reg:TI XMM7_REG))
17633 (clobber (reg:TI XMM8_REG))
17634 (clobber (reg:TI XMM9_REG))
17635 (clobber (reg:TI XMM10_REG))
17636 (clobber (reg:TI XMM11_REG))
17637 (clobber (reg:TI XMM12_REG))
17638 (clobber (reg:TI XMM13_REG))
17639 (clobber (reg:TI XMM14_REG))
17640 (clobber (reg:TI XMM15_REG))
17641 (clobber (reg:DI SI_REG))
17642 (clobber (reg:DI DI_REG))]
17643 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17644 { return ix86_output_call_insn (insn, operands[1], 1); }
17645 [(set_attr "type" "callv")])
17647 (define_insn_and_split "*call_value_1_vzeroupper"
17648 [(set (match_operand 0 "" "")
17649 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17650 (match_operand:SI 2 "" "")))
17651 (unspec [(match_operand 3 "const_int_operand" "")]
17652 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17653 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17655 "&& reload_completed"
17657 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17658 [(set_attr "type" "callv")])
17660 (define_insn "*call_value_1"
17661 [(set (match_operand 0 "" "")
17662 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17663 (match_operand:SI 2 "" "")))]
17664 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17665 { return ix86_output_call_insn (insn, operands[1], 1); }
17666 [(set_attr "type" "callv")])
17668 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17669 [(set (match_operand 0 "" "")
17670 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17671 (match_operand:SI 2 "" "")))
17672 (unspec [(match_operand 3 "const_int_operand" "")]
17673 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17674 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17676 "&& reload_completed"
17678 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17679 [(set_attr "type" "callv")])
17681 (define_insn "*sibcall_value_1"
17682 [(set (match_operand 0 "" "")
17683 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17684 (match_operand:SI 2 "" "")))]
17685 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17686 { return ix86_output_call_insn (insn, operands[1], 1); }
17687 [(set_attr "type" "callv")])
17689 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17690 [(set (match_operand 0 "" "")
17691 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17692 (match_operand:DI 2 "" "")))
17693 (unspec [(match_operand 3 "const_int_operand" "")]
17694 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17695 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17696 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17698 "&& reload_completed"
17700 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17701 [(set_attr "type" "callv")])
17703 (define_insn "*call_value_1_rex64"
17704 [(set (match_operand 0 "" "")
17705 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17706 (match_operand:DI 2 "" "")))]
17707 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17708 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17709 { return ix86_output_call_insn (insn, operands[1], 1); }
17710 [(set_attr "type" "callv")])
17712 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17714 [(set (match_operand 0 "" "")
17715 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17716 (match_operand:DI 2 "" "")))
17717 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17718 (clobber (reg:TI XMM6_REG))
17719 (clobber (reg:TI XMM7_REG))
17720 (clobber (reg:TI XMM8_REG))
17721 (clobber (reg:TI XMM9_REG))
17722 (clobber (reg:TI XMM10_REG))
17723 (clobber (reg:TI XMM11_REG))
17724 (clobber (reg:TI XMM12_REG))
17725 (clobber (reg:TI XMM13_REG))
17726 (clobber (reg:TI XMM14_REG))
17727 (clobber (reg:TI XMM15_REG))
17728 (clobber (reg:DI SI_REG))
17729 (clobber (reg:DI DI_REG))])
17730 (unspec [(match_operand 3 "const_int_operand" "")]
17731 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17732 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17734 "&& reload_completed"
17736 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17737 [(set_attr "type" "callv")])
17739 (define_insn "*call_value_1_rex64_ms_sysv"
17740 [(set (match_operand 0 "" "")
17741 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17742 (match_operand:DI 2 "" "")))
17743 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17744 (clobber (reg:TI XMM6_REG))
17745 (clobber (reg:TI XMM7_REG))
17746 (clobber (reg:TI XMM8_REG))
17747 (clobber (reg:TI XMM9_REG))
17748 (clobber (reg:TI XMM10_REG))
17749 (clobber (reg:TI XMM11_REG))
17750 (clobber (reg:TI XMM12_REG))
17751 (clobber (reg:TI XMM13_REG))
17752 (clobber (reg:TI XMM14_REG))
17753 (clobber (reg:TI XMM15_REG))
17754 (clobber (reg:DI SI_REG))
17755 (clobber (reg:DI DI_REG))]
17756 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17757 { return ix86_output_call_insn (insn, operands[1], 1); }
17758 [(set_attr "type" "callv")])
17760 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17761 [(set (match_operand 0 "" "")
17762 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17763 (match_operand:DI 2 "" "")))
17764 (unspec [(match_operand 3 "const_int_operand" "")]
17765 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17766 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17768 "&& reload_completed"
17770 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17771 [(set_attr "type" "callv")])
17773 (define_insn "*call_value_1_rex64_large"
17774 [(set (match_operand 0 "" "")
17775 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17776 (match_operand:DI 2 "" "")))]
17777 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17778 { return ix86_output_call_insn (insn, operands[1], 1); }
17779 [(set_attr "type" "callv")])
17781 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17782 [(set (match_operand 0 "" "")
17783 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17784 (match_operand:DI 2 "" "")))
17785 (unspec [(match_operand 3 "const_int_operand" "")]
17786 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17787 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17789 "&& reload_completed"
17791 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17792 [(set_attr "type" "callv")])
17794 (define_insn "*sibcall_value_1_rex64"
17795 [(set (match_operand 0 "" "")
17796 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17797 (match_operand:DI 2 "" "")))]
17798 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17799 { return ix86_output_call_insn (insn, operands[1], 1); }
17800 [(set_attr "type" "callv")])
17802 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17803 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17804 ;; caught for use by garbage collectors and the like. Using an insn that
17805 ;; maps to SIGILL makes it more likely the program will rightfully die.
17806 ;; Keeping with tradition, "6" is in honor of #UD.
17807 (define_insn "trap"
17808 [(trap_if (const_int 1) (const_int 6))]
17810 { return ASM_SHORT "0x0b0f"; }
17811 [(set_attr "length" "2")])
17813 (define_expand "prefetch"
17814 [(prefetch (match_operand 0 "address_operand" "")
17815 (match_operand:SI 1 "const_int_operand" "")
17816 (match_operand:SI 2 "const_int_operand" ""))]
17817 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17819 int rw = INTVAL (operands[1]);
17820 int locality = INTVAL (operands[2]);
17822 gcc_assert (rw == 0 || rw == 1);
17823 gcc_assert (locality >= 0 && locality <= 3);
17824 gcc_assert (GET_MODE (operands[0]) == Pmode
17825 || GET_MODE (operands[0]) == VOIDmode);
17827 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17828 supported by SSE counterpart or the SSE prefetch is not available
17829 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17831 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17832 operands[2] = GEN_INT (3);
17834 operands[1] = const0_rtx;
17837 (define_insn "*prefetch_sse_<mode>"
17838 [(prefetch (match_operand:P 0 "address_operand" "p")
17840 (match_operand:SI 1 "const_int_operand" ""))]
17841 "TARGET_PREFETCH_SSE"
17843 static const char * const patterns[4] = {
17844 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17847 int locality = INTVAL (operands[1]);
17848 gcc_assert (locality >= 0 && locality <= 3);
17850 return patterns[locality];
17852 [(set_attr "type" "sse")
17853 (set_attr "atom_sse_attr" "prefetch")
17854 (set (attr "length_address")
17855 (symbol_ref "memory_address_length (operands[0])"))
17856 (set_attr "memory" "none")])
17858 (define_insn "*prefetch_3dnow_<mode>"
17859 [(prefetch (match_operand:P 0 "address_operand" "p")
17860 (match_operand:SI 1 "const_int_operand" "n")
17864 if (INTVAL (operands[1]) == 0)
17865 return "prefetch\t%a0";
17867 return "prefetchw\t%a0";
17869 [(set_attr "type" "mmx")
17870 (set (attr "length_address")
17871 (symbol_ref "memory_address_length (operands[0])"))
17872 (set_attr "memory" "none")])
17874 (define_expand "stack_protect_set"
17875 [(match_operand 0 "memory_operand" "")
17876 (match_operand 1 "memory_operand" "")]
17879 rtx (*insn)(rtx, rtx);
17881 #ifdef TARGET_THREAD_SSP_OFFSET
17882 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17883 insn = (TARGET_64BIT
17884 ? gen_stack_tls_protect_set_di
17885 : gen_stack_tls_protect_set_si);
17887 insn = (TARGET_64BIT
17888 ? gen_stack_protect_set_di
17889 : gen_stack_protect_set_si);
17892 emit_insn (insn (operands[0], operands[1]));
17896 (define_insn "stack_protect_set_<mode>"
17897 [(set (match_operand:P 0 "memory_operand" "=m")
17898 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17899 (set (match_scratch:P 2 "=&r") (const_int 0))
17900 (clobber (reg:CC FLAGS_REG))]
17902 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17903 [(set_attr "type" "multi")])
17905 (define_insn "stack_tls_protect_set_<mode>"
17906 [(set (match_operand:P 0 "memory_operand" "=m")
17907 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17908 UNSPEC_SP_TLS_SET))
17909 (set (match_scratch:P 2 "=&r") (const_int 0))
17910 (clobber (reg:CC FLAGS_REG))]
17912 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17913 [(set_attr "type" "multi")])
17915 (define_expand "stack_protect_test"
17916 [(match_operand 0 "memory_operand" "")
17917 (match_operand 1 "memory_operand" "")
17918 (match_operand 2 "" "")]
17921 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17923 rtx (*insn)(rtx, rtx, rtx);
17925 #ifdef TARGET_THREAD_SSP_OFFSET
17926 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17927 insn = (TARGET_64BIT
17928 ? gen_stack_tls_protect_test_di
17929 : gen_stack_tls_protect_test_si);
17931 insn = (TARGET_64BIT
17932 ? gen_stack_protect_test_di
17933 : gen_stack_protect_test_si);
17936 emit_insn (insn (flags, operands[0], operands[1]));
17938 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17939 flags, const0_rtx, operands[2]));
17943 (define_insn "stack_protect_test_<mode>"
17944 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17945 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17946 (match_operand:P 2 "memory_operand" "m")]
17948 (clobber (match_scratch:P 3 "=&r"))]
17950 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17951 [(set_attr "type" "multi")])
17953 (define_insn "stack_tls_protect_test_<mode>"
17954 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17955 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17956 (match_operand:P 2 "const_int_operand" "i")]
17957 UNSPEC_SP_TLS_TEST))
17958 (clobber (match_scratch:P 3 "=r"))]
17960 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17961 [(set_attr "type" "multi")])
17963 (define_insn "sse4_2_crc32<mode>"
17964 [(set (match_operand:SI 0 "register_operand" "=r")
17966 [(match_operand:SI 1 "register_operand" "0")
17967 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17969 "TARGET_SSE4_2 || TARGET_CRC32"
17970 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17971 [(set_attr "type" "sselog1")
17972 (set_attr "prefix_rep" "1")
17973 (set_attr "prefix_extra" "1")
17974 (set (attr "prefix_data16")
17975 (if_then_else (match_operand:HI 2 "" "")
17977 (const_string "*")))
17978 (set (attr "prefix_rex")
17979 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17981 (const_string "*")))
17982 (set_attr "mode" "SI")])
17984 (define_insn "sse4_2_crc32di"
17985 [(set (match_operand:DI 0 "register_operand" "=r")
17987 [(match_operand:DI 1 "register_operand" "0")
17988 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17990 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17991 "crc32{q}\t{%2, %0|%0, %2}"
17992 [(set_attr "type" "sselog1")
17993 (set_attr "prefix_rep" "1")
17994 (set_attr "prefix_extra" "1")
17995 (set_attr "mode" "DI")])
17997 (define_expand "rdpmc"
17998 [(match_operand:DI 0 "register_operand" "")
17999 (match_operand:SI 1 "register_operand" "")]
18002 rtx reg = gen_reg_rtx (DImode);
18005 /* Force operand 1 into ECX. */
18006 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18007 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18008 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18013 rtvec vec = rtvec_alloc (2);
18014 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18015 rtx upper = gen_reg_rtx (DImode);
18016 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18017 gen_rtvec (1, const0_rtx),
18019 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18020 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18022 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18023 NULL, 1, OPTAB_DIRECT);
18024 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18028 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18029 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18033 (define_insn "*rdpmc"
18034 [(set (match_operand:DI 0 "register_operand" "=A")
18035 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18039 [(set_attr "type" "other")
18040 (set_attr "length" "2")])
18042 (define_insn "*rdpmc_rex64"
18043 [(set (match_operand:DI 0 "register_operand" "=a")
18044 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18046 (set (match_operand:DI 1 "register_operand" "=d")
18047 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18050 [(set_attr "type" "other")
18051 (set_attr "length" "2")])
18053 (define_expand "rdtsc"
18054 [(set (match_operand:DI 0 "register_operand" "")
18055 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18060 rtvec vec = rtvec_alloc (2);
18061 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18062 rtx upper = gen_reg_rtx (DImode);
18063 rtx lower = gen_reg_rtx (DImode);
18064 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18065 gen_rtvec (1, const0_rtx),
18067 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18068 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18070 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18071 NULL, 1, OPTAB_DIRECT);
18072 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18074 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18079 (define_insn "*rdtsc"
18080 [(set (match_operand:DI 0 "register_operand" "=A")
18081 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18084 [(set_attr "type" "other")
18085 (set_attr "length" "2")])
18087 (define_insn "*rdtsc_rex64"
18088 [(set (match_operand:DI 0 "register_operand" "=a")
18089 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18090 (set (match_operand:DI 1 "register_operand" "=d")
18091 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18094 [(set_attr "type" "other")
18095 (set_attr "length" "2")])
18097 (define_expand "rdtscp"
18098 [(match_operand:DI 0 "register_operand" "")
18099 (match_operand:SI 1 "memory_operand" "")]
18102 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18103 gen_rtvec (1, const0_rtx),
18105 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18106 gen_rtvec (1, const0_rtx),
18108 rtx reg = gen_reg_rtx (DImode);
18109 rtx tmp = gen_reg_rtx (SImode);
18113 rtvec vec = rtvec_alloc (3);
18114 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18115 rtx upper = gen_reg_rtx (DImode);
18116 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18117 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18118 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18120 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18121 NULL, 1, OPTAB_DIRECT);
18122 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18127 rtvec vec = rtvec_alloc (2);
18128 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18129 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18130 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18133 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18134 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18138 (define_insn "*rdtscp"
18139 [(set (match_operand:DI 0 "register_operand" "=A")
18140 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18141 (set (match_operand:SI 1 "register_operand" "=c")
18142 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18145 [(set_attr "type" "other")
18146 (set_attr "length" "3")])
18148 (define_insn "*rdtscp_rex64"
18149 [(set (match_operand:DI 0 "register_operand" "=a")
18150 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18151 (set (match_operand:DI 1 "register_operand" "=d")
18152 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18153 (set (match_operand:SI 2 "register_operand" "=c")
18154 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18157 [(set_attr "type" "other")
18158 (set_attr "length" "3")])
18160 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18162 ;; LWP instructions
18164 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18166 (define_expand "lwp_llwpcb"
18167 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18168 UNSPECV_LLWP_INTRINSIC)]
18171 (define_insn "*lwp_llwpcb<mode>1"
18172 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18173 UNSPECV_LLWP_INTRINSIC)]
18176 [(set_attr "type" "lwp")
18177 (set_attr "mode" "<MODE>")
18178 (set_attr "length" "5")])
18180 (define_expand "lwp_slwpcb"
18181 [(set (match_operand 0 "register_operand" "=r")
18182 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18187 insn = (TARGET_64BIT
18189 : gen_lwp_slwpcbsi);
18191 emit_insn (insn (operands[0]));
18195 (define_insn "lwp_slwpcb<mode>"
18196 [(set (match_operand:P 0 "register_operand" "=r")
18197 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18200 [(set_attr "type" "lwp")
18201 (set_attr "mode" "<MODE>")
18202 (set_attr "length" "5")])
18204 (define_expand "lwp_lwpval<mode>3"
18205 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18206 (match_operand:SI 2 "nonimmediate_operand" "rm")
18207 (match_operand:SI 3 "const_int_operand" "i")]
18208 UNSPECV_LWPVAL_INTRINSIC)]
18210 "/* Avoid unused variable warning. */
18213 (define_insn "*lwp_lwpval<mode>3_1"
18214 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18215 (match_operand:SI 1 "nonimmediate_operand" "rm")
18216 (match_operand:SI 2 "const_int_operand" "i")]
18217 UNSPECV_LWPVAL_INTRINSIC)]
18219 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18220 [(set_attr "type" "lwp")
18221 (set_attr "mode" "<MODE>")
18222 (set (attr "length")
18223 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18225 (define_expand "lwp_lwpins<mode>3"
18226 [(set (reg:CCC FLAGS_REG)
18227 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18228 (match_operand:SI 2 "nonimmediate_operand" "rm")
18229 (match_operand:SI 3 "const_int_operand" "i")]
18230 UNSPECV_LWPINS_INTRINSIC))
18231 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18232 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18235 (define_insn "*lwp_lwpins<mode>3_1"
18236 [(set (reg:CCC FLAGS_REG)
18237 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18238 (match_operand:SI 1 "nonimmediate_operand" "rm")
18239 (match_operand:SI 2 "const_int_operand" "i")]
18240 UNSPECV_LWPINS_INTRINSIC))]
18242 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18243 [(set_attr "type" "lwp")
18244 (set_attr "mode" "<MODE>")
18245 (set (attr "length")
18246 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18248 (define_insn "rdfsbase<mode>"
18249 [(set (match_operand:SWI48 0 "register_operand" "=r")
18250 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18251 "TARGET_64BIT && TARGET_FSGSBASE"
18253 [(set_attr "type" "other")
18254 (set_attr "prefix_extra" "2")])
18256 (define_insn "rdgsbase<mode>"
18257 [(set (match_operand:SWI48 0 "register_operand" "=r")
18258 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18259 "TARGET_64BIT && TARGET_FSGSBASE"
18261 [(set_attr "type" "other")
18262 (set_attr "prefix_extra" "2")])
18264 (define_insn "wrfsbase<mode>"
18265 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18267 "TARGET_64BIT && TARGET_FSGSBASE"
18269 [(set_attr "type" "other")
18270 (set_attr "prefix_extra" "2")])
18272 (define_insn "wrgsbase<mode>"
18273 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18275 "TARGET_64BIT && TARGET_FSGSBASE"
18277 [(set_attr "type" "other")
18278 (set_attr "prefix_extra" "2")])
18280 (define_insn "rdrand<mode>_1"
18281 [(set (match_operand:SWI248 0 "register_operand" "=r")
18282 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18283 (set (reg:CCC FLAGS_REG)
18284 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18287 [(set_attr "type" "other")
18288 (set_attr "prefix_extra" "1")])
18292 (include "sync.md")