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 require movd instead of movq. */
2005 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2006 return "%vmovd\t{%1, %0|%0, %1}";
2008 return "%vmovq\t{%1, %0|%0, %1}";
2011 /* Handle broken assemblers that require movd instead of movq. */
2012 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2013 return "movd\t{%1, %0|%0, %1}";
2015 return "movq\t{%1, %0|%0, %1}";
2018 return "%vpxor\t%0, %d0";
2021 return "pxor\t%0, %0";
2027 return "lea{q}\t{%a1, %0|%0, %a1}";
2030 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2031 if (get_attr_mode (insn) == MODE_SI)
2032 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2033 else if (which_alternative == 2)
2034 return "movabs{q}\t{%1, %0|%0, %1}";
2036 return "mov{q}\t{%1, %0|%0, %1}";
2040 (cond [(eq_attr "alternative" "5")
2041 (const_string "mmx")
2042 (eq_attr "alternative" "6,7,8,9,10")
2043 (const_string "mmxmov")
2044 (eq_attr "alternative" "11")
2045 (const_string "sselog1")
2046 (eq_attr "alternative" "12,13,14,15,16")
2047 (const_string "ssemov")
2048 (eq_attr "alternative" "17,18")
2049 (const_string "ssecvt")
2050 (eq_attr "alternative" "4")
2051 (const_string "multi")
2052 (match_operand:DI 1 "pic_32bit_operand" "")
2053 (const_string "lea")
2055 (const_string "imov")))
2058 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2060 (const_string "*")))
2061 (set (attr "length_immediate")
2063 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2065 (const_string "*")))
2066 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2067 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2068 (set (attr "prefix")
2069 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2070 (const_string "maybe_vex")
2071 (const_string "orig")))
2072 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2074 ;; Convert impossible stores of immediate to existing instructions.
2075 ;; First try to get scratch register and go through it. In case this
2076 ;; fails, move by 32bit parts.
2078 [(match_scratch:DI 2 "r")
2079 (set (match_operand:DI 0 "memory_operand" "")
2080 (match_operand:DI 1 "immediate_operand" ""))]
2081 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2082 && !x86_64_immediate_operand (operands[1], DImode)"
2083 [(set (match_dup 2) (match_dup 1))
2084 (set (match_dup 0) (match_dup 2))])
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 ;; "&& 1" is needed to keep it from matching the previous pattern.
2090 [(set (match_operand:DI 0 "memory_operand" "")
2091 (match_operand:DI 1 "immediate_operand" ""))]
2092 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2093 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2094 [(set (match_dup 2) (match_dup 3))
2095 (set (match_dup 4) (match_dup 5))]
2096 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2099 [(set (match_operand:DI 0 "memory_operand" "")
2100 (match_operand:DI 1 "immediate_operand" ""))]
2101 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2102 ? epilogue_completed : reload_completed)
2103 && !symbolic_operand (operands[1], DImode)
2104 && !x86_64_immediate_operand (operands[1], DImode)"
2105 [(set (match_dup 2) (match_dup 3))
2106 (set (match_dup 4) (match_dup 5))]
2107 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2109 (define_insn "*movdi_internal"
2110 [(set (match_operand:DI 0 "nonimmediate_operand"
2111 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2112 (match_operand:DI 1 "general_operand"
2113 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2114 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2119 movq\t{%1, %0|%0, %1}
2120 movq\t{%1, %0|%0, %1}
2122 %vmovq\t{%1, %0|%0, %1}
2123 %vmovdqa\t{%1, %0|%0, %1}
2124 %vmovq\t{%1, %0|%0, %1}
2126 movlps\t{%1, %0|%0, %1}
2127 movaps\t{%1, %0|%0, %1}
2128 movlps\t{%1, %0|%0, %1}"
2130 (if_then_else (eq_attr "alternative" "9,10,11,12")
2131 (const_string "noavx")
2132 (const_string "base")))
2133 (set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2134 (set (attr "prefix")
2135 (if_then_else (eq_attr "alternative" "5,6,7,8")
2136 (const_string "maybe_vex")
2137 (const_string "orig")))
2138 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2141 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2142 (match_operand:DI 1 "general_operand" ""))]
2143 "!TARGET_64BIT && reload_completed
2144 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2145 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2147 "ix86_split_long_move (operands); DONE;")
2149 (define_insn "*movsi_internal"
2150 [(set (match_operand:SI 0 "nonimmediate_operand"
2151 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2152 (match_operand:SI 1 "general_operand"
2153 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2154 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2156 switch (get_attr_type (insn))
2159 if (get_attr_mode (insn) == MODE_TI)
2160 return "%vpxor\t%0, %d0";
2161 return "%vxorps\t%0, %d0";
2164 switch (get_attr_mode (insn))
2167 return "%vmovdqa\t{%1, %0|%0, %1}";
2169 return "%vmovaps\t{%1, %0|%0, %1}";
2171 return "%vmovd\t{%1, %0|%0, %1}";
2173 return "%vmovss\t{%1, %0|%0, %1}";
2179 return "pxor\t%0, %0";
2182 if (get_attr_mode (insn) == MODE_DI)
2183 return "movq\t{%1, %0|%0, %1}";
2184 return "movd\t{%1, %0|%0, %1}";
2187 return "lea{l}\t{%a1, %0|%0, %a1}";
2190 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2191 return "mov{l}\t{%1, %0|%0, %1}";
2195 (cond [(eq_attr "alternative" "2")
2196 (const_string "mmx")
2197 (eq_attr "alternative" "3,4,5")
2198 (const_string "mmxmov")
2199 (eq_attr "alternative" "6")
2200 (const_string "sselog1")
2201 (eq_attr "alternative" "7,8,9,10,11")
2202 (const_string "ssemov")
2203 (match_operand:DI 1 "pic_32bit_operand" "")
2204 (const_string "lea")
2206 (const_string "imov")))
2207 (set (attr "prefix")
2208 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2209 (const_string "orig")
2210 (const_string "maybe_vex")))
2211 (set (attr "prefix_data16")
2212 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2214 (const_string "*")))
2216 (cond [(eq_attr "alternative" "2,3")
2218 (eq_attr "alternative" "6,7")
2220 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2221 (const_string "V4SF")
2222 (const_string "TI"))
2223 (and (eq_attr "alternative" "8,9,10,11")
2224 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2227 (const_string "SI")))])
2229 (define_insn "*movhi_internal"
2230 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2231 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2232 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2234 switch (get_attr_type (insn))
2237 /* movzwl is faster than movw on p2 due to partial word stalls,
2238 though not as fast as an aligned movl. */
2239 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2241 if (get_attr_mode (insn) == MODE_SI)
2242 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2244 return "mov{w}\t{%1, %0|%0, %1}";
2248 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2250 (const_string "imov")
2251 (and (eq_attr "alternative" "0")
2252 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2254 (eq (symbol_ref "TARGET_HIMODE_MATH")
2256 (const_string "imov")
2257 (and (eq_attr "alternative" "1,2")
2258 (match_operand:HI 1 "aligned_operand" ""))
2259 (const_string "imov")
2260 (and (ne (symbol_ref "TARGET_MOVX")
2262 (eq_attr "alternative" "0,2"))
2263 (const_string "imovx")
2265 (const_string "imov")))
2267 (cond [(eq_attr "type" "imovx")
2269 (and (eq_attr "alternative" "1,2")
2270 (match_operand:HI 1 "aligned_operand" ""))
2272 (and (eq_attr "alternative" "0")
2273 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2275 (eq (symbol_ref "TARGET_HIMODE_MATH")
2279 (const_string "HI")))])
2281 ;; Situation is quite tricky about when to choose full sized (SImode) move
2282 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2283 ;; partial register dependency machines (such as AMD Athlon), where QImode
2284 ;; moves issue extra dependency and for partial register stalls machines
2285 ;; that don't use QImode patterns (and QImode move cause stall on the next
2288 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2289 ;; register stall machines with, where we use QImode instructions, since
2290 ;; partial register stall can be caused there. Then we use movzx.
2291 (define_insn "*movqi_internal"
2292 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2293 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2294 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2296 switch (get_attr_type (insn))
2299 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2300 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2302 if (get_attr_mode (insn) == MODE_SI)
2303 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2305 return "mov{b}\t{%1, %0|%0, %1}";
2309 (cond [(and (eq_attr "alternative" "5")
2310 (not (match_operand:QI 1 "aligned_operand" "")))
2311 (const_string "imovx")
2312 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2314 (const_string "imov")
2315 (and (eq_attr "alternative" "3")
2316 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2318 (eq (symbol_ref "TARGET_QIMODE_MATH")
2320 (const_string "imov")
2321 (eq_attr "alternative" "3,5")
2322 (const_string "imovx")
2323 (and (ne (symbol_ref "TARGET_MOVX")
2325 (eq_attr "alternative" "2"))
2326 (const_string "imovx")
2328 (const_string "imov")))
2330 (cond [(eq_attr "alternative" "3,4,5")
2332 (eq_attr "alternative" "6")
2334 (eq_attr "type" "imovx")
2336 (and (eq_attr "type" "imov")
2337 (and (eq_attr "alternative" "0,1")
2338 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2340 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2342 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2345 ;; Avoid partial register stalls when not using QImode arithmetic
2346 (and (eq_attr "type" "imov")
2347 (and (eq_attr "alternative" "0,1")
2348 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2350 (eq (symbol_ref "TARGET_QIMODE_MATH")
2354 (const_string "QI")))])
2356 ;; Stores and loads of ax to arbitrary constant address.
2357 ;; We fake an second form of instruction to force reload to load address
2358 ;; into register when rax is not available
2359 (define_insn "*movabs<mode>_1"
2360 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2361 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2362 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2364 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2365 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2366 [(set_attr "type" "imov")
2367 (set_attr "modrm" "0,*")
2368 (set_attr "length_address" "8,0")
2369 (set_attr "length_immediate" "0,*")
2370 (set_attr "memory" "store")
2371 (set_attr "mode" "<MODE>")])
2373 (define_insn "*movabs<mode>_2"
2374 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2375 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2376 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2378 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2379 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2380 [(set_attr "type" "imov")
2381 (set_attr "modrm" "0,*")
2382 (set_attr "length_address" "8,0")
2383 (set_attr "length_immediate" "0")
2384 (set_attr "memory" "load")
2385 (set_attr "mode" "<MODE>")])
2387 (define_insn "*swap<mode>"
2388 [(set (match_operand:SWI48 0 "register_operand" "+r")
2389 (match_operand:SWI48 1 "register_operand" "+r"))
2393 "xchg{<imodesuffix>}\t%1, %0"
2394 [(set_attr "type" "imov")
2395 (set_attr "mode" "<MODE>")
2396 (set_attr "pent_pair" "np")
2397 (set_attr "athlon_decode" "vector")
2398 (set_attr "amdfam10_decode" "double")
2399 (set_attr "bdver1_decode" "double")])
2401 (define_insn "*swap<mode>_1"
2402 [(set (match_operand:SWI12 0 "register_operand" "+r")
2403 (match_operand:SWI12 1 "register_operand" "+r"))
2406 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2408 [(set_attr "type" "imov")
2409 (set_attr "mode" "SI")
2410 (set_attr "pent_pair" "np")
2411 (set_attr "athlon_decode" "vector")
2412 (set_attr "amdfam10_decode" "double")
2413 (set_attr "bdver1_decode" "double")])
2415 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2416 ;; is disabled for AMDFAM10
2417 (define_insn "*swap<mode>_2"
2418 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2419 (match_operand:SWI12 1 "register_operand" "+<r>"))
2422 "TARGET_PARTIAL_REG_STALL"
2423 "xchg{<imodesuffix>}\t%1, %0"
2424 [(set_attr "type" "imov")
2425 (set_attr "mode" "<MODE>")
2426 (set_attr "pent_pair" "np")
2427 (set_attr "athlon_decode" "vector")])
2429 (define_expand "movstrict<mode>"
2430 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2431 (match_operand:SWI12 1 "general_operand" ""))]
2434 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2436 if (GET_CODE (operands[0]) == SUBREG
2437 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2439 /* Don't generate memory->memory moves, go through a register */
2440 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2441 operands[1] = force_reg (<MODE>mode, operands[1]);
2444 (define_insn "*movstrict<mode>_1"
2445 [(set (strict_low_part
2446 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2447 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2448 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2449 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2450 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2451 [(set_attr "type" "imov")
2452 (set_attr "mode" "<MODE>")])
2454 (define_insn "*movstrict<mode>_xor"
2455 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2456 (match_operand:SWI12 1 "const0_operand" ""))
2457 (clobber (reg:CC FLAGS_REG))]
2459 "xor{<imodesuffix>}\t%0, %0"
2460 [(set_attr "type" "alu1")
2461 (set_attr "mode" "<MODE>")
2462 (set_attr "length_immediate" "0")])
2464 (define_insn "*mov<mode>_extv_1"
2465 [(set (match_operand:SWI24 0 "register_operand" "=R")
2466 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2470 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2471 [(set_attr "type" "imovx")
2472 (set_attr "mode" "SI")])
2474 (define_insn "*movqi_extv_1_rex64"
2475 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2476 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2481 switch (get_attr_type (insn))
2484 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2486 return "mov{b}\t{%h1, %0|%0, %h1}";
2490 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2491 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2492 (ne (symbol_ref "TARGET_MOVX")
2494 (const_string "imovx")
2495 (const_string "imov")))
2497 (if_then_else (eq_attr "type" "imovx")
2499 (const_string "QI")))])
2501 (define_insn "*movqi_extv_1"
2502 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2503 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2508 switch (get_attr_type (insn))
2511 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2513 return "mov{b}\t{%h1, %0|%0, %h1}";
2517 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2518 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2519 (ne (symbol_ref "TARGET_MOVX")
2521 (const_string "imovx")
2522 (const_string "imov")))
2524 (if_then_else (eq_attr "type" "imovx")
2526 (const_string "QI")))])
2528 (define_insn "*mov<mode>_extzv_1"
2529 [(set (match_operand:SWI48 0 "register_operand" "=R")
2530 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2534 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535 [(set_attr "type" "imovx")
2536 (set_attr "mode" "SI")])
2538 (define_insn "*movqi_extzv_2_rex64"
2539 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2541 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2546 switch (get_attr_type (insn))
2549 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2551 return "mov{b}\t{%h1, %0|%0, %h1}";
2555 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2556 (ne (symbol_ref "TARGET_MOVX")
2558 (const_string "imovx")
2559 (const_string "imov")))
2561 (if_then_else (eq_attr "type" "imovx")
2563 (const_string "QI")))])
2565 (define_insn "*movqi_extzv_2"
2566 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2568 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2573 switch (get_attr_type (insn))
2576 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2578 return "mov{b}\t{%h1, %0|%0, %h1}";
2582 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2583 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2584 (ne (symbol_ref "TARGET_MOVX")
2586 (const_string "imovx")
2587 (const_string "imov")))
2589 (if_then_else (eq_attr "type" "imovx")
2591 (const_string "QI")))])
2593 (define_expand "mov<mode>_insv_1"
2594 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2597 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2599 (define_insn "*mov<mode>_insv_1_rex64"
2600 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2603 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2605 "mov{b}\t{%b1, %h0|%h0, %b1}"
2606 [(set_attr "type" "imov")
2607 (set_attr "mode" "QI")])
2609 (define_insn "*movsi_insv_1"
2610 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2613 (match_operand:SI 1 "general_operand" "Qmn"))]
2615 "mov{b}\t{%b1, %h0|%h0, %b1}"
2616 [(set_attr "type" "imov")
2617 (set_attr "mode" "QI")])
2619 (define_insn "*movqi_insv_2"
2620 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2623 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2626 "mov{b}\t{%h1, %h0|%h0, %h1}"
2627 [(set_attr "type" "imov")
2628 (set_attr "mode" "QI")])
2630 ;; Floating point push instructions.
2632 (define_insn "*pushtf"
2633 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2634 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2637 /* This insn should be already split before reg-stack. */
2640 [(set_attr "type" "multi")
2641 (set_attr "unit" "sse,*,*")
2642 (set_attr "mode" "TF,SI,SI")])
2645 [(set (match_operand:TF 0 "push_operand" "")
2646 (match_operand:TF 1 "sse_reg_operand" ""))]
2647 "TARGET_SSE2 && reload_completed"
2648 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2649 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2652 [(set (match_operand:TF 0 "push_operand" "")
2653 (match_operand:TF 1 "general_operand" ""))]
2654 "TARGET_SSE2 && reload_completed
2655 && !SSE_REG_P (operands[1])"
2657 "ix86_split_long_move (operands); DONE;")
2659 (define_insn "*pushxf"
2660 [(set (match_operand:XF 0 "push_operand" "=<,<")
2661 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2662 "optimize_function_for_speed_p (cfun)"
2664 /* This insn should be already split before reg-stack. */
2667 [(set_attr "type" "multi")
2668 (set_attr "unit" "i387,*")
2669 (set_attr "mode" "XF,SI")])
2671 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2672 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2673 ;; Pushing using integer instructions is longer except for constants
2674 ;; and direct memory references (assuming that any given constant is pushed
2675 ;; only once, but this ought to be handled elsewhere).
2677 (define_insn "*pushxf_nointeger"
2678 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2679 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2680 "optimize_function_for_size_p (cfun)"
2682 /* This insn should be already split before reg-stack. */
2685 [(set_attr "type" "multi")
2686 (set_attr "unit" "i387,*,*")
2687 (set_attr "mode" "XF,SI,SI")])
2690 [(set (match_operand:XF 0 "push_operand" "")
2691 (match_operand:XF 1 "fp_register_operand" ""))]
2693 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2694 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2695 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2698 [(set (match_operand:XF 0 "push_operand" "")
2699 (match_operand:XF 1 "general_operand" ""))]
2701 && !FP_REG_P (operands[1])"
2703 "ix86_split_long_move (operands); DONE;")
2705 (define_insn "*pushdf"
2706 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2707 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2708 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2710 /* This insn should be already split before reg-stack. */
2713 [(set_attr "type" "multi")
2714 (set_attr "unit" "i387,*,*")
2715 (set_attr "mode" "DF,SI,DF")])
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2719 ;; On the average, pushdf using integers can be still shorter. Allow this
2720 ;; pattern for optimize_size too.
2722 (define_insn "*pushdf_nointeger"
2723 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2724 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2725 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2727 /* This insn should be already split before reg-stack. */
2730 [(set_attr "type" "multi")
2731 (set_attr "unit" "i387,*,*,*")
2732 (set_attr "mode" "DF,SI,SI,DF")])
2734 ;; %%% Kill this when call knows how to work this out.
2736 [(set (match_operand:DF 0 "push_operand" "")
2737 (match_operand:DF 1 "any_fp_register_operand" ""))]
2739 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2740 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2743 [(set (match_operand:DF 0 "push_operand" "")
2744 (match_operand:DF 1 "general_operand" ""))]
2746 && !ANY_FP_REG_P (operands[1])"
2748 "ix86_split_long_move (operands); DONE;")
2750 (define_insn "*pushsf_rex64"
2751 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2752 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2755 /* Anything else should be already split before reg-stack. */
2756 gcc_assert (which_alternative == 1);
2757 return "push{q}\t%q1";
2759 [(set_attr "type" "multi,push,multi")
2760 (set_attr "unit" "i387,*,*")
2761 (set_attr "mode" "SF,DI,SF")])
2763 (define_insn "*pushsf"
2764 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2765 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2768 /* Anything else should be already split before reg-stack. */
2769 gcc_assert (which_alternative == 1);
2770 return "push{l}\t%1";
2772 [(set_attr "type" "multi,push,multi")
2773 (set_attr "unit" "i387,*,*")
2774 (set_attr "mode" "SF,SI,SF")])
2777 [(set (match_operand:SF 0 "push_operand" "")
2778 (match_operand:SF 1 "memory_operand" ""))]
2780 && MEM_P (operands[1])
2781 && (operands[2] = find_constant_src (insn))"
2785 ;; %%% Kill this when call knows how to work this out.
2787 [(set (match_operand:SF 0 "push_operand" "")
2788 (match_operand:SF 1 "any_fp_register_operand" ""))]
2790 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2791 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2792 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2794 ;; Floating point move instructions.
2796 (define_expand "movtf"
2797 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2798 (match_operand:TF 1 "nonimmediate_operand" ""))]
2801 ix86_expand_move (TFmode, operands);
2805 (define_expand "mov<mode>"
2806 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2807 (match_operand:X87MODEF 1 "general_operand" ""))]
2809 "ix86_expand_move (<MODE>mode, operands); DONE;")
2811 (define_insn "*movtf_internal"
2812 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2813 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2815 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2817 switch (which_alternative)
2821 if (get_attr_mode (insn) == MODE_V4SF)
2822 return "%vmovaps\t{%1, %0|%0, %1}";
2824 return "%vmovdqa\t{%1, %0|%0, %1}";
2826 if (get_attr_mode (insn) == MODE_V4SF)
2827 return "%vxorps\t%0, %d0";
2829 return "%vpxor\t%0, %d0";
2837 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2838 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2840 (cond [(eq_attr "alternative" "0,2")
2842 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2844 (const_string "V4SF")
2845 (const_string "TI"))
2846 (eq_attr "alternative" "1")
2848 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2850 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2852 (const_string "V4SF")
2853 (const_string "TI"))]
2854 (const_string "DI")))])
2857 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2858 (match_operand:TF 1 "general_operand" ""))]
2860 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2862 "ix86_split_long_move (operands); DONE;")
2864 (define_insn "*movxf_internal"
2865 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2866 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2867 "optimize_function_for_speed_p (cfun)
2868 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2869 && (!can_create_pseudo_p ()
2870 || GET_CODE (operands[1]) != CONST_DOUBLE
2871 || memory_operand (operands[0], XFmode))"
2873 switch (which_alternative)
2877 return output_387_reg_move (insn, operands);
2880 return standard_80387_constant_opcode (operands[1]);
2889 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2890 (set_attr "mode" "XF,XF,XF,SI,SI")])
2892 ;; Do not use integer registers when optimizing for size
2893 (define_insn "*movxf_internal_nointeger"
2894 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2895 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2896 "optimize_function_for_size_p (cfun)
2897 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2898 && (!can_create_pseudo_p ()
2899 || standard_80387_constant_p (operands[1])
2900 || GET_CODE (operands[1]) != CONST_DOUBLE
2901 || memory_operand (operands[0], XFmode))"
2903 switch (which_alternative)
2907 return output_387_reg_move (insn, operands);
2910 return standard_80387_constant_opcode (operands[1]);
2918 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2919 (set_attr "mode" "XF,XF,XF,SI,SI")])
2922 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2923 (match_operand:XF 1 "general_operand" ""))]
2925 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2926 && ! (FP_REG_P (operands[0]) ||
2927 (GET_CODE (operands[0]) == SUBREG
2928 && FP_REG_P (SUBREG_REG (operands[0]))))
2929 && ! (FP_REG_P (operands[1]) ||
2930 (GET_CODE (operands[1]) == SUBREG
2931 && FP_REG_P (SUBREG_REG (operands[1]))))"
2933 "ix86_split_long_move (operands); DONE;")
2935 (define_insn "*movdf_internal_rex64"
2936 [(set (match_operand:DF 0 "nonimmediate_operand"
2937 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2938 (match_operand:DF 1 "general_operand"
2939 "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2940 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2941 && (!can_create_pseudo_p ()
2942 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2943 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2944 && optimize_function_for_size_p (cfun)
2945 && standard_80387_constant_p (operands[1]))
2946 || GET_CODE (operands[1]) != CONST_DOUBLE
2947 || memory_operand (operands[0], DFmode))"
2949 switch (which_alternative)
2953 return output_387_reg_move (insn, operands);
2956 return standard_80387_constant_opcode (operands[1]);
2960 return "mov{q}\t{%1, %0|%0, %1}";
2963 return "movabs{q}\t{%1, %0|%0, %1}";
2969 switch (get_attr_mode (insn))
2972 return "%vxorps\t%0, %d0";
2974 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2975 return "%vxorps\t%0, %d0";
2977 return "%vxorpd\t%0, %d0";
2979 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2980 return "%vxorps\t%0, %d0";
2982 return "%vpxor\t%0, %d0";
2989 switch (get_attr_mode (insn))
2992 return "%vmovaps\t{%1, %0|%0, %1}";
2994 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2995 return "%vmovaps\t{%1, %0|%0, %1}";
2997 return "%vmovapd\t{%1, %0|%0, %1}";
2999 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3000 return "%vmovaps\t{%1, %0|%0, %1}";
3002 return "%vmovdqa\t{%1, %0|%0, %1}";
3004 return "%vmovq\t{%1, %0|%0, %1}";
3006 if (TARGET_AVX && 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}";
3011 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3013 return "%vmovlps\t{%1, %d0|%d0, %1}";
3020 /* Handle broken assemblers that require movd instead of movq. */
3021 return "%vmovd\t{%1, %0|%0, %1}";
3027 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3030 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3032 (const_string "*")))
3033 (set (attr "length_immediate")
3035 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3037 (const_string "*")))
3038 (set (attr "prefix")
3039 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3040 (const_string "orig")
3041 (const_string "maybe_vex")))
3042 (set (attr "prefix_data16")
3043 (if_then_else (eq_attr "mode" "V1DF")
3045 (const_string "*")))
3047 (cond [(eq_attr "alternative" "0,1,2")
3049 (eq_attr "alternative" "3,4,5,6,11,12")
3052 /* For SSE1, we have many fewer alternatives. */
3053 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3054 (cond [(eq_attr "alternative" "7,8")
3055 (const_string "V4SF")
3057 (const_string "V2SF"))
3059 /* xorps is one byte shorter. */
3060 (eq_attr "alternative" "7")
3061 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3063 (const_string "V4SF")
3064 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3068 (const_string "V2DF"))
3070 /* For architectures resolving dependencies on
3071 whole SSE registers use APD move to break dependency
3072 chains, otherwise use short move to avoid extra work.
3074 movaps encodes one byte shorter. */
3075 (eq_attr "alternative" "8")
3077 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3079 (const_string "V4SF")
3080 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3082 (const_string "V2DF")
3084 (const_string "DF"))
3085 /* For architectures resolving dependencies on register
3086 parts we may avoid extra work to zero out upper part
3088 (eq_attr "alternative" "9")
3090 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3092 (const_string "V1DF")
3093 (const_string "DF"))
3095 (const_string "DF")))])
3097 (define_insn "*movdf_internal"
3098 [(set (match_operand:DF 0 "nonimmediate_operand"
3099 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3100 (match_operand:DF 1 "general_operand"
3101 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3102 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3103 && optimize_function_for_speed_p (cfun)
3104 && TARGET_INTEGER_DFMODE_MOVES
3105 && (!can_create_pseudo_p ()
3106 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3107 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3108 && optimize_function_for_size_p (cfun)
3109 && standard_80387_constant_p (operands[1]))
3110 || GET_CODE (operands[1]) != CONST_DOUBLE
3111 || memory_operand (operands[0], DFmode))"
3113 switch (which_alternative)
3117 return output_387_reg_move (insn, operands);
3120 return standard_80387_constant_opcode (operands[1]);
3127 switch (get_attr_mode (insn))
3130 return "%vxorps\t%0, %d0";
3132 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3133 return "%vxorps\t%0, %d0";
3135 return "%vxorpd\t%0, %d0";
3137 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3138 return "%vxorps\t%0, %d0";
3140 return "%vpxor\t%0, %d0";
3147 switch (get_attr_mode (insn))
3150 return "%vmovaps\t{%1, %0|%0, %1}";
3152 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3153 return "%vmovaps\t{%1, %0|%0, %1}";
3155 return "%vmovapd\t{%1, %0|%0, %1}";
3157 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3158 return "%vmovaps\t{%1, %0|%0, %1}";
3160 return "%vmovdqa\t{%1, %0|%0, %1}";
3162 return "%vmovq\t{%1, %0|%0, %1}";
3164 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3165 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3167 return "%vmovsd\t{%1, %0|%0, %1}";
3169 if (TARGET_AVX && REG_P (operands[0]))
3170 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3172 return "%vmovlpd\t{%1, %0|%0, %1}";
3174 if (TARGET_AVX && REG_P (operands[0]))
3175 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3177 return "%vmovlps\t{%1, %0|%0, %1}";
3186 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3187 (set (attr "prefix")
3188 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3189 (const_string "orig")
3190 (const_string "maybe_vex")))
3191 (set (attr "prefix_data16")
3192 (if_then_else (eq_attr "mode" "V1DF")
3194 (const_string "*")))
3196 (cond [(eq_attr "alternative" "0,1,2")
3198 (eq_attr "alternative" "3,4")
3201 /* For SSE1, we have many fewer alternatives. */
3202 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3203 (cond [(eq_attr "alternative" "5,6")
3204 (const_string "V4SF")
3206 (const_string "V2SF"))
3208 /* xorps is one byte shorter. */
3209 (eq_attr "alternative" "5")
3210 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3212 (const_string "V4SF")
3213 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3217 (const_string "V2DF"))
3219 /* For architectures resolving dependencies on
3220 whole SSE registers use APD move to break dependency
3221 chains, otherwise use short move to avoid extra work.
3223 movaps encodes one byte shorter. */
3224 (eq_attr "alternative" "6")
3226 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3228 (const_string "V4SF")
3229 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3231 (const_string "V2DF")
3233 (const_string "DF"))
3234 /* For architectures resolving dependencies on register
3235 parts we may avoid extra work to zero out upper part
3237 (eq_attr "alternative" "7")
3239 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3241 (const_string "V1DF")
3242 (const_string "DF"))
3244 (const_string "DF")))])
3246 ;; Moving is usually shorter when only FP registers are used. This separate
3247 ;; movdf pattern avoids the use of integer registers for FP operations
3248 ;; when optimizing for size.
3250 (define_insn "*movdf_internal_nointeger"
3251 [(set (match_operand:DF 0 "nonimmediate_operand"
3252 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3253 (match_operand:DF 1 "general_operand"
3254 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
3255 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3256 && (optimize_function_for_size_p (cfun)
3257 || !TARGET_INTEGER_DFMODE_MOVES)
3258 && (!can_create_pseudo_p ()
3259 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3260 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3261 && optimize_function_for_size_p (cfun)
3262 && !memory_operand (operands[0], DFmode)
3263 && standard_80387_constant_p (operands[1]))
3264 || GET_CODE (operands[1]) != CONST_DOUBLE
3265 || ((optimize_function_for_size_p (cfun)
3266 || !TARGET_MEMORY_MISMATCH_STALL)
3267 && memory_operand (operands[0], DFmode)))"
3269 switch (which_alternative)
3273 return output_387_reg_move (insn, operands);
3276 return standard_80387_constant_opcode (operands[1]);
3283 switch (get_attr_mode (insn))
3286 return "%vxorps\t%0, %d0";
3288 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3289 return "%vxorps\t%0, %d0";
3291 return "%vxorpd\t%0, %d0";
3293 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3294 return "%vxorps\t%0, %d0";
3296 return "%vpxor\t%0, %d0";
3303 switch (get_attr_mode (insn))
3306 return "%vmovaps\t{%1, %0|%0, %1}";
3308 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3309 return "%vmovaps\t{%1, %0|%0, %1}";
3311 return "%vmovapd\t{%1, %0|%0, %1}";
3313 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3314 return "%vmovaps\t{%1, %0|%0, %1}";
3316 return "%vmovdqa\t{%1, %0|%0, %1}";
3318 return "%vmovq\t{%1, %0|%0, %1}";
3320 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3321 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3323 return "%vmovsd\t{%1, %0|%0, %1}";
3325 if (TARGET_AVX && REG_P (operands[0]))
3326 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3328 return "%vmovlpd\t{%1, %0|%0, %1}";
3330 if (TARGET_AVX && REG_P (operands[0]))
3331 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3333 return "%vmovlps\t{%1, %0|%0, %1}";
3342 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3343 (set (attr "prefix")
3344 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3345 (const_string "orig")
3346 (const_string "maybe_vex")))
3347 (set (attr "prefix_data16")
3348 (if_then_else (eq_attr "mode" "V1DF")
3350 (const_string "*")))
3352 (cond [(eq_attr "alternative" "0,1,2")
3354 (eq_attr "alternative" "3,4")
3357 /* For SSE1, we have many fewer alternatives. */
3358 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3359 (cond [(eq_attr "alternative" "5,6")
3360 (const_string "V4SF")
3362 (const_string "V2SF"))
3364 /* xorps is one byte shorter. */
3365 (eq_attr "alternative" "5")
3366 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3368 (const_string "V4SF")
3369 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3373 (const_string "V2DF"))
3375 /* For architectures resolving dependencies on
3376 whole SSE registers use APD move to break dependency
3377 chains, otherwise use short move to avoid extra work.
3379 movaps encodes one byte shorter. */
3380 (eq_attr "alternative" "6")
3382 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3384 (const_string "V4SF")
3385 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3387 (const_string "V2DF")
3389 (const_string "DF"))
3390 /* For architectures resolving dependencies on register
3391 parts we may avoid extra work to zero out upper part
3393 (eq_attr "alternative" "7")
3395 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3397 (const_string "V1DF")
3398 (const_string "DF"))
3400 (const_string "DF")))])
3403 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3404 (match_operand:DF 1 "general_operand" ""))]
3406 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3407 && ! (ANY_FP_REG_P (operands[0]) ||
3408 (GET_CODE (operands[0]) == SUBREG
3409 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3410 && ! (ANY_FP_REG_P (operands[1]) ||
3411 (GET_CODE (operands[1]) == SUBREG
3412 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3414 "ix86_split_long_move (operands); DONE;")
3416 (define_insn "*movsf_internal"
3417 [(set (match_operand:SF 0 "nonimmediate_operand"
3418 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3419 (match_operand:SF 1 "general_operand"
3420 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3421 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3422 && (!can_create_pseudo_p ()
3423 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3424 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3425 && standard_80387_constant_p (operands[1]))
3426 || GET_CODE (operands[1]) != CONST_DOUBLE
3427 || memory_operand (operands[0], SFmode))"
3429 switch (which_alternative)
3433 return output_387_reg_move (insn, operands);
3436 return standard_80387_constant_opcode (operands[1]);
3440 return "mov{l}\t{%1, %0|%0, %1}";
3442 if (get_attr_mode (insn) == MODE_TI)
3443 return "%vpxor\t%0, %d0";
3445 return "%vxorps\t%0, %d0";
3447 if (get_attr_mode (insn) == MODE_V4SF)
3448 return "%vmovaps\t{%1, %0|%0, %1}";
3450 return "%vmovss\t{%1, %d0|%d0, %1}";
3452 if (TARGET_AVX && REG_P (operands[1]))
3453 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3455 return "%vmovss\t{%1, %0|%0, %1}";
3457 return "%vmovss\t{%1, %0|%0, %1}";
3459 case 9: case 10: case 14: case 15:
3460 return "movd\t{%1, %0|%0, %1}";
3463 return "movq\t{%1, %0|%0, %1}";
3466 return "%vmovd\t{%1, %0|%0, %1}";
3472 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3473 (set (attr "prefix")
3474 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3475 (const_string "maybe_vex")
3476 (const_string "orig")))
3478 (cond [(eq_attr "alternative" "3,4,9,10")
3480 (eq_attr "alternative" "5")
3482 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3484 (ne (symbol_ref "TARGET_SSE2")
3486 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3489 (const_string "V4SF"))
3490 /* For architectures resolving dependencies on
3491 whole SSE registers use APS move to break dependency
3492 chains, otherwise use short move to avoid extra work.
3494 Do the same for architectures resolving dependencies on
3495 the parts. While in DF mode it is better to always handle
3496 just register parts, the SF mode is different due to lack
3497 of instructions to load just part of the register. It is
3498 better to maintain the whole registers in single format
3499 to avoid problems on using packed logical operations. */
3500 (eq_attr "alternative" "6")
3502 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3504 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3506 (const_string "V4SF")
3507 (const_string "SF"))
3508 (eq_attr "alternative" "11")
3509 (const_string "DI")]
3510 (const_string "SF")))])
3513 [(set (match_operand 0 "register_operand" "")
3514 (match_operand 1 "memory_operand" ""))]
3516 && MEM_P (operands[1])
3517 && (GET_MODE (operands[0]) == TFmode
3518 || GET_MODE (operands[0]) == XFmode
3519 || GET_MODE (operands[0]) == DFmode
3520 || GET_MODE (operands[0]) == SFmode)
3521 && (operands[2] = find_constant_src (insn))"
3522 [(set (match_dup 0) (match_dup 2))]
3524 rtx c = operands[2];
3525 rtx r = operands[0];
3527 if (GET_CODE (r) == SUBREG)
3532 if (!standard_sse_constant_p (c))
3535 else if (FP_REG_P (r))
3537 if (!standard_80387_constant_p (c))
3540 else if (MMX_REG_P (r))
3545 [(set (match_operand 0 "register_operand" "")
3546 (float_extend (match_operand 1 "memory_operand" "")))]
3548 && MEM_P (operands[1])
3549 && (GET_MODE (operands[0]) == TFmode
3550 || GET_MODE (operands[0]) == XFmode
3551 || GET_MODE (operands[0]) == DFmode
3552 || GET_MODE (operands[0]) == SFmode)
3553 && (operands[2] = find_constant_src (insn))"
3554 [(set (match_dup 0) (match_dup 2))]
3556 rtx c = operands[2];
3557 rtx r = operands[0];
3559 if (GET_CODE (r) == SUBREG)
3564 if (!standard_sse_constant_p (c))
3567 else if (FP_REG_P (r))
3569 if (!standard_80387_constant_p (c))
3572 else if (MMX_REG_P (r))
3576 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3578 [(set (match_operand:X87MODEF 0 "register_operand" "")
3579 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3580 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3581 && (standard_80387_constant_p (operands[1]) == 8
3582 || standard_80387_constant_p (operands[1]) == 9)"
3583 [(set (match_dup 0)(match_dup 1))
3585 (neg:X87MODEF (match_dup 0)))]
3589 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3590 if (real_isnegzero (&r))
3591 operands[1] = CONST0_RTX (<MODE>mode);
3593 operands[1] = CONST1_RTX (<MODE>mode);
3596 (define_insn "swapxf"
3597 [(set (match_operand:XF 0 "register_operand" "+f")
3598 (match_operand:XF 1 "register_operand" "+f"))
3603 if (STACK_TOP_P (operands[0]))
3608 [(set_attr "type" "fxch")
3609 (set_attr "mode" "XF")])
3611 (define_insn "*swap<mode>"
3612 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3613 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3616 "TARGET_80387 || reload_completed"
3618 if (STACK_TOP_P (operands[0]))
3623 [(set_attr "type" "fxch")
3624 (set_attr "mode" "<MODE>")])
3626 ;; Zero extension instructions
3628 (define_expand "zero_extendsidi2"
3629 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3630 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3635 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3640 (define_insn "*zero_extendsidi2_rex64"
3641 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3643 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3646 mov\t{%k1, %k0|%k0, %k1}
3648 movd\t{%1, %0|%0, %1}
3649 movd\t{%1, %0|%0, %1}
3650 %vmovd\t{%1, %0|%0, %1}
3651 %vmovd\t{%1, %0|%0, %1}"
3652 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3653 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3654 (set_attr "prefix_0f" "0,*,*,*,*,*")
3655 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3658 [(set (match_operand:DI 0 "memory_operand" "")
3659 (zero_extend:DI (match_dup 0)))]
3661 [(set (match_dup 4) (const_int 0))]
3662 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3664 ;; %%% Kill me once multi-word ops are sane.
3665 (define_insn "zero_extendsidi2_1"
3666 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3668 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3669 (clobber (reg:CC FLAGS_REG))]
3675 movd\t{%1, %0|%0, %1}
3676 movd\t{%1, %0|%0, %1}
3677 %vmovd\t{%1, %0|%0, %1}
3678 %vmovd\t{%1, %0|%0, %1}"
3679 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3680 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3681 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3684 [(set (match_operand:DI 0 "register_operand" "")
3685 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3686 (clobber (reg:CC FLAGS_REG))]
3687 "!TARGET_64BIT && reload_completed
3688 && true_regnum (operands[0]) == true_regnum (operands[1])"
3689 [(set (match_dup 4) (const_int 0))]
3690 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3693 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3694 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3695 (clobber (reg:CC FLAGS_REG))]
3696 "!TARGET_64BIT && reload_completed
3697 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3698 [(set (match_dup 3) (match_dup 1))
3699 (set (match_dup 4) (const_int 0))]
3700 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3702 (define_insn "zero_extend<mode>di2"
3703 [(set (match_operand:DI 0 "register_operand" "=r")
3705 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3707 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3708 [(set_attr "type" "imovx")
3709 (set_attr "mode" "SI")])
3711 (define_expand "zero_extendhisi2"
3712 [(set (match_operand:SI 0 "register_operand" "")
3713 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3716 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3718 operands[1] = force_reg (HImode, operands[1]);
3719 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3724 (define_insn_and_split "zero_extendhisi2_and"
3725 [(set (match_operand:SI 0 "register_operand" "=r")
3726 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3727 (clobber (reg:CC FLAGS_REG))]
3728 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3730 "&& reload_completed"
3731 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3732 (clobber (reg:CC FLAGS_REG))])]
3734 [(set_attr "type" "alu1")
3735 (set_attr "mode" "SI")])
3737 (define_insn "*zero_extendhisi2_movzwl"
3738 [(set (match_operand:SI 0 "register_operand" "=r")
3739 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3740 "!TARGET_ZERO_EXTEND_WITH_AND
3741 || optimize_function_for_size_p (cfun)"
3742 "movz{wl|x}\t{%1, %0|%0, %1}"
3743 [(set_attr "type" "imovx")
3744 (set_attr "mode" "SI")])
3746 (define_expand "zero_extendqi<mode>2"
3748 [(set (match_operand:SWI24 0 "register_operand" "")
3749 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3750 (clobber (reg:CC FLAGS_REG))])])
3752 (define_insn "*zero_extendqi<mode>2_and"
3753 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3754 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3755 (clobber (reg:CC FLAGS_REG))]
3756 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3758 [(set_attr "type" "alu1")
3759 (set_attr "mode" "<MODE>")])
3761 ;; When source and destination does not overlap, clear destination
3762 ;; first and then do the movb
3764 [(set (match_operand:SWI24 0 "register_operand" "")
3765 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3766 (clobber (reg:CC FLAGS_REG))]
3768 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3769 && ANY_QI_REG_P (operands[0])
3770 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3771 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3772 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3774 operands[2] = gen_lowpart (QImode, operands[0]);
3775 ix86_expand_clear (operands[0]);
3778 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3779 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3780 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3781 (clobber (reg:CC FLAGS_REG))]
3782 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3784 [(set_attr "type" "imovx,alu1")
3785 (set_attr "mode" "<MODE>")])
3787 ;; For the movzbl case strip only the clobber
3789 [(set (match_operand:SWI24 0 "register_operand" "")
3790 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3791 (clobber (reg:CC FLAGS_REG))]
3793 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3794 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3796 (zero_extend:SWI24 (match_dup 1)))])
3798 ; zero extend to SImode to avoid partial register stalls
3799 (define_insn "*zero_extendqi<mode>2_movzbl"
3800 [(set (match_operand:SWI24 0 "register_operand" "=r")
3801 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3803 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3804 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3805 [(set_attr "type" "imovx")
3806 (set_attr "mode" "SI")])
3808 ;; Rest is handled by single and.
3810 [(set (match_operand:SWI24 0 "register_operand" "")
3811 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3812 (clobber (reg:CC FLAGS_REG))]
3814 && true_regnum (operands[0]) == true_regnum (operands[1])"
3815 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3816 (clobber (reg:CC FLAGS_REG))])])
3818 ;; Sign extension instructions
3820 (define_expand "extendsidi2"
3821 [(set (match_operand:DI 0 "register_operand" "")
3822 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3827 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3832 (define_insn "*extendsidi2_rex64"
3833 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3834 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3838 movs{lq|x}\t{%1, %0|%0, %1}"
3839 [(set_attr "type" "imovx")
3840 (set_attr "mode" "DI")
3841 (set_attr "prefix_0f" "0")
3842 (set_attr "modrm" "0,1")])
3844 (define_insn "extendsidi2_1"
3845 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3846 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3847 (clobber (reg:CC FLAGS_REG))
3848 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3852 ;; Extend to memory case when source register does die.
3854 [(set (match_operand:DI 0 "memory_operand" "")
3855 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3856 (clobber (reg:CC FLAGS_REG))
3857 (clobber (match_operand:SI 2 "register_operand" ""))]
3859 && dead_or_set_p (insn, operands[1])
3860 && !reg_mentioned_p (operands[1], operands[0]))"
3861 [(set (match_dup 3) (match_dup 1))
3862 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3863 (clobber (reg:CC FLAGS_REG))])
3864 (set (match_dup 4) (match_dup 1))]
3865 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3867 ;; Extend to memory case when source register does not die.
3869 [(set (match_operand:DI 0 "memory_operand" "")
3870 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3871 (clobber (reg:CC FLAGS_REG))
3872 (clobber (match_operand:SI 2 "register_operand" ""))]
3876 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3878 emit_move_insn (operands[3], operands[1]);
3880 /* Generate a cltd if possible and doing so it profitable. */
3881 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3882 && true_regnum (operands[1]) == AX_REG
3883 && true_regnum (operands[2]) == DX_REG)
3885 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3889 emit_move_insn (operands[2], operands[1]);
3890 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3892 emit_move_insn (operands[4], operands[2]);
3896 ;; Extend to register case. Optimize case where source and destination
3897 ;; registers match and cases where we can use cltd.
3899 [(set (match_operand:DI 0 "register_operand" "")
3900 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3901 (clobber (reg:CC FLAGS_REG))
3902 (clobber (match_scratch:SI 2 ""))]
3906 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3908 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3909 emit_move_insn (operands[3], operands[1]);
3911 /* Generate a cltd if possible and doing so it profitable. */
3912 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3913 && true_regnum (operands[3]) == AX_REG
3914 && true_regnum (operands[4]) == DX_REG)
3916 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3920 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3921 emit_move_insn (operands[4], operands[1]);
3923 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3927 (define_insn "extend<mode>di2"
3928 [(set (match_operand:DI 0 "register_operand" "=r")
3930 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3932 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3933 [(set_attr "type" "imovx")
3934 (set_attr "mode" "DI")])
3936 (define_insn "extendhisi2"
3937 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3938 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3941 switch (get_attr_prefix_0f (insn))
3944 return "{cwtl|cwde}";
3946 return "movs{wl|x}\t{%1, %0|%0, %1}";
3949 [(set_attr "type" "imovx")
3950 (set_attr "mode" "SI")
3951 (set (attr "prefix_0f")
3952 ;; movsx is short decodable while cwtl is vector decoded.
3953 (if_then_else (and (eq_attr "cpu" "!k6")
3954 (eq_attr "alternative" "0"))
3956 (const_string "1")))
3958 (if_then_else (eq_attr "prefix_0f" "0")
3960 (const_string "1")))])
3962 (define_insn "*extendhisi2_zext"
3963 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3966 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3969 switch (get_attr_prefix_0f (insn))
3972 return "{cwtl|cwde}";
3974 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3977 [(set_attr "type" "imovx")
3978 (set_attr "mode" "SI")
3979 (set (attr "prefix_0f")
3980 ;; movsx is short decodable while cwtl is vector decoded.
3981 (if_then_else (and (eq_attr "cpu" "!k6")
3982 (eq_attr "alternative" "0"))
3984 (const_string "1")))
3986 (if_then_else (eq_attr "prefix_0f" "0")
3988 (const_string "1")))])
3990 (define_insn "extendqisi2"
3991 [(set (match_operand:SI 0 "register_operand" "=r")
3992 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3994 "movs{bl|x}\t{%1, %0|%0, %1}"
3995 [(set_attr "type" "imovx")
3996 (set_attr "mode" "SI")])
3998 (define_insn "*extendqisi2_zext"
3999 [(set (match_operand:DI 0 "register_operand" "=r")
4001 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4003 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4004 [(set_attr "type" "imovx")
4005 (set_attr "mode" "SI")])
4007 (define_insn "extendqihi2"
4008 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4009 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4012 switch (get_attr_prefix_0f (insn))
4015 return "{cbtw|cbw}";
4017 return "movs{bw|x}\t{%1, %0|%0, %1}";
4020 [(set_attr "type" "imovx")
4021 (set_attr "mode" "HI")
4022 (set (attr "prefix_0f")
4023 ;; movsx is short decodable while cwtl is vector decoded.
4024 (if_then_else (and (eq_attr "cpu" "!k6")
4025 (eq_attr "alternative" "0"))
4027 (const_string "1")))
4029 (if_then_else (eq_attr "prefix_0f" "0")
4031 (const_string "1")))])
4033 ;; Conversions between float and double.
4035 ;; These are all no-ops in the model used for the 80387.
4036 ;; So just emit moves.
4038 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4040 [(set (match_operand:DF 0 "push_operand" "")
4041 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4043 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4044 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4047 [(set (match_operand:XF 0 "push_operand" "")
4048 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4050 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4051 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4052 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4054 (define_expand "extendsfdf2"
4055 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4056 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4057 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4059 /* ??? Needed for compress_float_constant since all fp constants
4060 are TARGET_LEGITIMATE_CONSTANT_P. */
4061 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4063 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4064 && standard_80387_constant_p (operands[1]) > 0)
4066 operands[1] = simplify_const_unary_operation
4067 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4068 emit_move_insn_1 (operands[0], operands[1]);
4071 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4075 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4077 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4079 We do the conversion post reload to avoid producing of 128bit spills
4080 that might lead to ICE on 32bit target. The sequence unlikely combine
4083 [(set (match_operand:DF 0 "register_operand" "")
4085 (match_operand:SF 1 "nonimmediate_operand" "")))]
4086 "TARGET_USE_VECTOR_FP_CONVERTS
4087 && optimize_insn_for_speed_p ()
4088 && reload_completed && SSE_REG_P (operands[0])"
4093 (parallel [(const_int 0) (const_int 1)]))))]
4095 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4096 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4097 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4098 Try to avoid move when unpacking can be done in source. */
4099 if (REG_P (operands[1]))
4101 /* If it is unsafe to overwrite upper half of source, we need
4102 to move to destination and unpack there. */
4103 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4104 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4105 && true_regnum (operands[0]) != true_regnum (operands[1]))
4107 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4108 emit_move_insn (tmp, operands[1]);
4111 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4112 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4116 emit_insn (gen_vec_setv4sf_0 (operands[3],
4117 CONST0_RTX (V4SFmode), operands[1]));
4120 (define_insn "*extendsfdf2_mixed"
4121 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4123 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4124 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4126 switch (which_alternative)
4130 return output_387_reg_move (insn, operands);
4133 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4139 [(set_attr "type" "fmov,fmov,ssecvt")
4140 (set_attr "prefix" "orig,orig,maybe_vex")
4141 (set_attr "mode" "SF,XF,DF")])
4143 (define_insn "*extendsfdf2_sse"
4144 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4145 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4146 "TARGET_SSE2 && TARGET_SSE_MATH"
4147 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4148 [(set_attr "type" "ssecvt")
4149 (set_attr "prefix" "maybe_vex")
4150 (set_attr "mode" "DF")])
4152 (define_insn "*extendsfdf2_i387"
4153 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4154 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4156 "* return output_387_reg_move (insn, operands);"
4157 [(set_attr "type" "fmov")
4158 (set_attr "mode" "SF,XF")])
4160 (define_expand "extend<mode>xf2"
4161 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4162 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4165 /* ??? Needed for compress_float_constant since all fp constants
4166 are TARGET_LEGITIMATE_CONSTANT_P. */
4167 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4169 if (standard_80387_constant_p (operands[1]) > 0)
4171 operands[1] = simplify_const_unary_operation
4172 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4173 emit_move_insn_1 (operands[0], operands[1]);
4176 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4180 (define_insn "*extend<mode>xf2_i387"
4181 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4183 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4185 "* return output_387_reg_move (insn, operands);"
4186 [(set_attr "type" "fmov")
4187 (set_attr "mode" "<MODE>,XF")])
4189 ;; %%% This seems bad bad news.
4190 ;; This cannot output into an f-reg because there is no way to be sure
4191 ;; of truncating in that case. Otherwise this is just like a simple move
4192 ;; insn. So we pretend we can output to a reg in order to get better
4193 ;; register preferencing, but we really use a stack slot.
4195 ;; Conversion from DFmode to SFmode.
4197 (define_expand "truncdfsf2"
4198 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4200 (match_operand:DF 1 "nonimmediate_operand" "")))]
4201 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4203 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4205 else if (flag_unsafe_math_optimizations)
4209 enum ix86_stack_slot slot = (virtuals_instantiated
4212 rtx temp = assign_386_stack_local (SFmode, slot);
4213 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4218 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4220 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4222 We do the conversion post reload to avoid producing of 128bit spills
4223 that might lead to ICE on 32bit target. The sequence unlikely combine
4226 [(set (match_operand:SF 0 "register_operand" "")
4228 (match_operand:DF 1 "nonimmediate_operand" "")))]
4229 "TARGET_USE_VECTOR_FP_CONVERTS
4230 && optimize_insn_for_speed_p ()
4231 && reload_completed && SSE_REG_P (operands[0])"
4234 (float_truncate:V2SF
4238 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4239 operands[3] = CONST0_RTX (V2SFmode);
4240 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4241 /* Use movsd for loading from memory, unpcklpd for registers.
4242 Try to avoid move when unpacking can be done in source, or SSE3
4243 movddup is available. */
4244 if (REG_P (operands[1]))
4247 && true_regnum (operands[0]) != true_regnum (operands[1])
4248 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4249 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4251 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4252 emit_move_insn (tmp, operands[1]);
4255 else if (!TARGET_SSE3)
4256 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4257 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4260 emit_insn (gen_sse2_loadlpd (operands[4],
4261 CONST0_RTX (V2DFmode), operands[1]));
4264 (define_expand "truncdfsf2_with_temp"
4265 [(parallel [(set (match_operand:SF 0 "" "")
4266 (float_truncate:SF (match_operand:DF 1 "" "")))
4267 (clobber (match_operand:SF 2 "" ""))])])
4269 (define_insn "*truncdfsf_fast_mixed"
4270 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4272 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4273 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4275 switch (which_alternative)
4278 return output_387_reg_move (insn, operands);
4280 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4285 [(set_attr "type" "fmov,ssecvt")
4286 (set_attr "prefix" "orig,maybe_vex")
4287 (set_attr "mode" "SF")])
4289 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4290 ;; because nothing we do here is unsafe.
4291 (define_insn "*truncdfsf_fast_sse"
4292 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4294 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4295 "TARGET_SSE2 && TARGET_SSE_MATH"
4296 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4297 [(set_attr "type" "ssecvt")
4298 (set_attr "prefix" "maybe_vex")
4299 (set_attr "mode" "SF")])
4301 (define_insn "*truncdfsf_fast_i387"
4302 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4304 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4305 "TARGET_80387 && flag_unsafe_math_optimizations"
4306 "* return output_387_reg_move (insn, operands);"
4307 [(set_attr "type" "fmov")
4308 (set_attr "mode" "SF")])
4310 (define_insn "*truncdfsf_mixed"
4311 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4313 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4314 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4315 "TARGET_MIX_SSE_I387"
4317 switch (which_alternative)
4320 return output_387_reg_move (insn, operands);
4322 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4328 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4329 (set_attr "unit" "*,*,i387,i387,i387")
4330 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4331 (set_attr "mode" "SF")])
4333 (define_insn "*truncdfsf_i387"
4334 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4336 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4337 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4340 switch (which_alternative)
4343 return output_387_reg_move (insn, operands);
4349 [(set_attr "type" "fmov,multi,multi,multi")
4350 (set_attr "unit" "*,i387,i387,i387")
4351 (set_attr "mode" "SF")])
4353 (define_insn "*truncdfsf2_i387_1"
4354 [(set (match_operand:SF 0 "memory_operand" "=m")
4356 (match_operand:DF 1 "register_operand" "f")))]
4358 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4359 && !TARGET_MIX_SSE_I387"
4360 "* return output_387_reg_move (insn, operands);"
4361 [(set_attr "type" "fmov")
4362 (set_attr "mode" "SF")])
4365 [(set (match_operand:SF 0 "register_operand" "")
4367 (match_operand:DF 1 "fp_register_operand" "")))
4368 (clobber (match_operand 2 "" ""))]
4370 [(set (match_dup 2) (match_dup 1))
4371 (set (match_dup 0) (match_dup 2))]
4372 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4374 ;; Conversion from XFmode to {SF,DF}mode
4376 (define_expand "truncxf<mode>2"
4377 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4378 (float_truncate:MODEF
4379 (match_operand:XF 1 "register_operand" "")))
4380 (clobber (match_dup 2))])]
4383 if (flag_unsafe_math_optimizations)
4385 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4386 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4387 if (reg != operands[0])
4388 emit_move_insn (operands[0], reg);
4393 enum ix86_stack_slot slot = (virtuals_instantiated
4396 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4400 (define_insn "*truncxfsf2_mixed"
4401 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4403 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4404 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4407 gcc_assert (!which_alternative);
4408 return output_387_reg_move (insn, operands);
4410 [(set_attr "type" "fmov,multi,multi,multi")
4411 (set_attr "unit" "*,i387,i387,i387")
4412 (set_attr "mode" "SF")])
4414 (define_insn "*truncxfdf2_mixed"
4415 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4417 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4418 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4421 gcc_assert (!which_alternative);
4422 return output_387_reg_move (insn, operands);
4424 [(set_attr "type" "fmov,multi,multi,multi")
4425 (set_attr "unit" "*,i387,i387,i387")
4426 (set_attr "mode" "DF")])
4428 (define_insn "truncxf<mode>2_i387_noop"
4429 [(set (match_operand:MODEF 0 "register_operand" "=f")
4430 (float_truncate:MODEF
4431 (match_operand:XF 1 "register_operand" "f")))]
4432 "TARGET_80387 && flag_unsafe_math_optimizations"
4433 "* return output_387_reg_move (insn, operands);"
4434 [(set_attr "type" "fmov")
4435 (set_attr "mode" "<MODE>")])
4437 (define_insn "*truncxf<mode>2_i387"
4438 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4439 (float_truncate:MODEF
4440 (match_operand:XF 1 "register_operand" "f")))]
4442 "* return output_387_reg_move (insn, operands);"
4443 [(set_attr "type" "fmov")
4444 (set_attr "mode" "<MODE>")])
4447 [(set (match_operand:MODEF 0 "register_operand" "")
4448 (float_truncate:MODEF
4449 (match_operand:XF 1 "register_operand" "")))
4450 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4451 "TARGET_80387 && reload_completed"
4452 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4453 (set (match_dup 0) (match_dup 2))])
4456 [(set (match_operand:MODEF 0 "memory_operand" "")
4457 (float_truncate:MODEF
4458 (match_operand:XF 1 "register_operand" "")))
4459 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4461 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4463 ;; Signed conversion to DImode.
4465 (define_expand "fix_truncxfdi2"
4466 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4467 (fix:DI (match_operand:XF 1 "register_operand" "")))
4468 (clobber (reg:CC FLAGS_REG))])]
4473 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4478 (define_expand "fix_trunc<mode>di2"
4479 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4480 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4481 (clobber (reg:CC FLAGS_REG))])]
4482 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4485 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4487 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4490 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4492 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4493 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4494 if (out != operands[0])
4495 emit_move_insn (operands[0], out);
4500 ;; Signed conversion to SImode.
4502 (define_expand "fix_truncxfsi2"
4503 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4504 (fix:SI (match_operand:XF 1 "register_operand" "")))
4505 (clobber (reg:CC FLAGS_REG))])]
4510 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4515 (define_expand "fix_trunc<mode>si2"
4516 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4517 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4518 (clobber (reg:CC FLAGS_REG))])]
4519 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4522 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4524 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4527 if (SSE_FLOAT_MODE_P (<MODE>mode))
4529 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4530 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4531 if (out != operands[0])
4532 emit_move_insn (operands[0], out);
4537 ;; Signed conversion to HImode.
4539 (define_expand "fix_trunc<mode>hi2"
4540 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4541 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4542 (clobber (reg:CC FLAGS_REG))])]
4544 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4548 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4553 ;; Unsigned conversion to SImode.
4555 (define_expand "fixuns_trunc<mode>si2"
4557 [(set (match_operand:SI 0 "register_operand" "")
4559 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4561 (clobber (match_scratch:<ssevecmode> 3 ""))
4562 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4563 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4565 enum machine_mode mode = <MODE>mode;
4566 enum machine_mode vecmode = <ssevecmode>mode;
4567 REAL_VALUE_TYPE TWO31r;
4570 if (optimize_insn_for_size_p ())
4573 real_ldexp (&TWO31r, &dconst1, 31);
4574 two31 = const_double_from_real_value (TWO31r, mode);
4575 two31 = ix86_build_const_vector (vecmode, true, two31);
4576 operands[2] = force_reg (vecmode, two31);
4579 (define_insn_and_split "*fixuns_trunc<mode>_1"
4580 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4582 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4583 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4584 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4585 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4586 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4587 && optimize_function_for_speed_p (cfun)"
4589 "&& reload_completed"
4592 ix86_split_convert_uns_si_sse (operands);
4596 ;; Unsigned conversion to HImode.
4597 ;; Without these patterns, we'll try the unsigned SI conversion which
4598 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4600 (define_expand "fixuns_trunc<mode>hi2"
4602 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4603 (set (match_operand:HI 0 "nonimmediate_operand" "")
4604 (subreg:HI (match_dup 2) 0))]
4605 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4606 "operands[2] = gen_reg_rtx (SImode);")
4608 ;; When SSE is available, it is always faster to use it!
4609 (define_insn "fix_trunc<mode>di_sse"
4610 [(set (match_operand:DI 0 "register_operand" "=r,r")
4611 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4612 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4613 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4614 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4615 [(set_attr "type" "sseicvt")
4616 (set_attr "prefix" "maybe_vex")
4617 (set_attr "prefix_rex" "1")
4618 (set_attr "mode" "<MODE>")
4619 (set_attr "athlon_decode" "double,vector")
4620 (set_attr "amdfam10_decode" "double,double")
4621 (set_attr "bdver1_decode" "double,double")])
4623 (define_insn "fix_trunc<mode>si_sse"
4624 [(set (match_operand:SI 0 "register_operand" "=r,r")
4625 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4626 "SSE_FLOAT_MODE_P (<MODE>mode)
4627 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4628 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4629 [(set_attr "type" "sseicvt")
4630 (set_attr "prefix" "maybe_vex")
4631 (set_attr "mode" "<MODE>")
4632 (set_attr "athlon_decode" "double,vector")
4633 (set_attr "amdfam10_decode" "double,double")
4634 (set_attr "bdver1_decode" "double,double")])
4636 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4638 [(set (match_operand:MODEF 0 "register_operand" "")
4639 (match_operand:MODEF 1 "memory_operand" ""))
4640 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4641 (fix:SSEMODEI24 (match_dup 0)))]
4642 "TARGET_SHORTEN_X87_SSE
4643 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4644 && peep2_reg_dead_p (2, operands[0])"
4645 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4647 ;; Avoid vector decoded forms of the instruction.
4649 [(match_scratch:DF 2 "Y2")
4650 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4651 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4652 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4653 [(set (match_dup 2) (match_dup 1))
4654 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4657 [(match_scratch:SF 2 "x")
4658 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4659 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4660 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4661 [(set (match_dup 2) (match_dup 1))
4662 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4664 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4665 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4666 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4667 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4669 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4670 && (TARGET_64BIT || <MODE>mode != DImode))
4672 && can_create_pseudo_p ()"
4677 if (memory_operand (operands[0], VOIDmode))
4678 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4681 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4682 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4688 [(set_attr "type" "fisttp")
4689 (set_attr "mode" "<MODE>")])
4691 (define_insn "fix_trunc<mode>_i387_fisttp"
4692 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4693 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4694 (clobber (match_scratch:XF 2 "=&1f"))]
4695 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4697 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4698 && (TARGET_64BIT || <MODE>mode != DImode))
4699 && TARGET_SSE_MATH)"
4700 "* return output_fix_trunc (insn, operands, 1);"
4701 [(set_attr "type" "fisttp")
4702 (set_attr "mode" "<MODE>")])
4704 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4705 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4706 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4707 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4708 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4709 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4711 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4712 && (TARGET_64BIT || <MODE>mode != DImode))
4713 && TARGET_SSE_MATH)"
4715 [(set_attr "type" "fisttp")
4716 (set_attr "mode" "<MODE>")])
4719 [(set (match_operand:X87MODEI 0 "register_operand" "")
4720 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4721 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4722 (clobber (match_scratch 3 ""))]
4724 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4725 (clobber (match_dup 3))])
4726 (set (match_dup 0) (match_dup 2))])
4729 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4730 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4731 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4732 (clobber (match_scratch 3 ""))]
4734 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4735 (clobber (match_dup 3))])])
4737 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4738 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4739 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4740 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4741 ;; function in i386.c.
4742 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4743 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4744 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4745 (clobber (reg:CC FLAGS_REG))]
4746 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4748 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4749 && (TARGET_64BIT || <MODE>mode != DImode))
4750 && can_create_pseudo_p ()"
4755 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4757 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4758 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4759 if (memory_operand (operands[0], VOIDmode))
4760 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4761 operands[2], operands[3]));
4764 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4765 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4766 operands[2], operands[3],
4771 [(set_attr "type" "fistp")
4772 (set_attr "i387_cw" "trunc")
4773 (set_attr "mode" "<MODE>")])
4775 (define_insn "fix_truncdi_i387"
4776 [(set (match_operand:DI 0 "memory_operand" "=m")
4777 (fix:DI (match_operand 1 "register_operand" "f")))
4778 (use (match_operand:HI 2 "memory_operand" "m"))
4779 (use (match_operand:HI 3 "memory_operand" "m"))
4780 (clobber (match_scratch:XF 4 "=&1f"))]
4781 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4783 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4784 "* return output_fix_trunc (insn, operands, 0);"
4785 [(set_attr "type" "fistp")
4786 (set_attr "i387_cw" "trunc")
4787 (set_attr "mode" "DI")])
4789 (define_insn "fix_truncdi_i387_with_temp"
4790 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4791 (fix:DI (match_operand 1 "register_operand" "f,f")))
4792 (use (match_operand:HI 2 "memory_operand" "m,m"))
4793 (use (match_operand:HI 3 "memory_operand" "m,m"))
4794 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4795 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4796 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4798 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4800 [(set_attr "type" "fistp")
4801 (set_attr "i387_cw" "trunc")
4802 (set_attr "mode" "DI")])
4805 [(set (match_operand:DI 0 "register_operand" "")
4806 (fix:DI (match_operand 1 "register_operand" "")))
4807 (use (match_operand:HI 2 "memory_operand" ""))
4808 (use (match_operand:HI 3 "memory_operand" ""))
4809 (clobber (match_operand:DI 4 "memory_operand" ""))
4810 (clobber (match_scratch 5 ""))]
4812 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4815 (clobber (match_dup 5))])
4816 (set (match_dup 0) (match_dup 4))])
4819 [(set (match_operand:DI 0 "memory_operand" "")
4820 (fix:DI (match_operand 1 "register_operand" "")))
4821 (use (match_operand:HI 2 "memory_operand" ""))
4822 (use (match_operand:HI 3 "memory_operand" ""))
4823 (clobber (match_operand:DI 4 "memory_operand" ""))
4824 (clobber (match_scratch 5 ""))]
4826 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4829 (clobber (match_dup 5))])])
4831 (define_insn "fix_trunc<mode>_i387"
4832 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4833 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4834 (use (match_operand:HI 2 "memory_operand" "m"))
4835 (use (match_operand:HI 3 "memory_operand" "m"))]
4836 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4838 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4839 "* return output_fix_trunc (insn, operands, 0);"
4840 [(set_attr "type" "fistp")
4841 (set_attr "i387_cw" "trunc")
4842 (set_attr "mode" "<MODE>")])
4844 (define_insn "fix_trunc<mode>_i387_with_temp"
4845 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4846 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4847 (use (match_operand:HI 2 "memory_operand" "m,m"))
4848 (use (match_operand:HI 3 "memory_operand" "m,m"))
4849 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4850 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4852 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4854 [(set_attr "type" "fistp")
4855 (set_attr "i387_cw" "trunc")
4856 (set_attr "mode" "<MODE>")])
4859 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4860 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4861 (use (match_operand:HI 2 "memory_operand" ""))
4862 (use (match_operand:HI 3 "memory_operand" ""))
4863 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4865 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4867 (use (match_dup 3))])
4868 (set (match_dup 0) (match_dup 4))])
4871 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4872 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4873 (use (match_operand:HI 2 "memory_operand" ""))
4874 (use (match_operand:HI 3 "memory_operand" ""))
4875 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4877 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4879 (use (match_dup 3))])])
4881 (define_insn "x86_fnstcw_1"
4882 [(set (match_operand:HI 0 "memory_operand" "=m")
4883 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4886 [(set (attr "length")
4887 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4888 (set_attr "mode" "HI")
4889 (set_attr "unit" "i387")
4890 (set_attr "bdver1_decode" "vector")])
4892 (define_insn "x86_fldcw_1"
4893 [(set (reg:HI FPCR_REG)
4894 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4897 [(set (attr "length")
4898 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4899 (set_attr "mode" "HI")
4900 (set_attr "unit" "i387")
4901 (set_attr "athlon_decode" "vector")
4902 (set_attr "amdfam10_decode" "vector")
4903 (set_attr "bdver1_decode" "vector")])
4905 ;; Conversion between fixed point and floating point.
4907 ;; Even though we only accept memory inputs, the backend _really_
4908 ;; wants to be able to do this between registers.
4910 (define_expand "floathi<mode>2"
4911 [(set (match_operand:X87MODEF 0 "register_operand" "")
4912 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4914 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4915 || TARGET_MIX_SSE_I387)")
4917 ;; Pre-reload splitter to add memory clobber to the pattern.
4918 (define_insn_and_split "*floathi<mode>2_1"
4919 [(set (match_operand:X87MODEF 0 "register_operand" "")
4920 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4922 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4923 || TARGET_MIX_SSE_I387)
4924 && can_create_pseudo_p ()"
4927 [(parallel [(set (match_dup 0)
4928 (float:X87MODEF (match_dup 1)))
4929 (clobber (match_dup 2))])]
4930 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4932 (define_insn "*floathi<mode>2_i387_with_temp"
4933 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4934 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4935 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4937 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4938 || TARGET_MIX_SSE_I387)"
4940 [(set_attr "type" "fmov,multi")
4941 (set_attr "mode" "<MODE>")
4942 (set_attr "unit" "*,i387")
4943 (set_attr "fp_int_src" "true")])
4945 (define_insn "*floathi<mode>2_i387"
4946 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4947 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4949 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4950 || TARGET_MIX_SSE_I387)"
4952 [(set_attr "type" "fmov")
4953 (set_attr "mode" "<MODE>")
4954 (set_attr "fp_int_src" "true")])
4957 [(set (match_operand:X87MODEF 0 "register_operand" "")
4958 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4959 (clobber (match_operand:HI 2 "memory_operand" ""))]
4961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4962 || TARGET_MIX_SSE_I387)
4963 && reload_completed"
4964 [(set (match_dup 2) (match_dup 1))
4965 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4968 [(set (match_operand:X87MODEF 0 "register_operand" "")
4969 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4970 (clobber (match_operand:HI 2 "memory_operand" ""))]
4972 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4973 || TARGET_MIX_SSE_I387)
4974 && reload_completed"
4975 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4977 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4978 [(set (match_operand:X87MODEF 0 "register_operand" "")
4980 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4982 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4983 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4985 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4986 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4987 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4989 rtx reg = gen_reg_rtx (XFmode);
4990 rtx (*insn)(rtx, rtx);
4992 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4994 if (<X87MODEF:MODE>mode == SFmode)
4995 insn = gen_truncxfsf2;
4996 else if (<X87MODEF:MODE>mode == DFmode)
4997 insn = gen_truncxfdf2;
5001 emit_insn (insn (operands[0], reg));
5006 ;; Pre-reload splitter to add memory clobber to the pattern.
5007 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5008 [(set (match_operand:X87MODEF 0 "register_operand" "")
5009 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5011 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5012 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5013 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5014 || TARGET_MIX_SSE_I387))
5015 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5016 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5017 && ((<SSEMODEI24:MODE>mode == SImode
5018 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5019 && optimize_function_for_speed_p (cfun)
5020 && flag_trapping_math)
5021 || !(TARGET_INTER_UNIT_CONVERSIONS
5022 || optimize_function_for_size_p (cfun)))))
5023 && can_create_pseudo_p ()"
5026 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5027 (clobber (match_dup 2))])]
5029 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5031 /* Avoid store forwarding (partial memory) stall penalty
5032 by passing DImode value through XMM registers. */
5033 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5034 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5035 && optimize_function_for_speed_p (cfun))
5037 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5044 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5045 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5047 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5048 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5049 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5050 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5052 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5053 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5054 (set_attr "unit" "*,i387,*,*,*")
5055 (set_attr "athlon_decode" "*,*,double,direct,double")
5056 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5057 (set_attr "bdver1_decode" "*,*,double,direct,double")
5058 (set_attr "fp_int_src" "true")])
5060 (define_insn "*floatsi<mode>2_vector_mixed"
5061 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5062 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5063 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5064 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5068 [(set_attr "type" "fmov,sseicvt")
5069 (set_attr "mode" "<MODE>,<ssevecmode>")
5070 (set_attr "unit" "i387,*")
5071 (set_attr "athlon_decode" "*,direct")
5072 (set_attr "amdfam10_decode" "*,double")
5073 (set_attr "bdver1_decode" "*,direct")
5074 (set_attr "fp_int_src" "true")])
5076 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5077 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5079 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5080 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5081 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5082 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5084 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5085 (set_attr "mode" "<MODEF:MODE>")
5086 (set_attr "unit" "*,i387,*,*")
5087 (set_attr "athlon_decode" "*,*,double,direct")
5088 (set_attr "amdfam10_decode" "*,*,vector,double")
5089 (set_attr "bdver1_decode" "*,*,double,direct")
5090 (set_attr "fp_int_src" "true")])
5093 [(set (match_operand:MODEF 0 "register_operand" "")
5094 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5095 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5096 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5097 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5098 && TARGET_INTER_UNIT_CONVERSIONS
5100 && (SSE_REG_P (operands[0])
5101 || (GET_CODE (operands[0]) == SUBREG
5102 && SSE_REG_P (operands[0])))"
5103 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5106 [(set (match_operand:MODEF 0 "register_operand" "")
5107 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5108 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5109 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5110 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5111 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5113 && (SSE_REG_P (operands[0])
5114 || (GET_CODE (operands[0]) == SUBREG
5115 && SSE_REG_P (operands[0])))"
5116 [(set (match_dup 2) (match_dup 1))
5117 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5119 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5120 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5122 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5123 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5124 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5125 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5128 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5129 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5130 [(set_attr "type" "fmov,sseicvt,sseicvt")
5131 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5132 (set_attr "mode" "<MODEF:MODE>")
5133 (set (attr "prefix_rex")
5135 (and (eq_attr "prefix" "maybe_vex")
5136 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5138 (const_string "*")))
5139 (set_attr "unit" "i387,*,*")
5140 (set_attr "athlon_decode" "*,double,direct")
5141 (set_attr "amdfam10_decode" "*,vector,double")
5142 (set_attr "bdver1_decode" "*,double,direct")
5143 (set_attr "fp_int_src" "true")])
5145 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5146 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5148 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5149 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5150 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5151 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5154 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5155 [(set_attr "type" "fmov,sseicvt")
5156 (set_attr "prefix" "orig,maybe_vex")
5157 (set_attr "mode" "<MODEF:MODE>")
5158 (set (attr "prefix_rex")
5160 (and (eq_attr "prefix" "maybe_vex")
5161 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5163 (const_string "*")))
5164 (set_attr "athlon_decode" "*,direct")
5165 (set_attr "amdfam10_decode" "*,double")
5166 (set_attr "bdver1_decode" "*,direct")
5167 (set_attr "fp_int_src" "true")])
5169 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5170 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5172 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5173 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5174 "TARGET_SSE2 && TARGET_SSE_MATH
5175 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5177 [(set_attr "type" "sseicvt")
5178 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5179 (set_attr "athlon_decode" "double,direct,double")
5180 (set_attr "amdfam10_decode" "vector,double,double")
5181 (set_attr "bdver1_decode" "double,direct,double")
5182 (set_attr "fp_int_src" "true")])
5184 (define_insn "*floatsi<mode>2_vector_sse"
5185 [(set (match_operand:MODEF 0 "register_operand" "=x")
5186 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5187 "TARGET_SSE2 && TARGET_SSE_MATH
5188 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5190 [(set_attr "type" "sseicvt")
5191 (set_attr "mode" "<MODE>")
5192 (set_attr "athlon_decode" "direct")
5193 (set_attr "amdfam10_decode" "double")
5194 (set_attr "bdver1_decode" "direct")
5195 (set_attr "fp_int_src" "true")])
5198 [(set (match_operand:MODEF 0 "register_operand" "")
5199 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5200 (clobber (match_operand:SI 2 "memory_operand" ""))]
5201 "TARGET_SSE2 && TARGET_SSE_MATH
5202 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5204 && (SSE_REG_P (operands[0])
5205 || (GET_CODE (operands[0]) == SUBREG
5206 && SSE_REG_P (operands[0])))"
5209 rtx op1 = operands[1];
5211 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5213 if (GET_CODE (op1) == SUBREG)
5214 op1 = SUBREG_REG (op1);
5216 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5218 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5219 emit_insn (gen_sse2_loadld (operands[4],
5220 CONST0_RTX (V4SImode), operands[1]));
5222 /* We can ignore possible trapping value in the
5223 high part of SSE register for non-trapping math. */
5224 else if (SSE_REG_P (op1) && !flag_trapping_math)
5225 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5228 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5229 emit_move_insn (operands[2], operands[1]);
5230 emit_insn (gen_sse2_loadld (operands[4],
5231 CONST0_RTX (V4SImode), operands[2]));
5234 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5239 [(set (match_operand:MODEF 0 "register_operand" "")
5240 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5241 (clobber (match_operand:SI 2 "memory_operand" ""))]
5242 "TARGET_SSE2 && TARGET_SSE_MATH
5243 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5245 && (SSE_REG_P (operands[0])
5246 || (GET_CODE (operands[0]) == SUBREG
5247 && SSE_REG_P (operands[0])))"
5250 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5252 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5254 emit_insn (gen_sse2_loadld (operands[4],
5255 CONST0_RTX (V4SImode), operands[1]));
5257 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5262 [(set (match_operand:MODEF 0 "register_operand" "")
5263 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5264 "TARGET_SSE2 && TARGET_SSE_MATH
5265 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5267 && (SSE_REG_P (operands[0])
5268 || (GET_CODE (operands[0]) == SUBREG
5269 && SSE_REG_P (operands[0])))"
5272 rtx op1 = operands[1];
5274 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5276 if (GET_CODE (op1) == SUBREG)
5277 op1 = SUBREG_REG (op1);
5279 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5281 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5282 emit_insn (gen_sse2_loadld (operands[4],
5283 CONST0_RTX (V4SImode), operands[1]));
5285 /* We can ignore possible trapping value in the
5286 high part of SSE register for non-trapping math. */
5287 else if (SSE_REG_P (op1) && !flag_trapping_math)
5288 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5292 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5297 [(set (match_operand:MODEF 0 "register_operand" "")
5298 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5299 "TARGET_SSE2 && TARGET_SSE_MATH
5300 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5302 && (SSE_REG_P (operands[0])
5303 || (GET_CODE (operands[0]) == SUBREG
5304 && SSE_REG_P (operands[0])))"
5307 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5309 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5311 emit_insn (gen_sse2_loadld (operands[4],
5312 CONST0_RTX (V4SImode), operands[1]));
5314 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5318 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5319 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5321 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5322 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5323 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5324 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5326 [(set_attr "type" "sseicvt")
5327 (set_attr "mode" "<MODEF:MODE>")
5328 (set_attr "athlon_decode" "double,direct")
5329 (set_attr "amdfam10_decode" "vector,double")
5330 (set_attr "bdver1_decode" "double,direct")
5331 (set_attr "fp_int_src" "true")])
5333 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5334 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5336 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5337 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5338 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5339 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5340 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5341 [(set_attr "type" "sseicvt")
5342 (set_attr "prefix" "maybe_vex")
5343 (set_attr "mode" "<MODEF:MODE>")
5344 (set (attr "prefix_rex")
5346 (and (eq_attr "prefix" "maybe_vex")
5347 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5349 (const_string "*")))
5350 (set_attr "athlon_decode" "double,direct")
5351 (set_attr "amdfam10_decode" "vector,double")
5352 (set_attr "bdver1_decode" "double,direct")
5353 (set_attr "fp_int_src" "true")])
5356 [(set (match_operand:MODEF 0 "register_operand" "")
5357 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5358 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5359 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5360 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5361 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5363 && (SSE_REG_P (operands[0])
5364 || (GET_CODE (operands[0]) == SUBREG
5365 && SSE_REG_P (operands[0])))"
5366 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5368 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5369 [(set (match_operand:MODEF 0 "register_operand" "=x")
5371 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5372 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5373 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5374 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5375 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5376 [(set_attr "type" "sseicvt")
5377 (set_attr "prefix" "maybe_vex")
5378 (set_attr "mode" "<MODEF:MODE>")
5379 (set (attr "prefix_rex")
5381 (and (eq_attr "prefix" "maybe_vex")
5382 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5384 (const_string "*")))
5385 (set_attr "athlon_decode" "direct")
5386 (set_attr "amdfam10_decode" "double")
5387 (set_attr "bdver1_decode" "direct")
5388 (set_attr "fp_int_src" "true")])
5391 [(set (match_operand:MODEF 0 "register_operand" "")
5392 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5393 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5394 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5395 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5396 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5398 && (SSE_REG_P (operands[0])
5399 || (GET_CODE (operands[0]) == SUBREG
5400 && SSE_REG_P (operands[0])))"
5401 [(set (match_dup 2) (match_dup 1))
5402 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5405 [(set (match_operand:MODEF 0 "register_operand" "")
5406 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5407 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5408 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5409 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5411 && (SSE_REG_P (operands[0])
5412 || (GET_CODE (operands[0]) == SUBREG
5413 && SSE_REG_P (operands[0])))"
5414 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5416 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5417 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5419 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5420 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5422 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5426 [(set_attr "type" "fmov,multi")
5427 (set_attr "mode" "<X87MODEF:MODE>")
5428 (set_attr "unit" "*,i387")
5429 (set_attr "fp_int_src" "true")])
5431 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5432 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5434 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5436 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5438 [(set_attr "type" "fmov")
5439 (set_attr "mode" "<X87MODEF:MODE>")
5440 (set_attr "fp_int_src" "true")])
5443 [(set (match_operand:X87MODEF 0 "register_operand" "")
5444 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5445 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5447 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5449 && FP_REG_P (operands[0])"
5450 [(set (match_dup 2) (match_dup 1))
5451 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5454 [(set (match_operand:X87MODEF 0 "register_operand" "")
5455 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5456 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5458 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5460 && FP_REG_P (operands[0])"
5461 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5463 ;; Avoid store forwarding (partial memory) stall penalty
5464 ;; by passing DImode value through XMM registers. */
5466 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5467 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5469 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5470 (clobber (match_scratch:V4SI 3 "=X,x"))
5471 (clobber (match_scratch:V4SI 4 "=X,x"))
5472 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5473 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5474 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5475 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5477 [(set_attr "type" "multi")
5478 (set_attr "mode" "<X87MODEF:MODE>")
5479 (set_attr "unit" "i387")
5480 (set_attr "fp_int_src" "true")])
5483 [(set (match_operand:X87MODEF 0 "register_operand" "")
5484 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5485 (clobber (match_scratch:V4SI 3 ""))
5486 (clobber (match_scratch:V4SI 4 ""))
5487 (clobber (match_operand:DI 2 "memory_operand" ""))]
5488 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5489 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5490 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5492 && FP_REG_P (operands[0])"
5493 [(set (match_dup 2) (match_dup 3))
5494 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5496 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5497 Assemble the 64-bit DImode value in an xmm register. */
5498 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5499 gen_rtx_SUBREG (SImode, operands[1], 0)));
5500 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5501 gen_rtx_SUBREG (SImode, operands[1], 4)));
5502 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5505 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5509 [(set (match_operand:X87MODEF 0 "register_operand" "")
5510 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5511 (clobber (match_scratch:V4SI 3 ""))
5512 (clobber (match_scratch:V4SI 4 ""))
5513 (clobber (match_operand:DI 2 "memory_operand" ""))]
5514 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5515 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5516 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5518 && FP_REG_P (operands[0])"
5519 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5521 ;; Avoid store forwarding (partial memory) stall penalty by extending
5522 ;; SImode value to DImode through XMM register instead of pushing two
5523 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5524 ;; targets benefit from this optimization. Also note that fild
5525 ;; loads from memory only.
5527 (define_insn "*floatunssi<mode>2_1"
5528 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5529 (unsigned_float:X87MODEF
5530 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5531 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5532 (clobber (match_scratch:SI 3 "=X,x"))]
5534 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5537 [(set_attr "type" "multi")
5538 (set_attr "mode" "<MODE>")])
5541 [(set (match_operand:X87MODEF 0 "register_operand" "")
5542 (unsigned_float:X87MODEF
5543 (match_operand:SI 1 "register_operand" "")))
5544 (clobber (match_operand:DI 2 "memory_operand" ""))
5545 (clobber (match_scratch:SI 3 ""))]
5547 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5549 && reload_completed"
5550 [(set (match_dup 2) (match_dup 1))
5552 (float:X87MODEF (match_dup 2)))]
5553 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5556 [(set (match_operand:X87MODEF 0 "register_operand" "")
5557 (unsigned_float:X87MODEF
5558 (match_operand:SI 1 "memory_operand" "")))
5559 (clobber (match_operand:DI 2 "memory_operand" ""))
5560 (clobber (match_scratch:SI 3 ""))]
5562 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5564 && reload_completed"
5565 [(set (match_dup 2) (match_dup 3))
5567 (float:X87MODEF (match_dup 2)))]
5569 emit_move_insn (operands[3], operands[1]);
5570 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5573 (define_expand "floatunssi<mode>2"
5575 [(set (match_operand:X87MODEF 0 "register_operand" "")
5576 (unsigned_float:X87MODEF
5577 (match_operand:SI 1 "nonimmediate_operand" "")))
5578 (clobber (match_dup 2))
5579 (clobber (match_scratch:SI 3 ""))])]
5581 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5583 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5585 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5587 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5592 enum ix86_stack_slot slot = (virtuals_instantiated
5595 operands[2] = assign_386_stack_local (DImode, slot);
5599 (define_expand "floatunsdisf2"
5600 [(use (match_operand:SF 0 "register_operand" ""))
5601 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5602 "TARGET_64BIT && TARGET_SSE_MATH"
5603 "x86_emit_floatuns (operands); DONE;")
5605 (define_expand "floatunsdidf2"
5606 [(use (match_operand:DF 0 "register_operand" ""))
5607 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5608 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5609 && TARGET_SSE2 && TARGET_SSE_MATH"
5612 x86_emit_floatuns (operands);
5614 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5620 (define_expand "add<mode>3"
5621 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5622 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5623 (match_operand:SDWIM 2 "<general_operand>" "")))]
5625 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5627 (define_insn_and_split "*add<dwi>3_doubleword"
5628 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5630 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5631 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5632 (clobber (reg:CC FLAGS_REG))]
5633 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5636 [(parallel [(set (reg:CC FLAGS_REG)
5637 (unspec:CC [(match_dup 1) (match_dup 2)]
5640 (plus:DWIH (match_dup 1) (match_dup 2)))])
5641 (parallel [(set (match_dup 3)
5645 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5647 (clobber (reg:CC FLAGS_REG))])]
5648 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5650 (define_insn "*add<mode>3_cc"
5651 [(set (reg:CC FLAGS_REG)
5653 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5654 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5656 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5657 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5658 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5659 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5660 [(set_attr "type" "alu")
5661 (set_attr "mode" "<MODE>")])
5663 (define_insn "addqi3_cc"
5664 [(set (reg:CC FLAGS_REG)
5666 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5667 (match_operand:QI 2 "general_operand" "qn,qm")]
5669 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5670 (plus:QI (match_dup 1) (match_dup 2)))]
5671 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5672 "add{b}\t{%2, %0|%0, %2}"
5673 [(set_attr "type" "alu")
5674 (set_attr "mode" "QI")])
5676 (define_insn "*lea_1"
5677 [(set (match_operand:P 0 "register_operand" "=r")
5678 (match_operand:P 1 "no_seg_address_operand" "p"))]
5680 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5681 [(set_attr "type" "lea")
5682 (set_attr "mode" "<MODE>")])
5684 (define_insn "*lea_2"
5685 [(set (match_operand:SI 0 "register_operand" "=r")
5686 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5688 "lea{l}\t{%a1, %0|%0, %a1}"
5689 [(set_attr "type" "lea")
5690 (set_attr "mode" "SI")])
5692 (define_insn "*lea_2_zext"
5693 [(set (match_operand:DI 0 "register_operand" "=r")
5695 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5697 "lea{l}\t{%a1, %k0|%k0, %a1}"
5698 [(set_attr "type" "lea")
5699 (set_attr "mode" "SI")])
5701 (define_insn "*add<mode>_1"
5702 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5704 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5705 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5706 (clobber (reg:CC FLAGS_REG))]
5707 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5709 switch (get_attr_type (insn))
5715 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5716 if (operands[2] == const1_rtx)
5717 return "inc{<imodesuffix>}\t%0";
5720 gcc_assert (operands[2] == constm1_rtx);
5721 return "dec{<imodesuffix>}\t%0";
5725 /* For most processors, ADD is faster than LEA. This alternative
5726 was added to use ADD as much as possible. */
5727 if (which_alternative == 2)
5730 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5733 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5734 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5735 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5737 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5741 (cond [(eq_attr "alternative" "3")
5742 (const_string "lea")
5743 (match_operand:SWI48 2 "incdec_operand" "")
5744 (const_string "incdec")
5746 (const_string "alu")))
5747 (set (attr "length_immediate")
5749 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5751 (const_string "*")))
5752 (set_attr "mode" "<MODE>")])
5754 ;; It may seem that nonimmediate operand is proper one for operand 1.
5755 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5756 ;; we take care in ix86_binary_operator_ok to not allow two memory
5757 ;; operands so proper swapping will be done in reload. This allow
5758 ;; patterns constructed from addsi_1 to match.
5760 (define_insn "*addsi_1_zext"
5761 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5763 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5764 (match_operand:SI 2 "general_operand" "g,0,li"))))
5765 (clobber (reg:CC FLAGS_REG))]
5766 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5768 switch (get_attr_type (insn))
5774 if (operands[2] == const1_rtx)
5775 return "inc{l}\t%k0";
5778 gcc_assert (operands[2] == constm1_rtx);
5779 return "dec{l}\t%k0";
5783 /* For most processors, ADD is faster than LEA. This alternative
5784 was added to use ADD as much as possible. */
5785 if (which_alternative == 1)
5788 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5791 if (x86_maybe_negate_const_int (&operands[2], SImode))
5792 return "sub{l}\t{%2, %k0|%k0, %2}";
5794 return "add{l}\t{%2, %k0|%k0, %2}";
5798 (cond [(eq_attr "alternative" "2")
5799 (const_string "lea")
5800 (match_operand:SI 2 "incdec_operand" "")
5801 (const_string "incdec")
5803 (const_string "alu")))
5804 (set (attr "length_immediate")
5806 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5808 (const_string "*")))
5809 (set_attr "mode" "SI")])
5811 (define_insn "*addhi_1"
5812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5813 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5814 (match_operand:HI 2 "general_operand" "rn,rm")))
5815 (clobber (reg:CC FLAGS_REG))]
5816 "TARGET_PARTIAL_REG_STALL
5817 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5819 switch (get_attr_type (insn))
5822 if (operands[2] == const1_rtx)
5823 return "inc{w}\t%0";
5826 gcc_assert (operands[2] == constm1_rtx);
5827 return "dec{w}\t%0";
5831 if (x86_maybe_negate_const_int (&operands[2], HImode))
5832 return "sub{w}\t{%2, %0|%0, %2}";
5834 return "add{w}\t{%2, %0|%0, %2}";
5838 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5839 (const_string "incdec")
5840 (const_string "alu")))
5841 (set (attr "length_immediate")
5843 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5845 (const_string "*")))
5846 (set_attr "mode" "HI")])
5848 (define_insn "*addhi_1_lea"
5849 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5850 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5851 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5852 (clobber (reg:CC FLAGS_REG))]
5853 "!TARGET_PARTIAL_REG_STALL
5854 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5856 switch (get_attr_type (insn))
5862 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5863 if (operands[2] == const1_rtx)
5864 return "inc{w}\t%0";
5867 gcc_assert (operands[2] == constm1_rtx);
5868 return "dec{w}\t%0";
5872 /* For most processors, ADD is faster than LEA. This alternative
5873 was added to use ADD as much as possible. */
5874 if (which_alternative == 2)
5877 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5880 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5881 if (x86_maybe_negate_const_int (&operands[2], HImode))
5882 return "sub{w}\t{%2, %0|%0, %2}";
5884 return "add{w}\t{%2, %0|%0, %2}";
5888 (cond [(eq_attr "alternative" "3")
5889 (const_string "lea")
5890 (match_operand:HI 2 "incdec_operand" "")
5891 (const_string "incdec")
5893 (const_string "alu")))
5894 (set (attr "length_immediate")
5896 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5898 (const_string "*")))
5899 (set_attr "mode" "HI,HI,HI,SI")])
5901 ;; %%% Potential partial reg stall on alternative 2. What to do?
5902 (define_insn "*addqi_1"
5903 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5904 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5905 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5906 (clobber (reg:CC FLAGS_REG))]
5907 "TARGET_PARTIAL_REG_STALL
5908 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5910 int widen = (which_alternative == 2);
5911 switch (get_attr_type (insn))
5914 if (operands[2] == const1_rtx)
5915 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5918 gcc_assert (operands[2] == constm1_rtx);
5919 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5923 if (x86_maybe_negate_const_int (&operands[2], QImode))
5926 return "sub{l}\t{%2, %k0|%k0, %2}";
5928 return "sub{b}\t{%2, %0|%0, %2}";
5931 return "add{l}\t{%k2, %k0|%k0, %k2}";
5933 return "add{b}\t{%2, %0|%0, %2}";
5937 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5938 (const_string "incdec")
5939 (const_string "alu")))
5940 (set (attr "length_immediate")
5942 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5944 (const_string "*")))
5945 (set_attr "mode" "QI,QI,SI")])
5947 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5948 (define_insn "*addqi_1_lea"
5949 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5950 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5951 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5952 (clobber (reg:CC FLAGS_REG))]
5953 "!TARGET_PARTIAL_REG_STALL
5954 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5956 int widen = (which_alternative == 3 || which_alternative == 4);
5958 switch (get_attr_type (insn))
5964 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5965 if (operands[2] == const1_rtx)
5966 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5969 gcc_assert (operands[2] == constm1_rtx);
5970 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5974 /* For most processors, ADD is faster than LEA. These alternatives
5975 were added to use ADD as much as possible. */
5976 if (which_alternative == 2 || which_alternative == 4)
5979 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5982 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5983 if (x86_maybe_negate_const_int (&operands[2], QImode))
5986 return "sub{l}\t{%2, %k0|%k0, %2}";
5988 return "sub{b}\t{%2, %0|%0, %2}";
5991 return "add{l}\t{%k2, %k0|%k0, %k2}";
5993 return "add{b}\t{%2, %0|%0, %2}";
5997 (cond [(eq_attr "alternative" "5")
5998 (const_string "lea")
5999 (match_operand:QI 2 "incdec_operand" "")
6000 (const_string "incdec")
6002 (const_string "alu")))
6003 (set (attr "length_immediate")
6005 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6007 (const_string "*")))
6008 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
6010 (define_insn "*addqi_1_slp"
6011 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6012 (plus:QI (match_dup 0)
6013 (match_operand:QI 1 "general_operand" "qn,qnm")))
6014 (clobber (reg:CC FLAGS_REG))]
6015 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6016 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6018 switch (get_attr_type (insn))
6021 if (operands[1] == const1_rtx)
6022 return "inc{b}\t%0";
6025 gcc_assert (operands[1] == constm1_rtx);
6026 return "dec{b}\t%0";
6030 if (x86_maybe_negate_const_int (&operands[1], QImode))
6031 return "sub{b}\t{%1, %0|%0, %1}";
6033 return "add{b}\t{%1, %0|%0, %1}";
6037 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6038 (const_string "incdec")
6039 (const_string "alu1")))
6040 (set (attr "memory")
6041 (if_then_else (match_operand 1 "memory_operand" "")
6042 (const_string "load")
6043 (const_string "none")))
6044 (set_attr "mode" "QI")])
6046 ;; Convert lea to the lea pattern to avoid flags dependency.
6048 [(set (match_operand 0 "register_operand" "")
6049 (plus (match_operand 1 "register_operand" "")
6050 (match_operand 2 "nonmemory_operand" "")))
6051 (clobber (reg:CC FLAGS_REG))]
6052 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6056 enum machine_mode mode = GET_MODE (operands[0]);
6058 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6059 may confuse gen_lowpart. */
6062 operands[1] = gen_lowpart (Pmode, operands[1]);
6063 operands[2] = gen_lowpart (Pmode, operands[2]);
6066 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6068 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6069 operands[0] = gen_lowpart (SImode, operands[0]);
6071 if (TARGET_64BIT && mode != Pmode)
6072 pat = gen_rtx_SUBREG (SImode, pat, 0);
6074 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6078 ;; Convert lea to the lea pattern to avoid flags dependency.
6079 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6080 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
6082 [(set (match_operand:DI 0 "register_operand" "")
6083 (plus:DI (match_operand:DI 1 "register_operand" "")
6084 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6085 (clobber (reg:CC FLAGS_REG))]
6086 "TARGET_64BIT && reload_completed
6087 && true_regnum (operands[0]) != true_regnum (operands[1])"
6089 (plus:DI (match_dup 1) (match_dup 2)))])
6091 ;; Convert lea to the lea pattern to avoid flags dependency.
6093 [(set (match_operand:DI 0 "register_operand" "")
6095 (plus:SI (match_operand:SI 1 "register_operand" "")
6096 (match_operand:SI 2 "nonmemory_operand" ""))))
6097 (clobber (reg:CC FLAGS_REG))]
6098 "TARGET_64BIT && reload_completed
6099 && ix86_lea_for_add_ok (insn, operands)"
6101 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6103 operands[1] = gen_lowpart (DImode, operands[1]);
6104 operands[2] = gen_lowpart (DImode, operands[2]);
6107 (define_insn "*add<mode>_2"
6108 [(set (reg FLAGS_REG)
6111 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6112 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6114 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6115 (plus:SWI (match_dup 1) (match_dup 2)))]
6116 "ix86_match_ccmode (insn, CCGOCmode)
6117 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6119 switch (get_attr_type (insn))
6122 if (operands[2] == const1_rtx)
6123 return "inc{<imodesuffix>}\t%0";
6126 gcc_assert (operands[2] == constm1_rtx);
6127 return "dec{<imodesuffix>}\t%0";
6131 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6132 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6134 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6138 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6139 (const_string "incdec")
6140 (const_string "alu")))
6141 (set (attr "length_immediate")
6143 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6145 (const_string "*")))
6146 (set_attr "mode" "<MODE>")])
6148 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6149 (define_insn "*addsi_2_zext"
6150 [(set (reg FLAGS_REG)
6152 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6153 (match_operand:SI 2 "general_operand" "g"))
6155 (set (match_operand:DI 0 "register_operand" "=r")
6156 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6157 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6158 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6160 switch (get_attr_type (insn))
6163 if (operands[2] == const1_rtx)
6164 return "inc{l}\t%k0";
6167 gcc_assert (operands[2] == constm1_rtx);
6168 return "dec{l}\t%k0";
6172 if (x86_maybe_negate_const_int (&operands[2], SImode))
6173 return "sub{l}\t{%2, %k0|%k0, %2}";
6175 return "add{l}\t{%2, %k0|%k0, %2}";
6179 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6180 (const_string "incdec")
6181 (const_string "alu")))
6182 (set (attr "length_immediate")
6184 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6186 (const_string "*")))
6187 (set_attr "mode" "SI")])
6189 (define_insn "*add<mode>_3"
6190 [(set (reg FLAGS_REG)
6192 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6193 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6194 (clobber (match_scratch:SWI 0 "=<r>"))]
6195 "ix86_match_ccmode (insn, CCZmode)
6196 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6198 switch (get_attr_type (insn))
6201 if (operands[2] == const1_rtx)
6202 return "inc{<imodesuffix>}\t%0";
6205 gcc_assert (operands[2] == constm1_rtx);
6206 return "dec{<imodesuffix>}\t%0";
6210 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6211 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6213 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6217 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6218 (const_string "incdec")
6219 (const_string "alu")))
6220 (set (attr "length_immediate")
6222 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6224 (const_string "*")))
6225 (set_attr "mode" "<MODE>")])
6227 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6228 (define_insn "*addsi_3_zext"
6229 [(set (reg FLAGS_REG)
6231 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6232 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6233 (set (match_operand:DI 0 "register_operand" "=r")
6234 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6235 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6236 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6238 switch (get_attr_type (insn))
6241 if (operands[2] == const1_rtx)
6242 return "inc{l}\t%k0";
6245 gcc_assert (operands[2] == constm1_rtx);
6246 return "dec{l}\t%k0";
6250 if (x86_maybe_negate_const_int (&operands[2], SImode))
6251 return "sub{l}\t{%2, %k0|%k0, %2}";
6253 return "add{l}\t{%2, %k0|%k0, %2}";
6257 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6258 (const_string "incdec")
6259 (const_string "alu")))
6260 (set (attr "length_immediate")
6262 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6264 (const_string "*")))
6265 (set_attr "mode" "SI")])
6267 ; For comparisons against 1, -1 and 128, we may generate better code
6268 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6269 ; is matched then. We can't accept general immediate, because for
6270 ; case of overflows, the result is messed up.
6271 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6272 ; only for comparisons not depending on it.
6274 (define_insn "*adddi_4"
6275 [(set (reg FLAGS_REG)
6277 (match_operand:DI 1 "nonimmediate_operand" "0")
6278 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6279 (clobber (match_scratch:DI 0 "=rm"))]
6281 && ix86_match_ccmode (insn, CCGCmode)"
6283 switch (get_attr_type (insn))
6286 if (operands[2] == constm1_rtx)
6287 return "inc{q}\t%0";
6290 gcc_assert (operands[2] == const1_rtx);
6291 return "dec{q}\t%0";
6295 if (x86_maybe_negate_const_int (&operands[2], DImode))
6296 return "add{q}\t{%2, %0|%0, %2}";
6298 return "sub{q}\t{%2, %0|%0, %2}";
6302 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6303 (const_string "incdec")
6304 (const_string "alu")))
6305 (set (attr "length_immediate")
6307 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6309 (const_string "*")))
6310 (set_attr "mode" "DI")])
6312 ; For comparisons against 1, -1 and 128, we may generate better code
6313 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6314 ; is matched then. We can't accept general immediate, because for
6315 ; case of overflows, the result is messed up.
6316 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6317 ; only for comparisons not depending on it.
6319 (define_insn "*add<mode>_4"
6320 [(set (reg FLAGS_REG)
6322 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6323 (match_operand:SWI124 2 "const_int_operand" "n")))
6324 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6325 "ix86_match_ccmode (insn, CCGCmode)"
6327 switch (get_attr_type (insn))
6330 if (operands[2] == constm1_rtx)
6331 return "inc{<imodesuffix>}\t%0";
6334 gcc_assert (operands[2] == const1_rtx);
6335 return "dec{<imodesuffix>}\t%0";
6339 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6340 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6342 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6346 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6347 (const_string "incdec")
6348 (const_string "alu")))
6349 (set (attr "length_immediate")
6351 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6353 (const_string "*")))
6354 (set_attr "mode" "<MODE>")])
6356 (define_insn "*add<mode>_5"
6357 [(set (reg FLAGS_REG)
6360 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6361 (match_operand:SWI 2 "<general_operand>" "<g>"))
6363 (clobber (match_scratch:SWI 0 "=<r>"))]
6364 "ix86_match_ccmode (insn, CCGOCmode)
6365 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6367 switch (get_attr_type (insn))
6370 if (operands[2] == const1_rtx)
6371 return "inc{<imodesuffix>}\t%0";
6374 gcc_assert (operands[2] == constm1_rtx);
6375 return "dec{<imodesuffix>}\t%0";
6379 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6380 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6382 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6386 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6387 (const_string "incdec")
6388 (const_string "alu")))
6389 (set (attr "length_immediate")
6391 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6393 (const_string "*")))
6394 (set_attr "mode" "<MODE>")])
6396 (define_insn "*addqi_ext_1_rex64"
6397 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6402 (match_operand 1 "ext_register_operand" "0")
6405 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6406 (clobber (reg:CC FLAGS_REG))]
6409 switch (get_attr_type (insn))
6412 if (operands[2] == const1_rtx)
6413 return "inc{b}\t%h0";
6416 gcc_assert (operands[2] == constm1_rtx);
6417 return "dec{b}\t%h0";
6421 return "add{b}\t{%2, %h0|%h0, %2}";
6425 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6426 (const_string "incdec")
6427 (const_string "alu")))
6428 (set_attr "modrm" "1")
6429 (set_attr "mode" "QI")])
6431 (define_insn "addqi_ext_1"
6432 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6437 (match_operand 1 "ext_register_operand" "0")
6440 (match_operand:QI 2 "general_operand" "Qmn")))
6441 (clobber (reg:CC FLAGS_REG))]
6444 switch (get_attr_type (insn))
6447 if (operands[2] == const1_rtx)
6448 return "inc{b}\t%h0";
6451 gcc_assert (operands[2] == constm1_rtx);
6452 return "dec{b}\t%h0";
6456 return "add{b}\t{%2, %h0|%h0, %2}";
6460 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6461 (const_string "incdec")
6462 (const_string "alu")))
6463 (set_attr "modrm" "1")
6464 (set_attr "mode" "QI")])
6466 (define_insn "*addqi_ext_2"
6467 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6472 (match_operand 1 "ext_register_operand" "%0")
6476 (match_operand 2 "ext_register_operand" "Q")
6479 (clobber (reg:CC FLAGS_REG))]
6481 "add{b}\t{%h2, %h0|%h0, %h2}"
6482 [(set_attr "type" "alu")
6483 (set_attr "mode" "QI")])
6485 ;; The lea patterns for non-Pmodes needs to be matched by
6486 ;; several insns converted to real lea by splitters.
6488 (define_insn_and_split "*lea_general_1"
6489 [(set (match_operand 0 "register_operand" "=r")
6490 (plus (plus (match_operand 1 "index_register_operand" "l")
6491 (match_operand 2 "register_operand" "r"))
6492 (match_operand 3 "immediate_operand" "i")))]
6493 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6494 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6495 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6496 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6497 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6498 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6499 || GET_MODE (operands[3]) == VOIDmode)"
6501 "&& reload_completed"
6505 operands[0] = gen_lowpart (SImode, operands[0]);
6506 operands[1] = gen_lowpart (Pmode, operands[1]);
6507 operands[2] = gen_lowpart (Pmode, operands[2]);
6508 operands[3] = gen_lowpart (Pmode, operands[3]);
6509 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6511 if (Pmode != SImode)
6512 pat = gen_rtx_SUBREG (SImode, pat, 0);
6513 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6516 [(set_attr "type" "lea")
6517 (set_attr "mode" "SI")])
6519 (define_insn_and_split "*lea_general_1_zext"
6520 [(set (match_operand:DI 0 "register_operand" "=r")
6523 (match_operand:SI 1 "index_register_operand" "l")
6524 (match_operand:SI 2 "register_operand" "r"))
6525 (match_operand:SI 3 "immediate_operand" "i"))))]
6528 "&& reload_completed"
6530 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6532 (match_dup 3)) 0)))]
6534 operands[1] = gen_lowpart (Pmode, operands[1]);
6535 operands[2] = gen_lowpart (Pmode, operands[2]);
6536 operands[3] = gen_lowpart (Pmode, operands[3]);
6538 [(set_attr "type" "lea")
6539 (set_attr "mode" "SI")])
6541 (define_insn_and_split "*lea_general_2"
6542 [(set (match_operand 0 "register_operand" "=r")
6543 (plus (mult (match_operand 1 "index_register_operand" "l")
6544 (match_operand 2 "const248_operand" "i"))
6545 (match_operand 3 "nonmemory_operand" "ri")))]
6546 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6547 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6548 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6549 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6550 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6551 || GET_MODE (operands[3]) == VOIDmode)"
6553 "&& reload_completed"
6557 operands[0] = gen_lowpart (SImode, operands[0]);
6558 operands[1] = gen_lowpart (Pmode, operands[1]);
6559 operands[3] = gen_lowpart (Pmode, operands[3]);
6560 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6562 if (Pmode != SImode)
6563 pat = gen_rtx_SUBREG (SImode, pat, 0);
6564 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6567 [(set_attr "type" "lea")
6568 (set_attr "mode" "SI")])
6570 (define_insn_and_split "*lea_general_2_zext"
6571 [(set (match_operand:DI 0 "register_operand" "=r")
6574 (match_operand:SI 1 "index_register_operand" "l")
6575 (match_operand:SI 2 "const248_operand" "n"))
6576 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6579 "&& reload_completed"
6581 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6583 (match_dup 3)) 0)))]
6585 operands[1] = gen_lowpart (Pmode, operands[1]);
6586 operands[3] = gen_lowpart (Pmode, operands[3]);
6588 [(set_attr "type" "lea")
6589 (set_attr "mode" "SI")])
6591 (define_insn_and_split "*lea_general_3"
6592 [(set (match_operand 0 "register_operand" "=r")
6593 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6594 (match_operand 2 "const248_operand" "i"))
6595 (match_operand 3 "register_operand" "r"))
6596 (match_operand 4 "immediate_operand" "i")))]
6597 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6598 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6599 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6600 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6601 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6603 "&& reload_completed"
6607 operands[0] = gen_lowpart (SImode, operands[0]);
6608 operands[1] = gen_lowpart (Pmode, operands[1]);
6609 operands[3] = gen_lowpart (Pmode, operands[3]);
6610 operands[4] = gen_lowpart (Pmode, operands[4]);
6611 pat = gen_rtx_PLUS (Pmode,
6612 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6616 if (Pmode != SImode)
6617 pat = gen_rtx_SUBREG (SImode, pat, 0);
6618 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6621 [(set_attr "type" "lea")
6622 (set_attr "mode" "SI")])
6624 (define_insn_and_split "*lea_general_3_zext"
6625 [(set (match_operand:DI 0 "register_operand" "=r")
6629 (match_operand:SI 1 "index_register_operand" "l")
6630 (match_operand:SI 2 "const248_operand" "n"))
6631 (match_operand:SI 3 "register_operand" "r"))
6632 (match_operand:SI 4 "immediate_operand" "i"))))]
6635 "&& reload_completed"
6637 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6640 (match_dup 4)) 0)))]
6642 operands[1] = gen_lowpart (Pmode, operands[1]);
6643 operands[3] = gen_lowpart (Pmode, operands[3]);
6644 operands[4] = gen_lowpart (Pmode, operands[4]);
6646 [(set_attr "type" "lea")
6647 (set_attr "mode" "SI")])
6649 ;; Subtract instructions
6651 (define_expand "sub<mode>3"
6652 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6653 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6654 (match_operand:SDWIM 2 "<general_operand>" "")))]
6656 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6658 (define_insn_and_split "*sub<dwi>3_doubleword"
6659 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6661 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6662 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6663 (clobber (reg:CC FLAGS_REG))]
6664 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6667 [(parallel [(set (reg:CC FLAGS_REG)
6668 (compare:CC (match_dup 1) (match_dup 2)))
6670 (minus:DWIH (match_dup 1) (match_dup 2)))])
6671 (parallel [(set (match_dup 3)
6675 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6677 (clobber (reg:CC FLAGS_REG))])]
6678 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6680 (define_insn "*sub<mode>_1"
6681 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6683 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6684 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6685 (clobber (reg:CC FLAGS_REG))]
6686 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6687 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6688 [(set_attr "type" "alu")
6689 (set_attr "mode" "<MODE>")])
6691 (define_insn "*subsi_1_zext"
6692 [(set (match_operand:DI 0 "register_operand" "=r")
6694 (minus:SI (match_operand:SI 1 "register_operand" "0")
6695 (match_operand:SI 2 "general_operand" "g"))))
6696 (clobber (reg:CC FLAGS_REG))]
6697 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6698 "sub{l}\t{%2, %k0|%k0, %2}"
6699 [(set_attr "type" "alu")
6700 (set_attr "mode" "SI")])
6702 (define_insn "*subqi_1_slp"
6703 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6704 (minus:QI (match_dup 0)
6705 (match_operand:QI 1 "general_operand" "qn,qm")))
6706 (clobber (reg:CC FLAGS_REG))]
6707 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6708 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6709 "sub{b}\t{%1, %0|%0, %1}"
6710 [(set_attr "type" "alu1")
6711 (set_attr "mode" "QI")])
6713 (define_insn "*sub<mode>_2"
6714 [(set (reg FLAGS_REG)
6717 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6718 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6720 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6721 (minus:SWI (match_dup 1) (match_dup 2)))]
6722 "ix86_match_ccmode (insn, CCGOCmode)
6723 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6724 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "<MODE>")])
6728 (define_insn "*subsi_2_zext"
6729 [(set (reg FLAGS_REG)
6731 (minus:SI (match_operand:SI 1 "register_operand" "0")
6732 (match_operand:SI 2 "general_operand" "g"))
6734 (set (match_operand:DI 0 "register_operand" "=r")
6736 (minus:SI (match_dup 1)
6738 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6739 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6740 "sub{l}\t{%2, %k0|%k0, %2}"
6741 [(set_attr "type" "alu")
6742 (set_attr "mode" "SI")])
6744 (define_insn "*sub<mode>_3"
6745 [(set (reg FLAGS_REG)
6746 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6747 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6748 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6749 (minus:SWI (match_dup 1) (match_dup 2)))]
6750 "ix86_match_ccmode (insn, CCmode)
6751 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6752 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6753 [(set_attr "type" "alu")
6754 (set_attr "mode" "<MODE>")])
6756 (define_insn "*subsi_3_zext"
6757 [(set (reg FLAGS_REG)
6758 (compare (match_operand:SI 1 "register_operand" "0")
6759 (match_operand:SI 2 "general_operand" "g")))
6760 (set (match_operand:DI 0 "register_operand" "=r")
6762 (minus:SI (match_dup 1)
6764 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6765 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6766 "sub{l}\t{%2, %1|%1, %2}"
6767 [(set_attr "type" "alu")
6768 (set_attr "mode" "SI")])
6770 ;; Add with carry and subtract with borrow
6772 (define_expand "<plusminus_insn><mode>3_carry"
6774 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6776 (match_operand:SWI 1 "nonimmediate_operand" "")
6777 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6778 [(match_operand 3 "flags_reg_operand" "")
6780 (match_operand:SWI 2 "<general_operand>" ""))))
6781 (clobber (reg:CC FLAGS_REG))])]
6782 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6784 (define_insn "*<plusminus_insn><mode>3_carry"
6785 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6787 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6789 (match_operator 3 "ix86_carry_flag_operator"
6790 [(reg FLAGS_REG) (const_int 0)])
6791 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6792 (clobber (reg:CC FLAGS_REG))]
6793 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6794 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6795 [(set_attr "type" "alu")
6796 (set_attr "use_carry" "1")
6797 (set_attr "pent_pair" "pu")
6798 (set_attr "mode" "<MODE>")])
6800 (define_insn "*addsi3_carry_zext"
6801 [(set (match_operand:DI 0 "register_operand" "=r")
6803 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6804 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6805 [(reg FLAGS_REG) (const_int 0)])
6806 (match_operand:SI 2 "general_operand" "g")))))
6807 (clobber (reg:CC FLAGS_REG))]
6808 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6809 "adc{l}\t{%2, %k0|%k0, %2}"
6810 [(set_attr "type" "alu")
6811 (set_attr "use_carry" "1")
6812 (set_attr "pent_pair" "pu")
6813 (set_attr "mode" "SI")])
6815 (define_insn "*subsi3_carry_zext"
6816 [(set (match_operand:DI 0 "register_operand" "=r")
6818 (minus:SI (match_operand:SI 1 "register_operand" "0")
6819 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6820 [(reg FLAGS_REG) (const_int 0)])
6821 (match_operand:SI 2 "general_operand" "g")))))
6822 (clobber (reg:CC FLAGS_REG))]
6823 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6824 "sbb{l}\t{%2, %k0|%k0, %2}"
6825 [(set_attr "type" "alu")
6826 (set_attr "pent_pair" "pu")
6827 (set_attr "mode" "SI")])
6829 ;; Overflow setting add and subtract instructions
6831 (define_insn "*add<mode>3_cconly_overflow"
6832 [(set (reg:CCC FLAGS_REG)
6835 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6836 (match_operand:SWI 2 "<general_operand>" "<g>"))
6838 (clobber (match_scratch:SWI 0 "=<r>"))]
6839 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6840 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6841 [(set_attr "type" "alu")
6842 (set_attr "mode" "<MODE>")])
6844 (define_insn "*sub<mode>3_cconly_overflow"
6845 [(set (reg:CCC FLAGS_REG)
6848 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6849 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6852 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6853 [(set_attr "type" "icmp")
6854 (set_attr "mode" "<MODE>")])
6856 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6857 [(set (reg:CCC FLAGS_REG)
6860 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6861 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6863 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6864 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6865 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6866 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6867 [(set_attr "type" "alu")
6868 (set_attr "mode" "<MODE>")])
6870 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6871 [(set (reg:CCC FLAGS_REG)
6874 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6875 (match_operand:SI 2 "general_operand" "g"))
6877 (set (match_operand:DI 0 "register_operand" "=r")
6878 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6879 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6880 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6881 [(set_attr "type" "alu")
6882 (set_attr "mode" "SI")])
6884 ;; The patterns that match these are at the end of this file.
6886 (define_expand "<plusminus_insn>xf3"
6887 [(set (match_operand:XF 0 "register_operand" "")
6889 (match_operand:XF 1 "register_operand" "")
6890 (match_operand:XF 2 "register_operand" "")))]
6893 (define_expand "<plusminus_insn><mode>3"
6894 [(set (match_operand:MODEF 0 "register_operand" "")
6896 (match_operand:MODEF 1 "register_operand" "")
6897 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6898 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6899 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6901 ;; Multiply instructions
6903 (define_expand "mul<mode>3"
6904 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6906 (match_operand:SWIM248 1 "register_operand" "")
6907 (match_operand:SWIM248 2 "<general_operand>" "")))
6908 (clobber (reg:CC FLAGS_REG))])])
6910 (define_expand "mulqi3"
6911 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6913 (match_operand:QI 1 "register_operand" "")
6914 (match_operand:QI 2 "nonimmediate_operand" "")))
6915 (clobber (reg:CC FLAGS_REG))])]
6916 "TARGET_QIMODE_MATH")
6919 ;; IMUL reg32/64, reg32/64, imm8 Direct
6920 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6921 ;; IMUL reg32/64, reg32/64, imm32 Direct
6922 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6923 ;; IMUL reg32/64, reg32/64 Direct
6924 ;; IMUL reg32/64, mem32/64 Direct
6926 ;; On BDVER1, all above IMULs use DirectPath
6928 (define_insn "*mul<mode>3_1"
6929 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6931 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6932 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6933 (clobber (reg:CC FLAGS_REG))]
6934 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6936 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6937 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6938 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6939 [(set_attr "type" "imul")
6940 (set_attr "prefix_0f" "0,0,1")
6941 (set (attr "athlon_decode")
6942 (cond [(eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (eq_attr "alternative" "1")
6945 (const_string "vector")
6946 (and (eq_attr "alternative" "2")
6947 (match_operand 1 "memory_operand" ""))
6948 (const_string "vector")]
6949 (const_string "direct")))
6950 (set (attr "amdfam10_decode")
6951 (cond [(and (eq_attr "alternative" "0,1")
6952 (match_operand 1 "memory_operand" ""))
6953 (const_string "vector")]
6954 (const_string "direct")))
6955 (set_attr "bdver1_decode" "direct")
6956 (set_attr "mode" "<MODE>")])
6958 (define_insn "*mulsi3_1_zext"
6959 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6961 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6962 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6963 (clobber (reg:CC FLAGS_REG))]
6965 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6967 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6968 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6969 imul{l}\t{%2, %k0|%k0, %2}"
6970 [(set_attr "type" "imul")
6971 (set_attr "prefix_0f" "0,0,1")
6972 (set (attr "athlon_decode")
6973 (cond [(eq_attr "cpu" "athlon")
6974 (const_string "vector")
6975 (eq_attr "alternative" "1")
6976 (const_string "vector")
6977 (and (eq_attr "alternative" "2")
6978 (match_operand 1 "memory_operand" ""))
6979 (const_string "vector")]
6980 (const_string "direct")))
6981 (set (attr "amdfam10_decode")
6982 (cond [(and (eq_attr "alternative" "0,1")
6983 (match_operand 1 "memory_operand" ""))
6984 (const_string "vector")]
6985 (const_string "direct")))
6986 (set_attr "bdver1_decode" "direct")
6987 (set_attr "mode" "SI")])
6990 ;; IMUL reg16, reg16, imm8 VectorPath
6991 ;; IMUL reg16, mem16, imm8 VectorPath
6992 ;; IMUL reg16, reg16, imm16 VectorPath
6993 ;; IMUL reg16, mem16, imm16 VectorPath
6994 ;; IMUL reg16, reg16 Direct
6995 ;; IMUL reg16, mem16 Direct
6997 ;; On BDVER1, all HI MULs use DoublePath
6999 (define_insn "*mulhi3_1"
7000 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7001 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7002 (match_operand:HI 2 "general_operand" "K,n,mr")))
7003 (clobber (reg:CC FLAGS_REG))]
7005 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7007 imul{w}\t{%2, %1, %0|%0, %1, %2}
7008 imul{w}\t{%2, %1, %0|%0, %1, %2}
7009 imul{w}\t{%2, %0|%0, %2}"
7010 [(set_attr "type" "imul")
7011 (set_attr "prefix_0f" "0,0,1")
7012 (set (attr "athlon_decode")
7013 (cond [(eq_attr "cpu" "athlon")
7014 (const_string "vector")
7015 (eq_attr "alternative" "1,2")
7016 (const_string "vector")]
7017 (const_string "direct")))
7018 (set (attr "amdfam10_decode")
7019 (cond [(eq_attr "alternative" "0,1")
7020 (const_string "vector")]
7021 (const_string "direct")))
7022 (set_attr "bdver1_decode" "double")
7023 (set_attr "mode" "HI")])
7025 ;;On AMDFAM10 and BDVER1
7029 (define_insn "*mulqi3_1"
7030 [(set (match_operand:QI 0 "register_operand" "=a")
7031 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7032 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7033 (clobber (reg:CC FLAGS_REG))]
7035 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7037 [(set_attr "type" "imul")
7038 (set_attr "length_immediate" "0")
7039 (set (attr "athlon_decode")
7040 (if_then_else (eq_attr "cpu" "athlon")
7041 (const_string "vector")
7042 (const_string "direct")))
7043 (set_attr "amdfam10_decode" "direct")
7044 (set_attr "bdver1_decode" "direct")
7045 (set_attr "mode" "QI")])
7047 (define_expand "<u>mul<mode><dwi>3"
7048 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7051 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7053 (match_operand:DWIH 2 "register_operand" ""))))
7054 (clobber (reg:CC FLAGS_REG))])])
7056 (define_expand "<u>mulqihi3"
7057 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7060 (match_operand:QI 1 "nonimmediate_operand" ""))
7062 (match_operand:QI 2 "register_operand" ""))))
7063 (clobber (reg:CC FLAGS_REG))])]
7064 "TARGET_QIMODE_MATH")
7066 (define_insn "*<u>mul<mode><dwi>3_1"
7067 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7070 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7072 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7073 (clobber (reg:CC FLAGS_REG))]
7074 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7075 "<sgnprefix>mul{<imodesuffix>}\t%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 "double")))
7082 (set_attr "amdfam10_decode" "double")
7083 (set_attr "bdver1_decode" "direct")
7084 (set_attr "mode" "<MODE>")])
7086 (define_insn "*<u>mulqihi3_1"
7087 [(set (match_operand:HI 0 "register_operand" "=a")
7090 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7092 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7093 (clobber (reg:CC FLAGS_REG))]
7095 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7096 "<sgnprefix>mul{b}\t%2"
7097 [(set_attr "type" "imul")
7098 (set_attr "length_immediate" "0")
7099 (set (attr "athlon_decode")
7100 (if_then_else (eq_attr "cpu" "athlon")
7101 (const_string "vector")
7102 (const_string "direct")))
7103 (set_attr "amdfam10_decode" "direct")
7104 (set_attr "bdver1_decode" "direct")
7105 (set_attr "mode" "QI")])
7107 (define_expand "<s>mul<mode>3_highpart"
7108 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7113 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7115 (match_operand:SWI48 2 "register_operand" "")))
7117 (clobber (match_scratch:SWI48 3 ""))
7118 (clobber (reg:CC FLAGS_REG))])]
7120 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7122 (define_insn "*<s>muldi3_highpart_1"
7123 [(set (match_operand:DI 0 "register_operand" "=d")
7128 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7130 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7132 (clobber (match_scratch:DI 3 "=1"))
7133 (clobber (reg:CC FLAGS_REG))]
7135 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7136 "<sgnprefix>mul{q}\t%2"
7137 [(set_attr "type" "imul")
7138 (set_attr "length_immediate" "0")
7139 (set (attr "athlon_decode")
7140 (if_then_else (eq_attr "cpu" "athlon")
7141 (const_string "vector")
7142 (const_string "double")))
7143 (set_attr "amdfam10_decode" "double")
7144 (set_attr "bdver1_decode" "direct")
7145 (set_attr "mode" "DI")])
7147 (define_insn "*<s>mulsi3_highpart_1"
7148 [(set (match_operand:SI 0 "register_operand" "=d")
7153 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7155 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7157 (clobber (match_scratch:SI 3 "=1"))
7158 (clobber (reg:CC FLAGS_REG))]
7159 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7160 "<sgnprefix>mul{l}\t%2"
7161 [(set_attr "type" "imul")
7162 (set_attr "length_immediate" "0")
7163 (set (attr "athlon_decode")
7164 (if_then_else (eq_attr "cpu" "athlon")
7165 (const_string "vector")
7166 (const_string "double")))
7167 (set_attr "amdfam10_decode" "double")
7168 (set_attr "bdver1_decode" "direct")
7169 (set_attr "mode" "SI")])
7171 (define_insn "*<s>mulsi3_highpart_zext"
7172 [(set (match_operand:DI 0 "register_operand" "=d")
7173 (zero_extend:DI (truncate:SI
7175 (mult:DI (any_extend:DI
7176 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7178 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7180 (clobber (match_scratch:SI 3 "=1"))
7181 (clobber (reg:CC FLAGS_REG))]
7183 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7184 "<sgnprefix>mul{l}\t%2"
7185 [(set_attr "type" "imul")
7186 (set_attr "length_immediate" "0")
7187 (set (attr "athlon_decode")
7188 (if_then_else (eq_attr "cpu" "athlon")
7189 (const_string "vector")
7190 (const_string "double")))
7191 (set_attr "amdfam10_decode" "double")
7192 (set_attr "bdver1_decode" "direct")
7193 (set_attr "mode" "SI")])
7195 ;; The patterns that match these are at the end of this file.
7197 (define_expand "mulxf3"
7198 [(set (match_operand:XF 0 "register_operand" "")
7199 (mult:XF (match_operand:XF 1 "register_operand" "")
7200 (match_operand:XF 2 "register_operand" "")))]
7203 (define_expand "mul<mode>3"
7204 [(set (match_operand:MODEF 0 "register_operand" "")
7205 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7206 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7207 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7208 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7210 ;; Divide instructions
7212 ;; The patterns that match these are at the end of this file.
7214 (define_expand "divxf3"
7215 [(set (match_operand:XF 0 "register_operand" "")
7216 (div:XF (match_operand:XF 1 "register_operand" "")
7217 (match_operand:XF 2 "register_operand" "")))]
7220 (define_expand "divdf3"
7221 [(set (match_operand:DF 0 "register_operand" "")
7222 (div:DF (match_operand:DF 1 "register_operand" "")
7223 (match_operand:DF 2 "nonimmediate_operand" "")))]
7224 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7225 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7227 (define_expand "divsf3"
7228 [(set (match_operand:SF 0 "register_operand" "")
7229 (div:SF (match_operand:SF 1 "register_operand" "")
7230 (match_operand:SF 2 "nonimmediate_operand" "")))]
7231 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7234 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7235 && flag_finite_math_only && !flag_trapping_math
7236 && flag_unsafe_math_optimizations)
7238 ix86_emit_swdivsf (operands[0], operands[1],
7239 operands[2], SFmode);
7244 ;; Divmod instructions.
7246 (define_expand "divmod<mode>4"
7247 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7249 (match_operand:SWIM248 1 "register_operand" "")
7250 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7251 (set (match_operand:SWIM248 3 "register_operand" "")
7252 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7253 (clobber (reg:CC FLAGS_REG))])])
7255 ;; Split with 8bit unsigned divide:
7256 ;; if (dividend an divisor are in [0-255])
7257 ;; use 8bit unsigned integer divide
7259 ;; use original integer divide
7261 [(set (match_operand:SWI48 0 "register_operand" "")
7262 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7263 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7264 (set (match_operand:SWI48 1 "register_operand" "")
7265 (mod:SWI48 (match_dup 2) (match_dup 3)))
7266 (clobber (reg:CC FLAGS_REG))]
7267 "TARGET_USE_8BIT_IDIV
7268 && TARGET_QIMODE_MATH
7269 && can_create_pseudo_p ()
7270 && !optimize_insn_for_size_p ()"
7272 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7274 (define_insn_and_split "divmod<mode>4_1"
7275 [(set (match_operand:SWI48 0 "register_operand" "=a")
7276 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7277 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7278 (set (match_operand:SWI48 1 "register_operand" "=&d")
7279 (mod:SWI48 (match_dup 2) (match_dup 3)))
7280 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7281 (clobber (reg:CC FLAGS_REG))]
7285 [(parallel [(set (match_dup 1)
7286 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7287 (clobber (reg:CC FLAGS_REG))])
7288 (parallel [(set (match_dup 0)
7289 (div:SWI48 (match_dup 2) (match_dup 3)))
7291 (mod:SWI48 (match_dup 2) (match_dup 3)))
7293 (clobber (reg:CC FLAGS_REG))])]
7295 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7297 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7298 operands[4] = operands[2];
7301 /* Avoid use of cltd in favor of a mov+shift. */
7302 emit_move_insn (operands[1], operands[2]);
7303 operands[4] = operands[1];
7306 [(set_attr "type" "multi")
7307 (set_attr "mode" "<MODE>")])
7309 (define_insn_and_split "*divmod<mode>4"
7310 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7311 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7312 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7313 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7314 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7315 (clobber (reg:CC FLAGS_REG))]
7319 [(parallel [(set (match_dup 1)
7320 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7321 (clobber (reg:CC FLAGS_REG))])
7322 (parallel [(set (match_dup 0)
7323 (div:SWIM248 (match_dup 2) (match_dup 3)))
7325 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7327 (clobber (reg:CC FLAGS_REG))])]
7329 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7331 if (<MODE>mode != HImode
7332 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7333 operands[4] = operands[2];
7336 /* Avoid use of cltd in favor of a mov+shift. */
7337 emit_move_insn (operands[1], operands[2]);
7338 operands[4] = operands[1];
7341 [(set_attr "type" "multi")
7342 (set_attr "mode" "<MODE>")])
7344 (define_insn "*divmod<mode>4_noext"
7345 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7346 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7347 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7348 (set (match_operand:SWIM248 1 "register_operand" "=d")
7349 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7350 (use (match_operand:SWIM248 4 "register_operand" "1"))
7351 (clobber (reg:CC FLAGS_REG))]
7353 "idiv{<imodesuffix>}\t%3"
7354 [(set_attr "type" "idiv")
7355 (set_attr "mode" "<MODE>")])
7357 (define_expand "divmodqi4"
7358 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7360 (match_operand:QI 1 "register_operand" "")
7361 (match_operand:QI 2 "nonimmediate_operand" "")))
7362 (set (match_operand:QI 3 "register_operand" "")
7363 (mod:QI (match_dup 1) (match_dup 2)))
7364 (clobber (reg:CC FLAGS_REG))])]
7365 "TARGET_QIMODE_MATH"
7370 tmp0 = gen_reg_rtx (HImode);
7371 tmp1 = gen_reg_rtx (HImode);
7373 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7375 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7376 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7378 /* Extract remainder from AH. */
7379 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7380 insn = emit_move_insn (operands[3], tmp1);
7382 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7383 set_unique_reg_note (insn, REG_EQUAL, mod);
7385 /* Extract quotient from AL. */
7386 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7388 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7389 set_unique_reg_note (insn, REG_EQUAL, div);
7394 ;; Divide AX by r/m8, with result stored in
7397 ;; Change div/mod to HImode and extend the second argument to HImode
7398 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7399 ;; combine may fail.
7400 (define_insn "divmodhiqi3"
7401 [(set (match_operand:HI 0 "register_operand" "=a")
7406 (mod:HI (match_operand:HI 1 "register_operand" "0")
7408 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7412 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7413 (clobber (reg:CC FLAGS_REG))]
7414 "TARGET_QIMODE_MATH"
7416 [(set_attr "type" "idiv")
7417 (set_attr "mode" "QI")])
7419 (define_expand "udivmod<mode>4"
7420 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7422 (match_operand:SWIM248 1 "register_operand" "")
7423 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7424 (set (match_operand:SWIM248 3 "register_operand" "")
7425 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7426 (clobber (reg:CC FLAGS_REG))])])
7428 ;; Split with 8bit unsigned divide:
7429 ;; if (dividend an divisor are in [0-255])
7430 ;; use 8bit unsigned integer divide
7432 ;; use original integer divide
7434 [(set (match_operand:SWI48 0 "register_operand" "")
7435 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7436 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7437 (set (match_operand:SWI48 1 "register_operand" "")
7438 (umod:SWI48 (match_dup 2) (match_dup 3)))
7439 (clobber (reg:CC FLAGS_REG))]
7440 "TARGET_USE_8BIT_IDIV
7441 && TARGET_QIMODE_MATH
7442 && can_create_pseudo_p ()
7443 && !optimize_insn_for_size_p ()"
7445 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7447 (define_insn_and_split "udivmod<mode>4_1"
7448 [(set (match_operand:SWI48 0 "register_operand" "=a")
7449 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7450 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7451 (set (match_operand:SWI48 1 "register_operand" "=&d")
7452 (umod:SWI48 (match_dup 2) (match_dup 3)))
7453 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7454 (clobber (reg:CC FLAGS_REG))]
7458 [(set (match_dup 1) (const_int 0))
7459 (parallel [(set (match_dup 0)
7460 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7462 (umod:SWI48 (match_dup 2) (match_dup 3)))
7464 (clobber (reg:CC FLAGS_REG))])]
7466 [(set_attr "type" "multi")
7467 (set_attr "mode" "<MODE>")])
7469 (define_insn_and_split "*udivmod<mode>4"
7470 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7471 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7472 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7473 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7474 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7475 (clobber (reg:CC FLAGS_REG))]
7479 [(set (match_dup 1) (const_int 0))
7480 (parallel [(set (match_dup 0)
7481 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7483 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7485 (clobber (reg:CC FLAGS_REG))])]
7487 [(set_attr "type" "multi")
7488 (set_attr "mode" "<MODE>")])
7490 (define_insn "*udivmod<mode>4_noext"
7491 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7492 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7493 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7494 (set (match_operand:SWIM248 1 "register_operand" "=d")
7495 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7496 (use (match_operand:SWIM248 4 "register_operand" "1"))
7497 (clobber (reg:CC FLAGS_REG))]
7499 "div{<imodesuffix>}\t%3"
7500 [(set_attr "type" "idiv")
7501 (set_attr "mode" "<MODE>")])
7503 (define_expand "udivmodqi4"
7504 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7506 (match_operand:QI 1 "register_operand" "")
7507 (match_operand:QI 2 "nonimmediate_operand" "")))
7508 (set (match_operand:QI 3 "register_operand" "")
7509 (umod:QI (match_dup 1) (match_dup 2)))
7510 (clobber (reg:CC FLAGS_REG))])]
7511 "TARGET_QIMODE_MATH"
7516 tmp0 = gen_reg_rtx (HImode);
7517 tmp1 = gen_reg_rtx (HImode);
7519 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7521 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7522 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7524 /* Extract remainder from AH. */
7525 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7526 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7527 insn = emit_move_insn (operands[3], tmp1);
7529 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7530 set_unique_reg_note (insn, REG_EQUAL, mod);
7532 /* Extract quotient from AL. */
7533 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7535 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7536 set_unique_reg_note (insn, REG_EQUAL, div);
7541 (define_insn "udivmodhiqi3"
7542 [(set (match_operand:HI 0 "register_operand" "=a")
7547 (mod:HI (match_operand:HI 1 "register_operand" "0")
7549 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7553 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7554 (clobber (reg:CC FLAGS_REG))]
7555 "TARGET_QIMODE_MATH"
7557 [(set_attr "type" "idiv")
7558 (set_attr "mode" "QI")])
7560 ;; We cannot use div/idiv for double division, because it causes
7561 ;; "division by zero" on the overflow and that's not what we expect
7562 ;; from truncate. Because true (non truncating) double division is
7563 ;; never generated, we can't create this insn anyway.
7566 ; [(set (match_operand:SI 0 "register_operand" "=a")
7568 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7570 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7571 ; (set (match_operand:SI 3 "register_operand" "=d")
7573 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7574 ; (clobber (reg:CC FLAGS_REG))]
7576 ; "div{l}\t{%2, %0|%0, %2}"
7577 ; [(set_attr "type" "idiv")])
7579 ;;- Logical AND instructions
7581 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7582 ;; Note that this excludes ah.
7584 (define_expand "testsi_ccno_1"
7585 [(set (reg:CCNO FLAGS_REG)
7587 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7588 (match_operand:SI 1 "nonmemory_operand" ""))
7591 (define_expand "testqi_ccz_1"
7592 [(set (reg:CCZ FLAGS_REG)
7593 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7594 (match_operand:QI 1 "nonmemory_operand" ""))
7597 (define_expand "testdi_ccno_1"
7598 [(set (reg:CCNO FLAGS_REG)
7600 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7601 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7603 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7605 (define_insn "*testdi_1"
7606 [(set (reg FLAGS_REG)
7609 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7610 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7612 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7613 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7615 test{l}\t{%k1, %k0|%k0, %k1}
7616 test{l}\t{%k1, %k0|%k0, %k1}
7617 test{q}\t{%1, %0|%0, %1}
7618 test{q}\t{%1, %0|%0, %1}
7619 test{q}\t{%1, %0|%0, %1}"
7620 [(set_attr "type" "test")
7621 (set_attr "modrm" "0,1,0,1,1")
7622 (set_attr "mode" "SI,SI,DI,DI,DI")])
7624 (define_insn "*testqi_1_maybe_si"
7625 [(set (reg FLAGS_REG)
7628 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7629 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7631 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7632 && ix86_match_ccmode (insn,
7633 CONST_INT_P (operands[1])
7634 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7636 if (which_alternative == 3)
7638 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7639 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7640 return "test{l}\t{%1, %k0|%k0, %1}";
7642 return "test{b}\t{%1, %0|%0, %1}";
7644 [(set_attr "type" "test")
7645 (set_attr "modrm" "0,1,1,1")
7646 (set_attr "mode" "QI,QI,QI,SI")
7647 (set_attr "pent_pair" "uv,np,uv,np")])
7649 (define_insn "*test<mode>_1"
7650 [(set (reg FLAGS_REG)
7653 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7654 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7656 "ix86_match_ccmode (insn, CCNOmode)
7657 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7658 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7659 [(set_attr "type" "test")
7660 (set_attr "modrm" "0,1,1")
7661 (set_attr "mode" "<MODE>")
7662 (set_attr "pent_pair" "uv,np,uv")])
7664 (define_expand "testqi_ext_ccno_0"
7665 [(set (reg:CCNO FLAGS_REG)
7669 (match_operand 0 "ext_register_operand" "")
7672 (match_operand 1 "const_int_operand" ""))
7675 (define_insn "*testqi_ext_0"
7676 [(set (reg FLAGS_REG)
7680 (match_operand 0 "ext_register_operand" "Q")
7683 (match_operand 1 "const_int_operand" "n"))
7685 "ix86_match_ccmode (insn, CCNOmode)"
7686 "test{b}\t{%1, %h0|%h0, %1}"
7687 [(set_attr "type" "test")
7688 (set_attr "mode" "QI")
7689 (set_attr "length_immediate" "1")
7690 (set_attr "modrm" "1")
7691 (set_attr "pent_pair" "np")])
7693 (define_insn "*testqi_ext_1_rex64"
7694 [(set (reg FLAGS_REG)
7698 (match_operand 0 "ext_register_operand" "Q")
7702 (match_operand:QI 1 "register_operand" "Q")))
7704 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7705 "test{b}\t{%1, %h0|%h0, %1}"
7706 [(set_attr "type" "test")
7707 (set_attr "mode" "QI")])
7709 (define_insn "*testqi_ext_1"
7710 [(set (reg FLAGS_REG)
7714 (match_operand 0 "ext_register_operand" "Q")
7718 (match_operand:QI 1 "general_operand" "Qm")))
7720 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7721 "test{b}\t{%1, %h0|%h0, %1}"
7722 [(set_attr "type" "test")
7723 (set_attr "mode" "QI")])
7725 (define_insn "*testqi_ext_2"
7726 [(set (reg FLAGS_REG)
7730 (match_operand 0 "ext_register_operand" "Q")
7734 (match_operand 1 "ext_register_operand" "Q")
7738 "ix86_match_ccmode (insn, CCNOmode)"
7739 "test{b}\t{%h1, %h0|%h0, %h1}"
7740 [(set_attr "type" "test")
7741 (set_attr "mode" "QI")])
7743 (define_insn "*testqi_ext_3_rex64"
7744 [(set (reg FLAGS_REG)
7745 (compare (zero_extract:DI
7746 (match_operand 0 "nonimmediate_operand" "rm")
7747 (match_operand:DI 1 "const_int_operand" "")
7748 (match_operand:DI 2 "const_int_operand" ""))
7751 && ix86_match_ccmode (insn, CCNOmode)
7752 && INTVAL (operands[1]) > 0
7753 && INTVAL (operands[2]) >= 0
7754 /* Ensure that resulting mask is zero or sign extended operand. */
7755 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7756 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7757 && INTVAL (operands[1]) > 32))
7758 && (GET_MODE (operands[0]) == SImode
7759 || GET_MODE (operands[0]) == DImode
7760 || GET_MODE (operands[0]) == HImode
7761 || GET_MODE (operands[0]) == QImode)"
7764 ;; Combine likes to form bit extractions for some tests. Humor it.
7765 (define_insn "*testqi_ext_3"
7766 [(set (reg FLAGS_REG)
7767 (compare (zero_extract:SI
7768 (match_operand 0 "nonimmediate_operand" "rm")
7769 (match_operand:SI 1 "const_int_operand" "")
7770 (match_operand:SI 2 "const_int_operand" ""))
7772 "ix86_match_ccmode (insn, CCNOmode)
7773 && INTVAL (operands[1]) > 0
7774 && INTVAL (operands[2]) >= 0
7775 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7776 && (GET_MODE (operands[0]) == SImode
7777 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7778 || GET_MODE (operands[0]) == HImode
7779 || GET_MODE (operands[0]) == QImode)"
7783 [(set (match_operand 0 "flags_reg_operand" "")
7784 (match_operator 1 "compare_operator"
7786 (match_operand 2 "nonimmediate_operand" "")
7787 (match_operand 3 "const_int_operand" "")
7788 (match_operand 4 "const_int_operand" ""))
7790 "ix86_match_ccmode (insn, CCNOmode)"
7791 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7793 rtx val = operands[2];
7794 HOST_WIDE_INT len = INTVAL (operands[3]);
7795 HOST_WIDE_INT pos = INTVAL (operands[4]);
7797 enum machine_mode mode, submode;
7799 mode = GET_MODE (val);
7802 /* ??? Combine likes to put non-volatile mem extractions in QImode
7803 no matter the size of the test. So find a mode that works. */
7804 if (! MEM_VOLATILE_P (val))
7806 mode = smallest_mode_for_size (pos + len, MODE_INT);
7807 val = adjust_address (val, mode, 0);
7810 else if (GET_CODE (val) == SUBREG
7811 && (submode = GET_MODE (SUBREG_REG (val)),
7812 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7813 && pos + len <= GET_MODE_BITSIZE (submode)
7814 && GET_MODE_CLASS (submode) == MODE_INT)
7816 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7818 val = SUBREG_REG (val);
7820 else if (mode == HImode && pos + len <= 8)
7822 /* Small HImode tests can be converted to QImode. */
7824 val = gen_lowpart (QImode, val);
7827 if (len == HOST_BITS_PER_WIDE_INT)
7830 mask = ((HOST_WIDE_INT)1 << len) - 1;
7833 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7836 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7837 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7838 ;; this is relatively important trick.
7839 ;; Do the conversion only post-reload to avoid limiting of the register class
7842 [(set (match_operand 0 "flags_reg_operand" "")
7843 (match_operator 1 "compare_operator"
7844 [(and (match_operand 2 "register_operand" "")
7845 (match_operand 3 "const_int_operand" ""))
7848 && QI_REG_P (operands[2])
7849 && GET_MODE (operands[2]) != QImode
7850 && ((ix86_match_ccmode (insn, CCZmode)
7851 && !(INTVAL (operands[3]) & ~(255 << 8)))
7852 || (ix86_match_ccmode (insn, CCNOmode)
7853 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7856 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7859 "operands[2] = gen_lowpart (SImode, operands[2]);
7860 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7863 [(set (match_operand 0 "flags_reg_operand" "")
7864 (match_operator 1 "compare_operator"
7865 [(and (match_operand 2 "nonimmediate_operand" "")
7866 (match_operand 3 "const_int_operand" ""))
7869 && GET_MODE (operands[2]) != QImode
7870 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7871 && ((ix86_match_ccmode (insn, CCZmode)
7872 && !(INTVAL (operands[3]) & ~255))
7873 || (ix86_match_ccmode (insn, CCNOmode)
7874 && !(INTVAL (operands[3]) & ~127)))"
7876 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7878 "operands[2] = gen_lowpart (QImode, operands[2]);
7879 operands[3] = gen_lowpart (QImode, operands[3]);")
7881 ;; %%% This used to optimize known byte-wide and operations to memory,
7882 ;; and sometimes to QImode registers. If this is considered useful,
7883 ;; it should be done with splitters.
7885 (define_expand "and<mode>3"
7886 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7887 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7888 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7890 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7892 (define_insn "*anddi_1"
7893 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7895 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7896 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7897 (clobber (reg:CC FLAGS_REG))]
7898 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7900 switch (get_attr_type (insn))
7904 enum machine_mode mode;
7906 gcc_assert (CONST_INT_P (operands[2]));
7907 if (INTVAL (operands[2]) == 0xff)
7911 gcc_assert (INTVAL (operands[2]) == 0xffff);
7915 operands[1] = gen_lowpart (mode, operands[1]);
7917 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7919 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7923 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7924 if (get_attr_mode (insn) == MODE_SI)
7925 return "and{l}\t{%k2, %k0|%k0, %k2}";
7927 return "and{q}\t{%2, %0|%0, %2}";
7930 [(set_attr "type" "alu,alu,alu,imovx")
7931 (set_attr "length_immediate" "*,*,*,0")
7932 (set (attr "prefix_rex")
7934 (and (eq_attr "type" "imovx")
7935 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7936 (match_operand 1 "ext_QIreg_operand" "")))
7938 (const_string "*")))
7939 (set_attr "mode" "SI,DI,DI,SI")])
7941 (define_insn "*andsi_1"
7942 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7943 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7944 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7945 (clobber (reg:CC FLAGS_REG))]
7946 "ix86_binary_operator_ok (AND, SImode, operands)"
7948 switch (get_attr_type (insn))
7952 enum machine_mode mode;
7954 gcc_assert (CONST_INT_P (operands[2]));
7955 if (INTVAL (operands[2]) == 0xff)
7959 gcc_assert (INTVAL (operands[2]) == 0xffff);
7963 operands[1] = gen_lowpart (mode, operands[1]);
7965 return "movz{bl|x}\t{%1, %0|%0, %1}";
7967 return "movz{wl|x}\t{%1, %0|%0, %1}";
7971 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7972 return "and{l}\t{%2, %0|%0, %2}";
7975 [(set_attr "type" "alu,alu,imovx")
7976 (set (attr "prefix_rex")
7978 (and (eq_attr "type" "imovx")
7979 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7980 (match_operand 1 "ext_QIreg_operand" "")))
7982 (const_string "*")))
7983 (set_attr "length_immediate" "*,*,0")
7984 (set_attr "mode" "SI")])
7986 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7987 (define_insn "*andsi_1_zext"
7988 [(set (match_operand:DI 0 "register_operand" "=r")
7990 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7991 (match_operand:SI 2 "general_operand" "g"))))
7992 (clobber (reg:CC FLAGS_REG))]
7993 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7994 "and{l}\t{%2, %k0|%k0, %2}"
7995 [(set_attr "type" "alu")
7996 (set_attr "mode" "SI")])
7998 (define_insn "*andhi_1"
7999 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8000 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8001 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8002 (clobber (reg:CC FLAGS_REG))]
8003 "ix86_binary_operator_ok (AND, HImode, operands)"
8005 switch (get_attr_type (insn))
8008 gcc_assert (CONST_INT_P (operands[2]));
8009 gcc_assert (INTVAL (operands[2]) == 0xff);
8010 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8013 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8015 return "and{w}\t{%2, %0|%0, %2}";
8018 [(set_attr "type" "alu,alu,imovx")
8019 (set_attr "length_immediate" "*,*,0")
8020 (set (attr "prefix_rex")
8022 (and (eq_attr "type" "imovx")
8023 (match_operand 1 "ext_QIreg_operand" ""))
8025 (const_string "*")))
8026 (set_attr "mode" "HI,HI,SI")])
8028 ;; %%% Potential partial reg stall on alternative 2. What to do?
8029 (define_insn "*andqi_1"
8030 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8031 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8032 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8033 (clobber (reg:CC FLAGS_REG))]
8034 "ix86_binary_operator_ok (AND, QImode, operands)"
8036 and{b}\t{%2, %0|%0, %2}
8037 and{b}\t{%2, %0|%0, %2}
8038 and{l}\t{%k2, %k0|%k0, %k2}"
8039 [(set_attr "type" "alu")
8040 (set_attr "mode" "QI,QI,SI")])
8042 (define_insn "*andqi_1_slp"
8043 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8044 (and:QI (match_dup 0)
8045 (match_operand:QI 1 "general_operand" "qn,qmn")))
8046 (clobber (reg:CC FLAGS_REG))]
8047 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8048 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8049 "and{b}\t{%1, %0|%0, %1}"
8050 [(set_attr "type" "alu1")
8051 (set_attr "mode" "QI")])
8054 [(set (match_operand 0 "register_operand" "")
8056 (const_int -65536)))
8057 (clobber (reg:CC FLAGS_REG))]
8058 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8059 || optimize_function_for_size_p (cfun)"
8060 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8061 "operands[1] = gen_lowpart (HImode, operands[0]);")
8064 [(set (match_operand 0 "ext_register_operand" "")
8067 (clobber (reg:CC FLAGS_REG))]
8068 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8069 && reload_completed"
8070 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8071 "operands[1] = gen_lowpart (QImode, operands[0]);")
8074 [(set (match_operand 0 "ext_register_operand" "")
8076 (const_int -65281)))
8077 (clobber (reg:CC FLAGS_REG))]
8078 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8079 && reload_completed"
8080 [(parallel [(set (zero_extract:SI (match_dup 0)
8084 (zero_extract:SI (match_dup 0)
8087 (zero_extract:SI (match_dup 0)
8090 (clobber (reg:CC FLAGS_REG))])]
8091 "operands[0] = gen_lowpart (SImode, operands[0]);")
8093 (define_insn "*anddi_2"
8094 [(set (reg FLAGS_REG)
8097 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8098 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8100 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8101 (and:DI (match_dup 1) (match_dup 2)))]
8102 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8103 && ix86_binary_operator_ok (AND, DImode, operands)"
8105 and{l}\t{%k2, %k0|%k0, %k2}
8106 and{q}\t{%2, %0|%0, %2}
8107 and{q}\t{%2, %0|%0, %2}"
8108 [(set_attr "type" "alu")
8109 (set_attr "mode" "SI,DI,DI")])
8111 (define_insn "*andqi_2_maybe_si"
8112 [(set (reg FLAGS_REG)
8114 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8115 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8117 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8118 (and:QI (match_dup 1) (match_dup 2)))]
8119 "ix86_binary_operator_ok (AND, QImode, operands)
8120 && ix86_match_ccmode (insn,
8121 CONST_INT_P (operands[2])
8122 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8124 if (which_alternative == 2)
8126 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8127 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8128 return "and{l}\t{%2, %k0|%k0, %2}";
8130 return "and{b}\t{%2, %0|%0, %2}";
8132 [(set_attr "type" "alu")
8133 (set_attr "mode" "QI,QI,SI")])
8135 (define_insn "*and<mode>_2"
8136 [(set (reg FLAGS_REG)
8137 (compare (and:SWI124
8138 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8139 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8141 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8142 (and:SWI124 (match_dup 1) (match_dup 2)))]
8143 "ix86_match_ccmode (insn, CCNOmode)
8144 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8145 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8146 [(set_attr "type" "alu")
8147 (set_attr "mode" "<MODE>")])
8149 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8150 (define_insn "*andsi_2_zext"
8151 [(set (reg FLAGS_REG)
8153 (match_operand:SI 1 "nonimmediate_operand" "%0")
8154 (match_operand:SI 2 "general_operand" "g"))
8156 (set (match_operand:DI 0 "register_operand" "=r")
8157 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8158 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8159 && ix86_binary_operator_ok (AND, SImode, operands)"
8160 "and{l}\t{%2, %k0|%k0, %2}"
8161 [(set_attr "type" "alu")
8162 (set_attr "mode" "SI")])
8164 (define_insn "*andqi_2_slp"
8165 [(set (reg FLAGS_REG)
8167 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8168 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8170 (set (strict_low_part (match_dup 0))
8171 (and:QI (match_dup 0) (match_dup 1)))]
8172 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8173 && ix86_match_ccmode (insn, CCNOmode)
8174 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8175 "and{b}\t{%1, %0|%0, %1}"
8176 [(set_attr "type" "alu1")
8177 (set_attr "mode" "QI")])
8179 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8180 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8181 ;; for a QImode operand, which of course failed.
8182 (define_insn "andqi_ext_0"
8183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8188 (match_operand 1 "ext_register_operand" "0")
8191 (match_operand 2 "const_int_operand" "n")))
8192 (clobber (reg:CC FLAGS_REG))]
8194 "and{b}\t{%2, %h0|%h0, %2}"
8195 [(set_attr "type" "alu")
8196 (set_attr "length_immediate" "1")
8197 (set_attr "modrm" "1")
8198 (set_attr "mode" "QI")])
8200 ;; Generated by peephole translating test to and. This shows up
8201 ;; often in fp comparisons.
8202 (define_insn "*andqi_ext_0_cc"
8203 [(set (reg FLAGS_REG)
8207 (match_operand 1 "ext_register_operand" "0")
8210 (match_operand 2 "const_int_operand" "n"))
8212 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8221 "ix86_match_ccmode (insn, CCNOmode)"
8222 "and{b}\t{%2, %h0|%h0, %2}"
8223 [(set_attr "type" "alu")
8224 (set_attr "length_immediate" "1")
8225 (set_attr "modrm" "1")
8226 (set_attr "mode" "QI")])
8228 (define_insn "*andqi_ext_1_rex64"
8229 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8234 (match_operand 1 "ext_register_operand" "0")
8238 (match_operand 2 "ext_register_operand" "Q"))))
8239 (clobber (reg:CC FLAGS_REG))]
8241 "and{b}\t{%2, %h0|%h0, %2}"
8242 [(set_attr "type" "alu")
8243 (set_attr "length_immediate" "0")
8244 (set_attr "mode" "QI")])
8246 (define_insn "*andqi_ext_1"
8247 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8252 (match_operand 1 "ext_register_operand" "0")
8256 (match_operand:QI 2 "general_operand" "Qm"))))
8257 (clobber (reg:CC FLAGS_REG))]
8259 "and{b}\t{%2, %h0|%h0, %2}"
8260 [(set_attr "type" "alu")
8261 (set_attr "length_immediate" "0")
8262 (set_attr "mode" "QI")])
8264 (define_insn "*andqi_ext_2"
8265 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8270 (match_operand 1 "ext_register_operand" "%0")
8274 (match_operand 2 "ext_register_operand" "Q")
8277 (clobber (reg:CC FLAGS_REG))]
8279 "and{b}\t{%h2, %h0|%h0, %h2}"
8280 [(set_attr "type" "alu")
8281 (set_attr "length_immediate" "0")
8282 (set_attr "mode" "QI")])
8284 ;; Convert wide AND instructions with immediate operand to shorter QImode
8285 ;; equivalents when possible.
8286 ;; Don't do the splitting with memory operands, since it introduces risk
8287 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8288 ;; for size, but that can (should?) be handled by generic code instead.
8290 [(set (match_operand 0 "register_operand" "")
8291 (and (match_operand 1 "register_operand" "")
8292 (match_operand 2 "const_int_operand" "")))
8293 (clobber (reg:CC FLAGS_REG))]
8295 && QI_REG_P (operands[0])
8296 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8297 && !(~INTVAL (operands[2]) & ~(255 << 8))
8298 && GET_MODE (operands[0]) != QImode"
8299 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8300 (and:SI (zero_extract:SI (match_dup 1)
8301 (const_int 8) (const_int 8))
8303 (clobber (reg:CC FLAGS_REG))])]
8304 "operands[0] = gen_lowpart (SImode, operands[0]);
8305 operands[1] = gen_lowpart (SImode, operands[1]);
8306 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8308 ;; Since AND can be encoded with sign extended immediate, this is only
8309 ;; profitable when 7th bit is not set.
8311 [(set (match_operand 0 "register_operand" "")
8312 (and (match_operand 1 "general_operand" "")
8313 (match_operand 2 "const_int_operand" "")))
8314 (clobber (reg:CC FLAGS_REG))]
8316 && ANY_QI_REG_P (operands[0])
8317 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8318 && !(~INTVAL (operands[2]) & ~255)
8319 && !(INTVAL (operands[2]) & 128)
8320 && GET_MODE (operands[0]) != QImode"
8321 [(parallel [(set (strict_low_part (match_dup 0))
8322 (and:QI (match_dup 1)
8324 (clobber (reg:CC FLAGS_REG))])]
8325 "operands[0] = gen_lowpart (QImode, operands[0]);
8326 operands[1] = gen_lowpart (QImode, operands[1]);
8327 operands[2] = gen_lowpart (QImode, operands[2]);")
8329 ;; Logical inclusive and exclusive OR instructions
8331 ;; %%% This used to optimize known byte-wide and operations to memory.
8332 ;; If this is considered useful, it should be done with splitters.
8334 (define_expand "<code><mode>3"
8335 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8336 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8337 (match_operand:SWIM 2 "<general_operand>" "")))]
8339 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8341 (define_insn "*<code><mode>_1"
8342 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8344 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8345 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8346 (clobber (reg:CC FLAGS_REG))]
8347 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8348 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8349 [(set_attr "type" "alu")
8350 (set_attr "mode" "<MODE>")])
8352 ;; %%% Potential partial reg stall on alternative 2. What to do?
8353 (define_insn "*<code>qi_1"
8354 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8355 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8356 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8357 (clobber (reg:CC FLAGS_REG))]
8358 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8360 <logic>{b}\t{%2, %0|%0, %2}
8361 <logic>{b}\t{%2, %0|%0, %2}
8362 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8363 [(set_attr "type" "alu")
8364 (set_attr "mode" "QI,QI,SI")])
8366 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8367 (define_insn "*<code>si_1_zext"
8368 [(set (match_operand:DI 0 "register_operand" "=r")
8370 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8371 (match_operand:SI 2 "general_operand" "g"))))
8372 (clobber (reg:CC FLAGS_REG))]
8373 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8374 "<logic>{l}\t{%2, %k0|%k0, %2}"
8375 [(set_attr "type" "alu")
8376 (set_attr "mode" "SI")])
8378 (define_insn "*<code>si_1_zext_imm"
8379 [(set (match_operand:DI 0 "register_operand" "=r")
8381 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8382 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8383 (clobber (reg:CC FLAGS_REG))]
8384 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8385 "<logic>{l}\t{%2, %k0|%k0, %2}"
8386 [(set_attr "type" "alu")
8387 (set_attr "mode" "SI")])
8389 (define_insn "*<code>qi_1_slp"
8390 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8391 (any_or:QI (match_dup 0)
8392 (match_operand:QI 1 "general_operand" "qmn,qn")))
8393 (clobber (reg:CC FLAGS_REG))]
8394 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8395 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8396 "<logic>{b}\t{%1, %0|%0, %1}"
8397 [(set_attr "type" "alu1")
8398 (set_attr "mode" "QI")])
8400 (define_insn "*<code><mode>_2"
8401 [(set (reg FLAGS_REG)
8402 (compare (any_or:SWI
8403 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8404 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8406 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8407 (any_or:SWI (match_dup 1) (match_dup 2)))]
8408 "ix86_match_ccmode (insn, CCNOmode)
8409 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8410 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8411 [(set_attr "type" "alu")
8412 (set_attr "mode" "<MODE>")])
8414 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8415 ;; ??? Special case for immediate operand is missing - it is tricky.
8416 (define_insn "*<code>si_2_zext"
8417 [(set (reg FLAGS_REG)
8418 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8419 (match_operand:SI 2 "general_operand" "g"))
8421 (set (match_operand:DI 0 "register_operand" "=r")
8422 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8423 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8424 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8425 "<logic>{l}\t{%2, %k0|%k0, %2}"
8426 [(set_attr "type" "alu")
8427 (set_attr "mode" "SI")])
8429 (define_insn "*<code>si_2_zext_imm"
8430 [(set (reg FLAGS_REG)
8432 (match_operand:SI 1 "nonimmediate_operand" "%0")
8433 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8435 (set (match_operand:DI 0 "register_operand" "=r")
8436 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8437 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8438 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8439 "<logic>{l}\t{%2, %k0|%k0, %2}"
8440 [(set_attr "type" "alu")
8441 (set_attr "mode" "SI")])
8443 (define_insn "*<code>qi_2_slp"
8444 [(set (reg FLAGS_REG)
8445 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8446 (match_operand:QI 1 "general_operand" "qmn,qn"))
8448 (set (strict_low_part (match_dup 0))
8449 (any_or:QI (match_dup 0) (match_dup 1)))]
8450 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8451 && ix86_match_ccmode (insn, CCNOmode)
8452 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8453 "<logic>{b}\t{%1, %0|%0, %1}"
8454 [(set_attr "type" "alu1")
8455 (set_attr "mode" "QI")])
8457 (define_insn "*<code><mode>_3"
8458 [(set (reg FLAGS_REG)
8459 (compare (any_or:SWI
8460 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8461 (match_operand:SWI 2 "<general_operand>" "<g>"))
8463 (clobber (match_scratch:SWI 0 "=<r>"))]
8464 "ix86_match_ccmode (insn, CCNOmode)
8465 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8466 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8467 [(set_attr "type" "alu")
8468 (set_attr "mode" "<MODE>")])
8470 (define_insn "*<code>qi_ext_0"
8471 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8476 (match_operand 1 "ext_register_operand" "0")
8479 (match_operand 2 "const_int_operand" "n")))
8480 (clobber (reg:CC FLAGS_REG))]
8481 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8482 "<logic>{b}\t{%2, %h0|%h0, %2}"
8483 [(set_attr "type" "alu")
8484 (set_attr "length_immediate" "1")
8485 (set_attr "modrm" "1")
8486 (set_attr "mode" "QI")])
8488 (define_insn "*<code>qi_ext_1_rex64"
8489 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8494 (match_operand 1 "ext_register_operand" "0")
8498 (match_operand 2 "ext_register_operand" "Q"))))
8499 (clobber (reg:CC FLAGS_REG))]
8501 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8502 "<logic>{b}\t{%2, %h0|%h0, %2}"
8503 [(set_attr "type" "alu")
8504 (set_attr "length_immediate" "0")
8505 (set_attr "mode" "QI")])
8507 (define_insn "*<code>qi_ext_1"
8508 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8513 (match_operand 1 "ext_register_operand" "0")
8517 (match_operand:QI 2 "general_operand" "Qm"))))
8518 (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" "0")
8524 (set_attr "mode" "QI")])
8526 (define_insn "*<code>qi_ext_2"
8527 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8531 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8534 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8537 (clobber (reg:CC FLAGS_REG))]
8538 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8539 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8540 [(set_attr "type" "alu")
8541 (set_attr "length_immediate" "0")
8542 (set_attr "mode" "QI")])
8545 [(set (match_operand 0 "register_operand" "")
8546 (any_or (match_operand 1 "register_operand" "")
8547 (match_operand 2 "const_int_operand" "")))
8548 (clobber (reg:CC FLAGS_REG))]
8550 && QI_REG_P (operands[0])
8551 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8552 && !(INTVAL (operands[2]) & ~(255 << 8))
8553 && GET_MODE (operands[0]) != QImode"
8554 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8555 (any_or:SI (zero_extract:SI (match_dup 1)
8556 (const_int 8) (const_int 8))
8558 (clobber (reg:CC FLAGS_REG))])]
8559 "operands[0] = gen_lowpart (SImode, operands[0]);
8560 operands[1] = gen_lowpart (SImode, operands[1]);
8561 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8563 ;; Since OR can be encoded with sign extended immediate, this is only
8564 ;; profitable when 7th bit is set.
8566 [(set (match_operand 0 "register_operand" "")
8567 (any_or (match_operand 1 "general_operand" "")
8568 (match_operand 2 "const_int_operand" "")))
8569 (clobber (reg:CC FLAGS_REG))]
8571 && ANY_QI_REG_P (operands[0])
8572 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8573 && !(INTVAL (operands[2]) & ~255)
8574 && (INTVAL (operands[2]) & 128)
8575 && GET_MODE (operands[0]) != QImode"
8576 [(parallel [(set (strict_low_part (match_dup 0))
8577 (any_or:QI (match_dup 1)
8579 (clobber (reg:CC FLAGS_REG))])]
8580 "operands[0] = gen_lowpart (QImode, operands[0]);
8581 operands[1] = gen_lowpart (QImode, operands[1]);
8582 operands[2] = gen_lowpart (QImode, operands[2]);")
8584 (define_expand "xorqi_cc_ext_1"
8586 (set (reg:CCNO FLAGS_REG)
8590 (match_operand 1 "ext_register_operand" "")
8593 (match_operand:QI 2 "general_operand" ""))
8595 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8605 (define_insn "*xorqi_cc_ext_1_rex64"
8606 [(set (reg FLAGS_REG)
8610 (match_operand 1 "ext_register_operand" "0")
8613 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8615 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8624 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8625 "xor{b}\t{%2, %h0|%h0, %2}"
8626 [(set_attr "type" "alu")
8627 (set_attr "modrm" "1")
8628 (set_attr "mode" "QI")])
8630 (define_insn "*xorqi_cc_ext_1"
8631 [(set (reg FLAGS_REG)
8635 (match_operand 1 "ext_register_operand" "0")
8638 (match_operand:QI 2 "general_operand" "qmn"))
8640 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8649 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8650 "xor{b}\t{%2, %h0|%h0, %2}"
8651 [(set_attr "type" "alu")
8652 (set_attr "modrm" "1")
8653 (set_attr "mode" "QI")])
8655 ;; Negation instructions
8657 (define_expand "neg<mode>2"
8658 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8659 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8661 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8663 (define_insn_and_split "*neg<dwi>2_doubleword"
8664 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8665 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8666 (clobber (reg:CC FLAGS_REG))]
8667 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8671 [(set (reg:CCZ FLAGS_REG)
8672 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8673 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8676 (plus:DWIH (match_dup 3)
8677 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8679 (clobber (reg:CC FLAGS_REG))])
8682 (neg:DWIH (match_dup 2)))
8683 (clobber (reg:CC FLAGS_REG))])]
8684 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8686 (define_insn "*neg<mode>2_1"
8687 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8688 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8689 (clobber (reg:CC FLAGS_REG))]
8690 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8691 "neg{<imodesuffix>}\t%0"
8692 [(set_attr "type" "negnot")
8693 (set_attr "mode" "<MODE>")])
8695 ;; Combine is quite creative about this pattern.
8696 (define_insn "*negsi2_1_zext"
8697 [(set (match_operand:DI 0 "register_operand" "=r")
8699 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8702 (clobber (reg:CC FLAGS_REG))]
8703 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8705 [(set_attr "type" "negnot")
8706 (set_attr "mode" "SI")])
8708 ;; The problem with neg is that it does not perform (compare x 0),
8709 ;; it really performs (compare 0 x), which leaves us with the zero
8710 ;; flag being the only useful item.
8712 (define_insn "*neg<mode>2_cmpz"
8713 [(set (reg:CCZ FLAGS_REG)
8715 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8717 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8718 (neg:SWI (match_dup 1)))]
8719 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8720 "neg{<imodesuffix>}\t%0"
8721 [(set_attr "type" "negnot")
8722 (set_attr "mode" "<MODE>")])
8724 (define_insn "*negsi2_cmpz_zext"
8725 [(set (reg:CCZ FLAGS_REG)
8729 (match_operand:DI 1 "register_operand" "0")
8733 (set (match_operand:DI 0 "register_operand" "=r")
8734 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8737 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8739 [(set_attr "type" "negnot")
8740 (set_attr "mode" "SI")])
8742 ;; Changing of sign for FP values is doable using integer unit too.
8744 (define_expand "<code><mode>2"
8745 [(set (match_operand:X87MODEF 0 "register_operand" "")
8746 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8747 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8748 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8750 (define_insn "*absneg<mode>2_mixed"
8751 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8752 (match_operator:MODEF 3 "absneg_operator"
8753 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8754 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8755 (clobber (reg:CC FLAGS_REG))]
8756 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8759 (define_insn "*absneg<mode>2_sse"
8760 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8761 (match_operator:MODEF 3 "absneg_operator"
8762 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8763 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8764 (clobber (reg:CC FLAGS_REG))]
8765 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8768 (define_insn "*absneg<mode>2_i387"
8769 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8770 (match_operator:X87MODEF 3 "absneg_operator"
8771 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8772 (use (match_operand 2 "" ""))
8773 (clobber (reg:CC FLAGS_REG))]
8774 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8777 (define_expand "<code>tf2"
8778 [(set (match_operand:TF 0 "register_operand" "")
8779 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8781 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8783 (define_insn "*absnegtf2_sse"
8784 [(set (match_operand:TF 0 "register_operand" "=x,x")
8785 (match_operator:TF 3 "absneg_operator"
8786 [(match_operand:TF 1 "register_operand" "0,x")]))
8787 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8788 (clobber (reg:CC FLAGS_REG))]
8792 ;; Splitters for fp abs and neg.
8795 [(set (match_operand 0 "fp_register_operand" "")
8796 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8797 (use (match_operand 2 "" ""))
8798 (clobber (reg:CC FLAGS_REG))]
8800 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8803 [(set (match_operand 0 "register_operand" "")
8804 (match_operator 3 "absneg_operator"
8805 [(match_operand 1 "register_operand" "")]))
8806 (use (match_operand 2 "nonimmediate_operand" ""))
8807 (clobber (reg:CC FLAGS_REG))]
8808 "reload_completed && SSE_REG_P (operands[0])"
8809 [(set (match_dup 0) (match_dup 3))]
8811 enum machine_mode mode = GET_MODE (operands[0]);
8812 enum machine_mode vmode = GET_MODE (operands[2]);
8815 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8816 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8817 if (operands_match_p (operands[0], operands[2]))
8820 operands[1] = operands[2];
8823 if (GET_CODE (operands[3]) == ABS)
8824 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8826 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8831 [(set (match_operand:SF 0 "register_operand" "")
8832 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8833 (use (match_operand:V4SF 2 "" ""))
8834 (clobber (reg:CC FLAGS_REG))]
8836 [(parallel [(set (match_dup 0) (match_dup 1))
8837 (clobber (reg:CC FLAGS_REG))])]
8840 operands[0] = gen_lowpart (SImode, operands[0]);
8841 if (GET_CODE (operands[1]) == ABS)
8843 tmp = gen_int_mode (0x7fffffff, SImode);
8844 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8848 tmp = gen_int_mode (0x80000000, SImode);
8849 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8855 [(set (match_operand:DF 0 "register_operand" "")
8856 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8857 (use (match_operand 2 "" ""))
8858 (clobber (reg:CC FLAGS_REG))]
8860 [(parallel [(set (match_dup 0) (match_dup 1))
8861 (clobber (reg:CC FLAGS_REG))])]
8866 tmp = gen_lowpart (DImode, operands[0]);
8867 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8870 if (GET_CODE (operands[1]) == ABS)
8873 tmp = gen_rtx_NOT (DImode, tmp);
8877 operands[0] = gen_highpart (SImode, operands[0]);
8878 if (GET_CODE (operands[1]) == ABS)
8880 tmp = gen_int_mode (0x7fffffff, SImode);
8881 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8885 tmp = gen_int_mode (0x80000000, SImode);
8886 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8893 [(set (match_operand:XF 0 "register_operand" "")
8894 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8895 (use (match_operand 2 "" ""))
8896 (clobber (reg:CC FLAGS_REG))]
8898 [(parallel [(set (match_dup 0) (match_dup 1))
8899 (clobber (reg:CC FLAGS_REG))])]
8902 operands[0] = gen_rtx_REG (SImode,
8903 true_regnum (operands[0])
8904 + (TARGET_64BIT ? 1 : 2));
8905 if (GET_CODE (operands[1]) == ABS)
8907 tmp = GEN_INT (0x7fff);
8908 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8912 tmp = GEN_INT (0x8000);
8913 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8918 ;; Conditionalize these after reload. If they match before reload, we
8919 ;; lose the clobber and ability to use integer instructions.
8921 (define_insn "*<code><mode>2_1"
8922 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8923 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8925 && (reload_completed
8926 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8927 "f<absneg_mnemonic>"
8928 [(set_attr "type" "fsgn")
8929 (set_attr "mode" "<MODE>")])
8931 (define_insn "*<code>extendsfdf2"
8932 [(set (match_operand:DF 0 "register_operand" "=f")
8933 (absneg:DF (float_extend:DF
8934 (match_operand:SF 1 "register_operand" "0"))))]
8935 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8936 "f<absneg_mnemonic>"
8937 [(set_attr "type" "fsgn")
8938 (set_attr "mode" "DF")])
8940 (define_insn "*<code>extendsfxf2"
8941 [(set (match_operand:XF 0 "register_operand" "=f")
8942 (absneg:XF (float_extend:XF
8943 (match_operand:SF 1 "register_operand" "0"))))]
8945 "f<absneg_mnemonic>"
8946 [(set_attr "type" "fsgn")
8947 (set_attr "mode" "XF")])
8949 (define_insn "*<code>extenddfxf2"
8950 [(set (match_operand:XF 0 "register_operand" "=f")
8951 (absneg:XF (float_extend:XF
8952 (match_operand:DF 1 "register_operand" "0"))))]
8954 "f<absneg_mnemonic>"
8955 [(set_attr "type" "fsgn")
8956 (set_attr "mode" "XF")])
8958 ;; Copysign instructions
8960 (define_mode_iterator CSGNMODE [SF DF TF])
8961 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8963 (define_expand "copysign<mode>3"
8964 [(match_operand:CSGNMODE 0 "register_operand" "")
8965 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8966 (match_operand:CSGNMODE 2 "register_operand" "")]
8967 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8968 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8969 "ix86_expand_copysign (operands); DONE;")
8971 (define_insn_and_split "copysign<mode>3_const"
8972 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8974 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8975 (match_operand:CSGNMODE 2 "register_operand" "0")
8976 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8978 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8979 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8981 "&& reload_completed"
8983 "ix86_split_copysign_const (operands); DONE;")
8985 (define_insn "copysign<mode>3_var"
8986 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8988 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8989 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8990 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8991 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8993 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8994 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8995 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8999 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9001 [(match_operand:CSGNMODE 2 "register_operand" "")
9002 (match_operand:CSGNMODE 3 "register_operand" "")
9003 (match_operand:<CSGNVMODE> 4 "" "")
9004 (match_operand:<CSGNVMODE> 5 "" "")]
9006 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9007 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9008 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9009 && reload_completed"
9011 "ix86_split_copysign_var (operands); DONE;")
9013 ;; One complement instructions
9015 (define_expand "one_cmpl<mode>2"
9016 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9017 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9019 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9021 (define_insn "*one_cmpl<mode>2_1"
9022 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9023 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9024 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9025 "not{<imodesuffix>}\t%0"
9026 [(set_attr "type" "negnot")
9027 (set_attr "mode" "<MODE>")])
9029 ;; %%% Potential partial reg stall on alternative 1. What to do?
9030 (define_insn "*one_cmplqi2_1"
9031 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9032 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9033 "ix86_unary_operator_ok (NOT, QImode, operands)"
9037 [(set_attr "type" "negnot")
9038 (set_attr "mode" "QI,SI")])
9040 ;; ??? Currently never generated - xor is used instead.
9041 (define_insn "*one_cmplsi2_1_zext"
9042 [(set (match_operand:DI 0 "register_operand" "=r")
9044 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9045 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9047 [(set_attr "type" "negnot")
9048 (set_attr "mode" "SI")])
9050 (define_insn "*one_cmpl<mode>2_2"
9051 [(set (reg FLAGS_REG)
9052 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9054 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9055 (not:SWI (match_dup 1)))]
9056 "ix86_match_ccmode (insn, CCNOmode)
9057 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9059 [(set_attr "type" "alu1")
9060 (set_attr "mode" "<MODE>")])
9063 [(set (match_operand 0 "flags_reg_operand" "")
9064 (match_operator 2 "compare_operator"
9065 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9067 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9068 (not:SWI (match_dup 3)))]
9069 "ix86_match_ccmode (insn, CCNOmode)"
9070 [(parallel [(set (match_dup 0)
9071 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9074 (xor:SWI (match_dup 3) (const_int -1)))])])
9076 ;; ??? Currently never generated - xor is used instead.
9077 (define_insn "*one_cmplsi2_2_zext"
9078 [(set (reg FLAGS_REG)
9079 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9081 (set (match_operand:DI 0 "register_operand" "=r")
9082 (zero_extend:DI (not:SI (match_dup 1))))]
9083 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9084 && ix86_unary_operator_ok (NOT, SImode, operands)"
9086 [(set_attr "type" "alu1")
9087 (set_attr "mode" "SI")])
9090 [(set (match_operand 0 "flags_reg_operand" "")
9091 (match_operator 2 "compare_operator"
9092 [(not:SI (match_operand:SI 3 "register_operand" ""))
9094 (set (match_operand:DI 1 "register_operand" "")
9095 (zero_extend:DI (not:SI (match_dup 3))))]
9096 "ix86_match_ccmode (insn, CCNOmode)"
9097 [(parallel [(set (match_dup 0)
9098 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9101 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9103 ;; Shift instructions
9105 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9106 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9107 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9108 ;; from the assembler input.
9110 ;; This instruction shifts the target reg/mem as usual, but instead of
9111 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9112 ;; is a left shift double, bits are taken from the high order bits of
9113 ;; reg, else if the insn is a shift right double, bits are taken from the
9114 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9115 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9117 ;; Since sh[lr]d does not change the `reg' operand, that is done
9118 ;; separately, making all shifts emit pairs of shift double and normal
9119 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9120 ;; support a 63 bit shift, each shift where the count is in a reg expands
9121 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9123 ;; If the shift count is a constant, we need never emit more than one
9124 ;; shift pair, instead using moves and sign extension for counts greater
9127 (define_expand "ashl<mode>3"
9128 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9129 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9130 (match_operand:QI 2 "nonmemory_operand" "")))]
9132 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9134 (define_insn "*ashl<mode>3_doubleword"
9135 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9136 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9137 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9138 (clobber (reg:CC FLAGS_REG))]
9141 [(set_attr "type" "multi")])
9144 [(set (match_operand:DWI 0 "register_operand" "")
9145 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9146 (match_operand:QI 2 "nonmemory_operand" "")))
9147 (clobber (reg:CC FLAGS_REG))]
9148 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9150 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9152 ;; By default we don't ask for a scratch register, because when DWImode
9153 ;; values are manipulated, registers are already at a premium. But if
9154 ;; we have one handy, we won't turn it away.
9157 [(match_scratch:DWIH 3 "r")
9158 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9160 (match_operand:<DWI> 1 "nonmemory_operand" "")
9161 (match_operand:QI 2 "nonmemory_operand" "")))
9162 (clobber (reg:CC FLAGS_REG))])
9166 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9168 (define_insn "x86_64_shld"
9169 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9170 (ior:DI (ashift:DI (match_dup 0)
9171 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9172 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9173 (minus:QI (const_int 64) (match_dup 2)))))
9174 (clobber (reg:CC FLAGS_REG))]
9176 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9177 [(set_attr "type" "ishift")
9178 (set_attr "prefix_0f" "1")
9179 (set_attr "mode" "DI")
9180 (set_attr "athlon_decode" "vector")
9181 (set_attr "amdfam10_decode" "vector")
9182 (set_attr "bdver1_decode" "vector")])
9184 (define_insn "x86_shld"
9185 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9186 (ior:SI (ashift:SI (match_dup 0)
9187 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9188 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9189 (minus:QI (const_int 32) (match_dup 2)))))
9190 (clobber (reg:CC FLAGS_REG))]
9192 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9193 [(set_attr "type" "ishift")
9194 (set_attr "prefix_0f" "1")
9195 (set_attr "mode" "SI")
9196 (set_attr "pent_pair" "np")
9197 (set_attr "athlon_decode" "vector")
9198 (set_attr "amdfam10_decode" "vector")
9199 (set_attr "bdver1_decode" "vector")])
9201 (define_expand "x86_shift<mode>_adj_1"
9202 [(set (reg:CCZ FLAGS_REG)
9203 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9206 (set (match_operand:SWI48 0 "register_operand" "")
9207 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9208 (match_operand:SWI48 1 "register_operand" "")
9211 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9212 (match_operand:SWI48 3 "register_operand" "r")
9215 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9217 (define_expand "x86_shift<mode>_adj_2"
9218 [(use (match_operand:SWI48 0 "register_operand" ""))
9219 (use (match_operand:SWI48 1 "register_operand" ""))
9220 (use (match_operand:QI 2 "register_operand" ""))]
9223 rtx label = gen_label_rtx ();
9226 emit_insn (gen_testqi_ccz_1 (operands[2],
9227 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9229 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9230 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9231 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9232 gen_rtx_LABEL_REF (VOIDmode, label),
9234 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9235 JUMP_LABEL (tmp) = label;
9237 emit_move_insn (operands[0], operands[1]);
9238 ix86_expand_clear (operands[1]);
9241 LABEL_NUSES (label) = 1;
9246 ;; Avoid useless masking of count operand.
9247 (define_insn_and_split "*ashl<mode>3_mask"
9248 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9250 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9253 (match_operand:SI 2 "nonimmediate_operand" "c")
9254 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9255 (clobber (reg:CC FLAGS_REG))]
9256 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9257 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9258 == GET_MODE_BITSIZE (<MODE>mode)-1"
9261 [(parallel [(set (match_dup 0)
9262 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9263 (clobber (reg:CC FLAGS_REG))])]
9265 if (can_create_pseudo_p ())
9266 operands [2] = force_reg (SImode, operands[2]);
9268 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9270 [(set_attr "type" "ishift")
9271 (set_attr "mode" "<MODE>")])
9273 (define_insn "*ashl<mode>3_1"
9274 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9275 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9276 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9277 (clobber (reg:CC FLAGS_REG))]
9278 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9280 switch (get_attr_type (insn))
9286 gcc_assert (operands[2] == const1_rtx);
9287 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9288 return "add{<imodesuffix>}\t%0, %0";
9291 if (operands[2] == const1_rtx
9292 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9293 return "sal{<imodesuffix>}\t%0";
9295 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9299 (cond [(eq_attr "alternative" "1")
9300 (const_string "lea")
9301 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9303 (match_operand 0 "register_operand" ""))
9304 (match_operand 2 "const1_operand" ""))
9305 (const_string "alu")
9307 (const_string "ishift")))
9308 (set (attr "length_immediate")
9310 (ior (eq_attr "type" "alu")
9311 (and (eq_attr "type" "ishift")
9312 (and (match_operand 2 "const1_operand" "")
9313 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9316 (const_string "*")))
9317 (set_attr "mode" "<MODE>")])
9319 (define_insn "*ashlsi3_1_zext"
9320 [(set (match_operand:DI 0 "register_operand" "=r,r")
9322 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9323 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9324 (clobber (reg:CC FLAGS_REG))]
9325 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9327 switch (get_attr_type (insn))
9333 gcc_assert (operands[2] == const1_rtx);
9334 return "add{l}\t%k0, %k0";
9337 if (operands[2] == const1_rtx
9338 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9339 return "sal{l}\t%k0";
9341 return "sal{l}\t{%2, %k0|%k0, %2}";
9345 (cond [(eq_attr "alternative" "1")
9346 (const_string "lea")
9347 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9349 (match_operand 2 "const1_operand" ""))
9350 (const_string "alu")
9352 (const_string "ishift")))
9353 (set (attr "length_immediate")
9355 (ior (eq_attr "type" "alu")
9356 (and (eq_attr "type" "ishift")
9357 (and (match_operand 2 "const1_operand" "")
9358 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9361 (const_string "*")))
9362 (set_attr "mode" "SI")])
9364 (define_insn "*ashlhi3_1"
9365 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9366 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9367 (match_operand:QI 2 "nonmemory_operand" "cI")))
9368 (clobber (reg:CC FLAGS_REG))]
9369 "TARGET_PARTIAL_REG_STALL
9370 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9372 switch (get_attr_type (insn))
9375 gcc_assert (operands[2] == const1_rtx);
9376 return "add{w}\t%0, %0";
9379 if (operands[2] == const1_rtx
9380 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9381 return "sal{w}\t%0";
9383 return "sal{w}\t{%2, %0|%0, %2}";
9387 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9389 (match_operand 0 "register_operand" ""))
9390 (match_operand 2 "const1_operand" ""))
9391 (const_string "alu")
9393 (const_string "ishift")))
9394 (set (attr "length_immediate")
9396 (ior (eq_attr "type" "alu")
9397 (and (eq_attr "type" "ishift")
9398 (and (match_operand 2 "const1_operand" "")
9399 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9402 (const_string "*")))
9403 (set_attr "mode" "HI")])
9405 (define_insn "*ashlhi3_1_lea"
9406 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9407 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9408 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9409 (clobber (reg:CC FLAGS_REG))]
9410 "!TARGET_PARTIAL_REG_STALL
9411 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9413 switch (get_attr_type (insn))
9419 gcc_assert (operands[2] == const1_rtx);
9420 return "add{w}\t%0, %0";
9423 if (operands[2] == const1_rtx
9424 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9425 return "sal{w}\t%0";
9427 return "sal{w}\t{%2, %0|%0, %2}";
9431 (cond [(eq_attr "alternative" "1")
9432 (const_string "lea")
9433 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9435 (match_operand 0 "register_operand" ""))
9436 (match_operand 2 "const1_operand" ""))
9437 (const_string "alu")
9439 (const_string "ishift")))
9440 (set (attr "length_immediate")
9442 (ior (eq_attr "type" "alu")
9443 (and (eq_attr "type" "ishift")
9444 (and (match_operand 2 "const1_operand" "")
9445 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9448 (const_string "*")))
9449 (set_attr "mode" "HI,SI")])
9451 (define_insn "*ashlqi3_1"
9452 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9453 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9454 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9455 (clobber (reg:CC FLAGS_REG))]
9456 "TARGET_PARTIAL_REG_STALL
9457 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9459 switch (get_attr_type (insn))
9462 gcc_assert (operands[2] == const1_rtx);
9463 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9464 return "add{l}\t%k0, %k0";
9466 return "add{b}\t%0, %0";
9469 if (operands[2] == const1_rtx
9470 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9472 if (get_attr_mode (insn) == MODE_SI)
9473 return "sal{l}\t%k0";
9475 return "sal{b}\t%0";
9479 if (get_attr_mode (insn) == MODE_SI)
9480 return "sal{l}\t{%2, %k0|%k0, %2}";
9482 return "sal{b}\t{%2, %0|%0, %2}";
9487 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9489 (match_operand 0 "register_operand" ""))
9490 (match_operand 2 "const1_operand" ""))
9491 (const_string "alu")
9493 (const_string "ishift")))
9494 (set (attr "length_immediate")
9496 (ior (eq_attr "type" "alu")
9497 (and (eq_attr "type" "ishift")
9498 (and (match_operand 2 "const1_operand" "")
9499 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9502 (const_string "*")))
9503 (set_attr "mode" "QI,SI")])
9505 ;; %%% Potential partial reg stall on alternative 2. What to do?
9506 (define_insn "*ashlqi3_1_lea"
9507 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9508 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9509 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9510 (clobber (reg:CC FLAGS_REG))]
9511 "!TARGET_PARTIAL_REG_STALL
9512 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9514 switch (get_attr_type (insn))
9520 gcc_assert (operands[2] == const1_rtx);
9521 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9522 return "add{l}\t%k0, %k0";
9524 return "add{b}\t%0, %0";
9527 if (operands[2] == const1_rtx
9528 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9530 if (get_attr_mode (insn) == MODE_SI)
9531 return "sal{l}\t%k0";
9533 return "sal{b}\t%0";
9537 if (get_attr_mode (insn) == MODE_SI)
9538 return "sal{l}\t{%2, %k0|%k0, %2}";
9540 return "sal{b}\t{%2, %0|%0, %2}";
9545 (cond [(eq_attr "alternative" "2")
9546 (const_string "lea")
9547 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9549 (match_operand 0 "register_operand" ""))
9550 (match_operand 2 "const1_operand" ""))
9551 (const_string "alu")
9553 (const_string "ishift")))
9554 (set (attr "length_immediate")
9556 (ior (eq_attr "type" "alu")
9557 (and (eq_attr "type" "ishift")
9558 (and (match_operand 2 "const1_operand" "")
9559 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9562 (const_string "*")))
9563 (set_attr "mode" "QI,SI,SI")])
9565 (define_insn "*ashlqi3_1_slp"
9566 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9567 (ashift:QI (match_dup 0)
9568 (match_operand:QI 1 "nonmemory_operand" "cI")))
9569 (clobber (reg:CC FLAGS_REG))]
9570 "(optimize_function_for_size_p (cfun)
9571 || !TARGET_PARTIAL_FLAG_REG_STALL
9572 || (operands[1] == const1_rtx
9574 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9576 switch (get_attr_type (insn))
9579 gcc_assert (operands[1] == const1_rtx);
9580 return "add{b}\t%0, %0";
9583 if (operands[1] == const1_rtx
9584 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9585 return "sal{b}\t%0";
9587 return "sal{b}\t{%1, %0|%0, %1}";
9591 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9593 (match_operand 0 "register_operand" ""))
9594 (match_operand 1 "const1_operand" ""))
9595 (const_string "alu")
9597 (const_string "ishift1")))
9598 (set (attr "length_immediate")
9600 (ior (eq_attr "type" "alu")
9601 (and (eq_attr "type" "ishift1")
9602 (and (match_operand 1 "const1_operand" "")
9603 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9606 (const_string "*")))
9607 (set_attr "mode" "QI")])
9609 ;; Convert lea to the lea pattern to avoid flags dependency.
9611 [(set (match_operand 0 "register_operand" "")
9612 (ashift (match_operand 1 "index_register_operand" "")
9613 (match_operand:QI 2 "const_int_operand" "")))
9614 (clobber (reg:CC FLAGS_REG))]
9616 && true_regnum (operands[0]) != true_regnum (operands[1])"
9620 enum machine_mode mode = GET_MODE (operands[0]);
9623 operands[1] = gen_lowpart (Pmode, operands[1]);
9624 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9626 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9628 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9629 operands[0] = gen_lowpart (SImode, operands[0]);
9631 if (TARGET_64BIT && mode != Pmode)
9632 pat = gen_rtx_SUBREG (SImode, pat, 0);
9634 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9638 ;; Convert lea to the lea pattern to avoid flags dependency.
9640 [(set (match_operand:DI 0 "register_operand" "")
9642 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9643 (match_operand:QI 2 "const_int_operand" ""))))
9644 (clobber (reg:CC FLAGS_REG))]
9645 "TARGET_64BIT && reload_completed
9646 && true_regnum (operands[0]) != true_regnum (operands[1])"
9648 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9650 operands[1] = gen_lowpart (DImode, operands[1]);
9651 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9654 ;; This pattern can't accept a variable shift count, since shifts by
9655 ;; zero don't affect the flags. We assume that shifts by constant
9656 ;; zero are optimized away.
9657 (define_insn "*ashl<mode>3_cmp"
9658 [(set (reg FLAGS_REG)
9660 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9661 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9663 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9664 (ashift:SWI (match_dup 1) (match_dup 2)))]
9665 "(optimize_function_for_size_p (cfun)
9666 || !TARGET_PARTIAL_FLAG_REG_STALL
9667 || (operands[2] == const1_rtx
9669 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9670 && ix86_match_ccmode (insn, CCGOCmode)
9671 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9673 switch (get_attr_type (insn))
9676 gcc_assert (operands[2] == const1_rtx);
9677 return "add{<imodesuffix>}\t%0, %0";
9680 if (operands[2] == const1_rtx
9681 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9682 return "sal{<imodesuffix>}\t%0";
9684 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9688 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9690 (match_operand 0 "register_operand" ""))
9691 (match_operand 2 "const1_operand" ""))
9692 (const_string "alu")
9694 (const_string "ishift")))
9695 (set (attr "length_immediate")
9697 (ior (eq_attr "type" "alu")
9698 (and (eq_attr "type" "ishift")
9699 (and (match_operand 2 "const1_operand" "")
9700 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9703 (const_string "*")))
9704 (set_attr "mode" "<MODE>")])
9706 (define_insn "*ashlsi3_cmp_zext"
9707 [(set (reg FLAGS_REG)
9709 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9710 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9712 (set (match_operand:DI 0 "register_operand" "=r")
9713 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9715 && (optimize_function_for_size_p (cfun)
9716 || !TARGET_PARTIAL_FLAG_REG_STALL
9717 || (operands[2] == const1_rtx
9719 || TARGET_DOUBLE_WITH_ADD)))
9720 && ix86_match_ccmode (insn, CCGOCmode)
9721 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9723 switch (get_attr_type (insn))
9726 gcc_assert (operands[2] == const1_rtx);
9727 return "add{l}\t%k0, %k0";
9730 if (operands[2] == const1_rtx
9731 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9732 return "sal{l}\t%k0";
9734 return "sal{l}\t{%2, %k0|%k0, %2}";
9738 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9740 (match_operand 2 "const1_operand" ""))
9741 (const_string "alu")
9743 (const_string "ishift")))
9744 (set (attr "length_immediate")
9746 (ior (eq_attr "type" "alu")
9747 (and (eq_attr "type" "ishift")
9748 (and (match_operand 2 "const1_operand" "")
9749 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9752 (const_string "*")))
9753 (set_attr "mode" "SI")])
9755 (define_insn "*ashl<mode>3_cconly"
9756 [(set (reg FLAGS_REG)
9758 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9759 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9761 (clobber (match_scratch:SWI 0 "=<r>"))]
9762 "(optimize_function_for_size_p (cfun)
9763 || !TARGET_PARTIAL_FLAG_REG_STALL
9764 || (operands[2] == const1_rtx
9766 || TARGET_DOUBLE_WITH_ADD)))
9767 && ix86_match_ccmode (insn, CCGOCmode)"
9769 switch (get_attr_type (insn))
9772 gcc_assert (operands[2] == const1_rtx);
9773 return "add{<imodesuffix>}\t%0, %0";
9776 if (operands[2] == const1_rtx
9777 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9778 return "sal{<imodesuffix>}\t%0";
9780 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9784 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9786 (match_operand 0 "register_operand" ""))
9787 (match_operand 2 "const1_operand" ""))
9788 (const_string "alu")
9790 (const_string "ishift")))
9791 (set (attr "length_immediate")
9793 (ior (eq_attr "type" "alu")
9794 (and (eq_attr "type" "ishift")
9795 (and (match_operand 2 "const1_operand" "")
9796 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9799 (const_string "*")))
9800 (set_attr "mode" "<MODE>")])
9802 ;; See comment above `ashl<mode>3' about how this works.
9804 (define_expand "<shiftrt_insn><mode>3"
9805 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9806 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9807 (match_operand:QI 2 "nonmemory_operand" "")))]
9809 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9811 ;; Avoid useless masking of count operand.
9812 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9813 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9815 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9818 (match_operand:SI 2 "nonimmediate_operand" "c")
9819 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9820 (clobber (reg:CC FLAGS_REG))]
9821 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9822 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9823 == GET_MODE_BITSIZE (<MODE>mode)-1"
9826 [(parallel [(set (match_dup 0)
9827 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9828 (clobber (reg:CC FLAGS_REG))])]
9830 if (can_create_pseudo_p ())
9831 operands [2] = force_reg (SImode, operands[2]);
9833 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9835 [(set_attr "type" "ishift")
9836 (set_attr "mode" "<MODE>")])
9838 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9839 [(set (match_operand:DWI 0 "register_operand" "=r")
9840 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9841 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9842 (clobber (reg:CC FLAGS_REG))]
9845 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9847 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9848 [(set_attr "type" "multi")])
9850 ;; By default we don't ask for a scratch register, because when DWImode
9851 ;; values are manipulated, registers are already at a premium. But if
9852 ;; we have one handy, we won't turn it away.
9855 [(match_scratch:DWIH 3 "r")
9856 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9858 (match_operand:<DWI> 1 "register_operand" "")
9859 (match_operand:QI 2 "nonmemory_operand" "")))
9860 (clobber (reg:CC FLAGS_REG))])
9864 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9866 (define_insn "x86_64_shrd"
9867 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9868 (ior:DI (ashiftrt:DI (match_dup 0)
9869 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9870 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9871 (minus:QI (const_int 64) (match_dup 2)))))
9872 (clobber (reg:CC FLAGS_REG))]
9874 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9875 [(set_attr "type" "ishift")
9876 (set_attr "prefix_0f" "1")
9877 (set_attr "mode" "DI")
9878 (set_attr "athlon_decode" "vector")
9879 (set_attr "amdfam10_decode" "vector")
9880 (set_attr "bdver1_decode" "vector")])
9882 (define_insn "x86_shrd"
9883 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9884 (ior:SI (ashiftrt:SI (match_dup 0)
9885 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9886 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9887 (minus:QI (const_int 32) (match_dup 2)))))
9888 (clobber (reg:CC FLAGS_REG))]
9890 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9891 [(set_attr "type" "ishift")
9892 (set_attr "prefix_0f" "1")
9893 (set_attr "mode" "SI")
9894 (set_attr "pent_pair" "np")
9895 (set_attr "athlon_decode" "vector")
9896 (set_attr "amdfam10_decode" "vector")
9897 (set_attr "bdver1_decode" "vector")])
9899 (define_insn "ashrdi3_cvt"
9900 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9901 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9902 (match_operand:QI 2 "const_int_operand" "")))
9903 (clobber (reg:CC FLAGS_REG))]
9904 "TARGET_64BIT && INTVAL (operands[2]) == 63
9905 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9906 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9909 sar{q}\t{%2, %0|%0, %2}"
9910 [(set_attr "type" "imovx,ishift")
9911 (set_attr "prefix_0f" "0,*")
9912 (set_attr "length_immediate" "0,*")
9913 (set_attr "modrm" "0,1")
9914 (set_attr "mode" "DI")])
9916 (define_insn "ashrsi3_cvt"
9917 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9918 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9919 (match_operand:QI 2 "const_int_operand" "")))
9920 (clobber (reg:CC FLAGS_REG))]
9921 "INTVAL (operands[2]) == 31
9922 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9923 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9926 sar{l}\t{%2, %0|%0, %2}"
9927 [(set_attr "type" "imovx,ishift")
9928 (set_attr "prefix_0f" "0,*")
9929 (set_attr "length_immediate" "0,*")
9930 (set_attr "modrm" "0,1")
9931 (set_attr "mode" "SI")])
9933 (define_insn "*ashrsi3_cvt_zext"
9934 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9936 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9937 (match_operand:QI 2 "const_int_operand" ""))))
9938 (clobber (reg:CC FLAGS_REG))]
9939 "TARGET_64BIT && INTVAL (operands[2]) == 31
9940 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9941 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9944 sar{l}\t{%2, %k0|%k0, %2}"
9945 [(set_attr "type" "imovx,ishift")
9946 (set_attr "prefix_0f" "0,*")
9947 (set_attr "length_immediate" "0,*")
9948 (set_attr "modrm" "0,1")
9949 (set_attr "mode" "SI")])
9951 (define_expand "x86_shift<mode>_adj_3"
9952 [(use (match_operand:SWI48 0 "register_operand" ""))
9953 (use (match_operand:SWI48 1 "register_operand" ""))
9954 (use (match_operand:QI 2 "register_operand" ""))]
9957 rtx label = gen_label_rtx ();
9960 emit_insn (gen_testqi_ccz_1 (operands[2],
9961 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9963 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9964 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9965 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9966 gen_rtx_LABEL_REF (VOIDmode, label),
9968 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9969 JUMP_LABEL (tmp) = label;
9971 emit_move_insn (operands[0], operands[1]);
9972 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9973 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9975 LABEL_NUSES (label) = 1;
9980 (define_insn "*<shiftrt_insn><mode>3_1"
9981 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9982 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9983 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9984 (clobber (reg:CC FLAGS_REG))]
9985 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9987 if (operands[2] == const1_rtx
9988 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9989 return "<shiftrt>{<imodesuffix>}\t%0";
9991 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9993 [(set_attr "type" "ishift")
9994 (set (attr "length_immediate")
9996 (and (match_operand 2 "const1_operand" "")
9997 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10000 (const_string "*")))
10001 (set_attr "mode" "<MODE>")])
10003 (define_insn "*<shiftrt_insn>si3_1_zext"
10004 [(set (match_operand:DI 0 "register_operand" "=r")
10006 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10007 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10008 (clobber (reg:CC FLAGS_REG))]
10009 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10011 if (operands[2] == const1_rtx
10012 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10013 return "<shiftrt>{l}\t%k0";
10015 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10017 [(set_attr "type" "ishift")
10018 (set (attr "length_immediate")
10020 (and (match_operand 2 "const1_operand" "")
10021 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10024 (const_string "*")))
10025 (set_attr "mode" "SI")])
10027 (define_insn "*<shiftrt_insn>qi3_1_slp"
10028 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10029 (any_shiftrt:QI (match_dup 0)
10030 (match_operand:QI 1 "nonmemory_operand" "cI")))
10031 (clobber (reg:CC FLAGS_REG))]
10032 "(optimize_function_for_size_p (cfun)
10033 || !TARGET_PARTIAL_REG_STALL
10034 || (operands[1] == const1_rtx
10035 && TARGET_SHIFT1))"
10037 if (operands[1] == const1_rtx
10038 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10039 return "<shiftrt>{b}\t%0";
10041 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10043 [(set_attr "type" "ishift1")
10044 (set (attr "length_immediate")
10046 (and (match_operand 1 "const1_operand" "")
10047 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10050 (const_string "*")))
10051 (set_attr "mode" "QI")])
10053 ;; This pattern can't accept a variable shift count, since shifts by
10054 ;; zero don't affect the flags. We assume that shifts by constant
10055 ;; zero are optimized away.
10056 (define_insn "*<shiftrt_insn><mode>3_cmp"
10057 [(set (reg FLAGS_REG)
10060 (match_operand:SWI 1 "nonimmediate_operand" "0")
10061 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10063 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10064 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10065 "(optimize_function_for_size_p (cfun)
10066 || !TARGET_PARTIAL_FLAG_REG_STALL
10067 || (operands[2] == const1_rtx
10069 && ix86_match_ccmode (insn, CCGOCmode)
10070 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10072 if (operands[2] == const1_rtx
10073 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10074 return "<shiftrt>{<imodesuffix>}\t%0";
10076 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10078 [(set_attr "type" "ishift")
10079 (set (attr "length_immediate")
10081 (and (match_operand 2 "const1_operand" "")
10082 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10085 (const_string "*")))
10086 (set_attr "mode" "<MODE>")])
10088 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10089 [(set (reg FLAGS_REG)
10091 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10092 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10094 (set (match_operand:DI 0 "register_operand" "=r")
10095 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10097 && (optimize_function_for_size_p (cfun)
10098 || !TARGET_PARTIAL_FLAG_REG_STALL
10099 || (operands[2] == const1_rtx
10101 && ix86_match_ccmode (insn, CCGOCmode)
10102 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10104 if (operands[2] == const1_rtx
10105 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10106 return "<shiftrt>{l}\t%k0";
10108 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10110 [(set_attr "type" "ishift")
10111 (set (attr "length_immediate")
10113 (and (match_operand 2 "const1_operand" "")
10114 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10117 (const_string "*")))
10118 (set_attr "mode" "SI")])
10120 (define_insn "*<shiftrt_insn><mode>3_cconly"
10121 [(set (reg FLAGS_REG)
10124 (match_operand:SWI 1 "register_operand" "0")
10125 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10127 (clobber (match_scratch:SWI 0 "=<r>"))]
10128 "(optimize_function_for_size_p (cfun)
10129 || !TARGET_PARTIAL_FLAG_REG_STALL
10130 || (operands[2] == const1_rtx
10132 && ix86_match_ccmode (insn, CCGOCmode)"
10134 if (operands[2] == const1_rtx
10135 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10136 return "<shiftrt>{<imodesuffix>}\t%0";
10138 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10140 [(set_attr "type" "ishift")
10141 (set (attr "length_immediate")
10143 (and (match_operand 2 "const1_operand" "")
10144 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10147 (const_string "*")))
10148 (set_attr "mode" "<MODE>")])
10150 ;; Rotate instructions
10152 (define_expand "<rotate_insn>ti3"
10153 [(set (match_operand:TI 0 "register_operand" "")
10154 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10155 (match_operand:QI 2 "nonmemory_operand" "")))]
10158 if (const_1_to_63_operand (operands[2], VOIDmode))
10159 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10160 (operands[0], operands[1], operands[2]));
10167 (define_expand "<rotate_insn>di3"
10168 [(set (match_operand:DI 0 "shiftdi_operand" "")
10169 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10170 (match_operand:QI 2 "nonmemory_operand" "")))]
10174 ix86_expand_binary_operator (<CODE>, DImode, operands);
10175 else if (const_1_to_31_operand (operands[2], VOIDmode))
10176 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10177 (operands[0], operands[1], operands[2]));
10184 (define_expand "<rotate_insn><mode>3"
10185 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10186 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10187 (match_operand:QI 2 "nonmemory_operand" "")))]
10189 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10191 ;; Avoid useless masking of count operand.
10192 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10193 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10195 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10198 (match_operand:SI 2 "nonimmediate_operand" "c")
10199 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10200 (clobber (reg:CC FLAGS_REG))]
10201 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10202 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10203 == GET_MODE_BITSIZE (<MODE>mode)-1"
10206 [(parallel [(set (match_dup 0)
10207 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10208 (clobber (reg:CC FLAGS_REG))])]
10210 if (can_create_pseudo_p ())
10211 operands [2] = force_reg (SImode, operands[2]);
10213 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10215 [(set_attr "type" "rotate")
10216 (set_attr "mode" "<MODE>")])
10218 ;; Implement rotation using two double-precision
10219 ;; shift instructions and a scratch register.
10221 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10222 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10223 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10224 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10225 (clobber (reg:CC FLAGS_REG))
10226 (clobber (match_scratch:DWIH 3 "=&r"))]
10230 [(set (match_dup 3) (match_dup 4))
10232 [(set (match_dup 4)
10233 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10234 (lshiftrt:DWIH (match_dup 5)
10235 (minus:QI (match_dup 6) (match_dup 2)))))
10236 (clobber (reg:CC FLAGS_REG))])
10238 [(set (match_dup 5)
10239 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10240 (lshiftrt:DWIH (match_dup 3)
10241 (minus:QI (match_dup 6) (match_dup 2)))))
10242 (clobber (reg:CC FLAGS_REG))])]
10244 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10246 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10249 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10250 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10251 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10252 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10253 (clobber (reg:CC FLAGS_REG))
10254 (clobber (match_scratch:DWIH 3 "=&r"))]
10258 [(set (match_dup 3) (match_dup 4))
10260 [(set (match_dup 4)
10261 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10262 (ashift:DWIH (match_dup 5)
10263 (minus:QI (match_dup 6) (match_dup 2)))))
10264 (clobber (reg:CC FLAGS_REG))])
10266 [(set (match_dup 5)
10267 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10268 (ashift:DWIH (match_dup 3)
10269 (minus:QI (match_dup 6) (match_dup 2)))))
10270 (clobber (reg:CC FLAGS_REG))])]
10272 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10274 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10277 (define_insn "*<rotate_insn><mode>3_1"
10278 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10279 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10280 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10281 (clobber (reg:CC FLAGS_REG))]
10282 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10284 if (operands[2] == const1_rtx
10285 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10286 return "<rotate>{<imodesuffix>}\t%0";
10288 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10290 [(set_attr "type" "rotate")
10291 (set (attr "length_immediate")
10293 (and (match_operand 2 "const1_operand" "")
10294 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10297 (const_string "*")))
10298 (set_attr "mode" "<MODE>")])
10300 (define_insn "*<rotate_insn>si3_1_zext"
10301 [(set (match_operand:DI 0 "register_operand" "=r")
10303 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10304 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10305 (clobber (reg:CC FLAGS_REG))]
10306 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10308 if (operands[2] == const1_rtx
10309 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10310 return "<rotate>{l}\t%k0";
10312 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10314 [(set_attr "type" "rotate")
10315 (set (attr "length_immediate")
10317 (and (match_operand 2 "const1_operand" "")
10318 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10321 (const_string "*")))
10322 (set_attr "mode" "SI")])
10324 (define_insn "*<rotate_insn>qi3_1_slp"
10325 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10326 (any_rotate:QI (match_dup 0)
10327 (match_operand:QI 1 "nonmemory_operand" "cI")))
10328 (clobber (reg:CC FLAGS_REG))]
10329 "(optimize_function_for_size_p (cfun)
10330 || !TARGET_PARTIAL_REG_STALL
10331 || (operands[1] == const1_rtx
10332 && TARGET_SHIFT1))"
10334 if (operands[1] == const1_rtx
10335 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10336 return "<rotate>{b}\t%0";
10338 return "<rotate>{b}\t{%1, %0|%0, %1}";
10340 [(set_attr "type" "rotate1")
10341 (set (attr "length_immediate")
10343 (and (match_operand 1 "const1_operand" "")
10344 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10347 (const_string "*")))
10348 (set_attr "mode" "QI")])
10351 [(set (match_operand:HI 0 "register_operand" "")
10352 (any_rotate:HI (match_dup 0) (const_int 8)))
10353 (clobber (reg:CC FLAGS_REG))]
10355 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10356 [(parallel [(set (strict_low_part (match_dup 0))
10357 (bswap:HI (match_dup 0)))
10358 (clobber (reg:CC FLAGS_REG))])])
10360 ;; Bit set / bit test instructions
10362 (define_expand "extv"
10363 [(set (match_operand:SI 0 "register_operand" "")
10364 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10365 (match_operand:SI 2 "const8_operand" "")
10366 (match_operand:SI 3 "const8_operand" "")))]
10369 /* Handle extractions from %ah et al. */
10370 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10373 /* From mips.md: extract_bit_field doesn't verify that our source
10374 matches the predicate, so check it again here. */
10375 if (! ext_register_operand (operands[1], VOIDmode))
10379 (define_expand "extzv"
10380 [(set (match_operand:SI 0 "register_operand" "")
10381 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10382 (match_operand:SI 2 "const8_operand" "")
10383 (match_operand:SI 3 "const8_operand" "")))]
10386 /* Handle extractions from %ah et al. */
10387 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10390 /* From mips.md: extract_bit_field doesn't verify that our source
10391 matches the predicate, so check it again here. */
10392 if (! ext_register_operand (operands[1], VOIDmode))
10396 (define_expand "insv"
10397 [(set (zero_extract (match_operand 0 "register_operand" "")
10398 (match_operand 1 "const_int_operand" "")
10399 (match_operand 2 "const_int_operand" ""))
10400 (match_operand 3 "register_operand" ""))]
10403 rtx (*gen_mov_insv_1) (rtx, rtx);
10405 if (ix86_expand_pinsr (operands))
10408 /* Handle insertions to %ah et al. */
10409 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10412 /* From mips.md: insert_bit_field doesn't verify that our source
10413 matches the predicate, so check it again here. */
10414 if (! ext_register_operand (operands[0], VOIDmode))
10417 gen_mov_insv_1 = (TARGET_64BIT
10418 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10420 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10424 ;; %%% bts, btr, btc, bt.
10425 ;; In general these instructions are *slow* when applied to memory,
10426 ;; since they enforce atomic operation. When applied to registers,
10427 ;; it depends on the cpu implementation. They're never faster than
10428 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10429 ;; no point. But in 64-bit, we can't hold the relevant immediates
10430 ;; within the instruction itself, so operating on bits in the high
10431 ;; 32-bits of a register becomes easier.
10433 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10434 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10435 ;; negdf respectively, so they can never be disabled entirely.
10437 (define_insn "*btsq"
10438 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10440 (match_operand:DI 1 "const_0_to_63_operand" ""))
10442 (clobber (reg:CC FLAGS_REG))]
10443 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10444 "bts{q}\t{%1, %0|%0, %1}"
10445 [(set_attr "type" "alu1")
10446 (set_attr "prefix_0f" "1")
10447 (set_attr "mode" "DI")])
10449 (define_insn "*btrq"
10450 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10452 (match_operand:DI 1 "const_0_to_63_operand" ""))
10454 (clobber (reg:CC FLAGS_REG))]
10455 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10456 "btr{q}\t{%1, %0|%0, %1}"
10457 [(set_attr "type" "alu1")
10458 (set_attr "prefix_0f" "1")
10459 (set_attr "mode" "DI")])
10461 (define_insn "*btcq"
10462 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10464 (match_operand:DI 1 "const_0_to_63_operand" ""))
10465 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10466 (clobber (reg:CC FLAGS_REG))]
10467 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10468 "btc{q}\t{%1, %0|%0, %1}"
10469 [(set_attr "type" "alu1")
10470 (set_attr "prefix_0f" "1")
10471 (set_attr "mode" "DI")])
10473 ;; Allow Nocona to avoid these instructions if a register is available.
10476 [(match_scratch:DI 2 "r")
10477 (parallel [(set (zero_extract:DI
10478 (match_operand:DI 0 "register_operand" "")
10480 (match_operand:DI 1 "const_0_to_63_operand" ""))
10482 (clobber (reg:CC FLAGS_REG))])]
10483 "TARGET_64BIT && !TARGET_USE_BT"
10486 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10489 if (HOST_BITS_PER_WIDE_INT >= 64)
10490 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10491 else if (i < HOST_BITS_PER_WIDE_INT)
10492 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10494 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10496 op1 = immed_double_const (lo, hi, DImode);
10499 emit_move_insn (operands[2], op1);
10503 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10508 [(match_scratch:DI 2 "r")
10509 (parallel [(set (zero_extract:DI
10510 (match_operand:DI 0 "register_operand" "")
10512 (match_operand:DI 1 "const_0_to_63_operand" ""))
10514 (clobber (reg:CC FLAGS_REG))])]
10515 "TARGET_64BIT && !TARGET_USE_BT"
10518 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10521 if (HOST_BITS_PER_WIDE_INT >= 64)
10522 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10523 else if (i < HOST_BITS_PER_WIDE_INT)
10524 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10526 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10528 op1 = immed_double_const (~lo, ~hi, DImode);
10531 emit_move_insn (operands[2], op1);
10535 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10540 [(match_scratch:DI 2 "r")
10541 (parallel [(set (zero_extract:DI
10542 (match_operand:DI 0 "register_operand" "")
10544 (match_operand:DI 1 "const_0_to_63_operand" ""))
10545 (not:DI (zero_extract:DI
10546 (match_dup 0) (const_int 1) (match_dup 1))))
10547 (clobber (reg:CC FLAGS_REG))])]
10548 "TARGET_64BIT && !TARGET_USE_BT"
10551 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10554 if (HOST_BITS_PER_WIDE_INT >= 64)
10555 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10556 else if (i < HOST_BITS_PER_WIDE_INT)
10557 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10559 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10561 op1 = immed_double_const (lo, hi, DImode);
10564 emit_move_insn (operands[2], op1);
10568 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10572 (define_insn "*bt<mode>"
10573 [(set (reg:CCC FLAGS_REG)
10575 (zero_extract:SWI48
10576 (match_operand:SWI48 0 "register_operand" "r")
10578 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10580 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10581 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10582 [(set_attr "type" "alu1")
10583 (set_attr "prefix_0f" "1")
10584 (set_attr "mode" "<MODE>")])
10586 ;; Store-flag instructions.
10588 ;; For all sCOND expanders, also expand the compare or test insn that
10589 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10591 (define_insn_and_split "*setcc_di_1"
10592 [(set (match_operand:DI 0 "register_operand" "=q")
10593 (match_operator:DI 1 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)]))]
10595 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10597 "&& reload_completed"
10598 [(set (match_dup 2) (match_dup 1))
10599 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10601 PUT_MODE (operands[1], QImode);
10602 operands[2] = gen_lowpart (QImode, operands[0]);
10605 (define_insn_and_split "*setcc_si_1_and"
10606 [(set (match_operand:SI 0 "register_operand" "=q")
10607 (match_operator:SI 1 "ix86_comparison_operator"
10608 [(reg FLAGS_REG) (const_int 0)]))
10609 (clobber (reg:CC FLAGS_REG))]
10610 "!TARGET_PARTIAL_REG_STALL
10611 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10613 "&& reload_completed"
10614 [(set (match_dup 2) (match_dup 1))
10615 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10616 (clobber (reg:CC FLAGS_REG))])]
10618 PUT_MODE (operands[1], QImode);
10619 operands[2] = gen_lowpart (QImode, operands[0]);
10622 (define_insn_and_split "*setcc_si_1_movzbl"
10623 [(set (match_operand:SI 0 "register_operand" "=q")
10624 (match_operator:SI 1 "ix86_comparison_operator"
10625 [(reg FLAGS_REG) (const_int 0)]))]
10626 "!TARGET_PARTIAL_REG_STALL
10627 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10629 "&& reload_completed"
10630 [(set (match_dup 2) (match_dup 1))
10631 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10633 PUT_MODE (operands[1], QImode);
10634 operands[2] = gen_lowpart (QImode, operands[0]);
10637 (define_insn "*setcc_qi"
10638 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10639 (match_operator:QI 1 "ix86_comparison_operator"
10640 [(reg FLAGS_REG) (const_int 0)]))]
10643 [(set_attr "type" "setcc")
10644 (set_attr "mode" "QI")])
10646 (define_insn "*setcc_qi_slp"
10647 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10648 (match_operator:QI 1 "ix86_comparison_operator"
10649 [(reg FLAGS_REG) (const_int 0)]))]
10652 [(set_attr "type" "setcc")
10653 (set_attr "mode" "QI")])
10655 ;; In general it is not safe to assume too much about CCmode registers,
10656 ;; so simplify-rtx stops when it sees a second one. Under certain
10657 ;; conditions this is safe on x86, so help combine not create
10664 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10665 (ne:QI (match_operator 1 "ix86_comparison_operator"
10666 [(reg FLAGS_REG) (const_int 0)])
10669 [(set (match_dup 0) (match_dup 1))]
10670 "PUT_MODE (operands[1], QImode);")
10673 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10674 (ne:QI (match_operator 1 "ix86_comparison_operator"
10675 [(reg FLAGS_REG) (const_int 0)])
10678 [(set (match_dup 0) (match_dup 1))]
10679 "PUT_MODE (operands[1], QImode);")
10682 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10683 (eq:QI (match_operator 1 "ix86_comparison_operator"
10684 [(reg FLAGS_REG) (const_int 0)])
10687 [(set (match_dup 0) (match_dup 1))]
10689 rtx new_op1 = copy_rtx (operands[1]);
10690 operands[1] = new_op1;
10691 PUT_MODE (new_op1, QImode);
10692 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10693 GET_MODE (XEXP (new_op1, 0))));
10695 /* Make sure that (a) the CCmode we have for the flags is strong
10696 enough for the reversed compare or (b) we have a valid FP compare. */
10697 if (! ix86_comparison_operator (new_op1, VOIDmode))
10702 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10703 (eq:QI (match_operator 1 "ix86_comparison_operator"
10704 [(reg FLAGS_REG) (const_int 0)])
10707 [(set (match_dup 0) (match_dup 1))]
10709 rtx new_op1 = copy_rtx (operands[1]);
10710 operands[1] = new_op1;
10711 PUT_MODE (new_op1, QImode);
10712 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10713 GET_MODE (XEXP (new_op1, 0))));
10715 /* Make sure that (a) the CCmode we have for the flags is strong
10716 enough for the reversed compare or (b) we have a valid FP compare. */
10717 if (! ix86_comparison_operator (new_op1, VOIDmode))
10721 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10722 ;; subsequent logical operations are used to imitate conditional moves.
10723 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10726 (define_insn "setcc_<mode>_sse"
10727 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10728 (match_operator:MODEF 3 "sse_comparison_operator"
10729 [(match_operand:MODEF 1 "register_operand" "0,x")
10730 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10731 "SSE_FLOAT_MODE_P (<MODE>mode)"
10733 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10734 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10735 [(set_attr "isa" "noavx,avx")
10736 (set_attr "type" "ssecmp")
10737 (set_attr "length_immediate" "1")
10738 (set_attr "prefix" "orig,vex")
10739 (set_attr "mode" "<MODE>")])
10741 ;; Basic conditional jump instructions.
10742 ;; We ignore the overflow flag for signed branch instructions.
10744 (define_insn "*jcc_1"
10746 (if_then_else (match_operator 1 "ix86_comparison_operator"
10747 [(reg FLAGS_REG) (const_int 0)])
10748 (label_ref (match_operand 0 "" ""))
10752 [(set_attr "type" "ibr")
10753 (set_attr "modrm" "0")
10754 (set (attr "length")
10755 (if_then_else (and (ge (minus (match_dup 0) (pc))
10757 (lt (minus (match_dup 0) (pc))
10762 (define_insn "*jcc_2"
10764 (if_then_else (match_operator 1 "ix86_comparison_operator"
10765 [(reg FLAGS_REG) (const_int 0)])
10767 (label_ref (match_operand 0 "" ""))))]
10770 [(set_attr "type" "ibr")
10771 (set_attr "modrm" "0")
10772 (set (attr "length")
10773 (if_then_else (and (ge (minus (match_dup 0) (pc))
10775 (lt (minus (match_dup 0) (pc))
10780 ;; In general it is not safe to assume too much about CCmode registers,
10781 ;; so simplify-rtx stops when it sees a second one. Under certain
10782 ;; conditions this is safe on x86, so help combine not create
10790 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10791 [(reg FLAGS_REG) (const_int 0)])
10793 (label_ref (match_operand 1 "" ""))
10797 (if_then_else (match_dup 0)
10798 (label_ref (match_dup 1))
10800 "PUT_MODE (operands[0], VOIDmode);")
10804 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10805 [(reg FLAGS_REG) (const_int 0)])
10807 (label_ref (match_operand 1 "" ""))
10811 (if_then_else (match_dup 0)
10812 (label_ref (match_dup 1))
10815 rtx new_op0 = copy_rtx (operands[0]);
10816 operands[0] = new_op0;
10817 PUT_MODE (new_op0, VOIDmode);
10818 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10819 GET_MODE (XEXP (new_op0, 0))));
10821 /* Make sure that (a) the CCmode we have for the flags is strong
10822 enough for the reversed compare or (b) we have a valid FP compare. */
10823 if (! ix86_comparison_operator (new_op0, VOIDmode))
10827 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10828 ;; pass generates from shift insn with QImode operand. Actually, the mode
10829 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10830 ;; appropriate modulo of the bit offset value.
10832 (define_insn_and_split "*jcc_bt<mode>"
10834 (if_then_else (match_operator 0 "bt_comparison_operator"
10835 [(zero_extract:SWI48
10836 (match_operand:SWI48 1 "register_operand" "r")
10839 (match_operand:QI 2 "register_operand" "r")))
10841 (label_ref (match_operand 3 "" ""))
10843 (clobber (reg:CC FLAGS_REG))]
10844 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10847 [(set (reg:CCC FLAGS_REG)
10849 (zero_extract:SWI48
10855 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10856 (label_ref (match_dup 3))
10859 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10861 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10864 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10865 ;; also for DImode, this is what combine produces.
10866 (define_insn_and_split "*jcc_bt<mode>_mask"
10868 (if_then_else (match_operator 0 "bt_comparison_operator"
10869 [(zero_extract:SWI48
10870 (match_operand:SWI48 1 "register_operand" "r")
10873 (match_operand:SI 2 "register_operand" "r")
10874 (match_operand:SI 3 "const_int_operand" "n")))])
10875 (label_ref (match_operand 4 "" ""))
10877 (clobber (reg:CC FLAGS_REG))]
10878 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10879 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10880 == GET_MODE_BITSIZE (<MODE>mode)-1"
10883 [(set (reg:CCC FLAGS_REG)
10885 (zero_extract:SWI48
10891 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10892 (label_ref (match_dup 4))
10895 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10897 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10900 (define_insn_and_split "*jcc_btsi_1"
10902 (if_then_else (match_operator 0 "bt_comparison_operator"
10905 (match_operand:SI 1 "register_operand" "r")
10906 (match_operand:QI 2 "register_operand" "r"))
10909 (label_ref (match_operand 3 "" ""))
10911 (clobber (reg:CC FLAGS_REG))]
10912 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10915 [(set (reg:CCC FLAGS_REG)
10923 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10924 (label_ref (match_dup 3))
10927 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10929 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10932 ;; avoid useless masking of bit offset operand
10933 (define_insn_and_split "*jcc_btsi_mask_1"
10936 (match_operator 0 "bt_comparison_operator"
10939 (match_operand:SI 1 "register_operand" "r")
10942 (match_operand:SI 2 "register_operand" "r")
10943 (match_operand:SI 3 "const_int_operand" "n")) 0))
10946 (label_ref (match_operand 4 "" ""))
10948 (clobber (reg:CC FLAGS_REG))]
10949 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10950 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10953 [(set (reg:CCC FLAGS_REG)
10961 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10962 (label_ref (match_dup 4))
10964 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10966 ;; Define combination compare-and-branch fp compare instructions to help
10969 (define_insn "*fp_jcc_1_387"
10971 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10972 [(match_operand 1 "register_operand" "f")
10973 (match_operand 2 "nonimmediate_operand" "fm")])
10974 (label_ref (match_operand 3 "" ""))
10976 (clobber (reg:CCFP FPSR_REG))
10977 (clobber (reg:CCFP FLAGS_REG))
10978 (clobber (match_scratch:HI 4 "=a"))]
10980 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10981 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10982 && SELECT_CC_MODE (GET_CODE (operands[0]),
10983 operands[1], operands[2]) == CCFPmode
10987 (define_insn "*fp_jcc_1r_387"
10989 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10990 [(match_operand 1 "register_operand" "f")
10991 (match_operand 2 "nonimmediate_operand" "fm")])
10993 (label_ref (match_operand 3 "" ""))))
10994 (clobber (reg:CCFP FPSR_REG))
10995 (clobber (reg:CCFP FLAGS_REG))
10996 (clobber (match_scratch:HI 4 "=a"))]
10998 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10999 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11000 && SELECT_CC_MODE (GET_CODE (operands[0]),
11001 operands[1], operands[2]) == CCFPmode
11005 (define_insn "*fp_jcc_2_387"
11007 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11008 [(match_operand 1 "register_operand" "f")
11009 (match_operand 2 "register_operand" "f")])
11010 (label_ref (match_operand 3 "" ""))
11012 (clobber (reg:CCFP FPSR_REG))
11013 (clobber (reg:CCFP FLAGS_REG))
11014 (clobber (match_scratch:HI 4 "=a"))]
11015 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11016 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11020 (define_insn "*fp_jcc_2r_387"
11022 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11023 [(match_operand 1 "register_operand" "f")
11024 (match_operand 2 "register_operand" "f")])
11026 (label_ref (match_operand 3 "" ""))))
11027 (clobber (reg:CCFP FPSR_REG))
11028 (clobber (reg:CCFP FLAGS_REG))
11029 (clobber (match_scratch:HI 4 "=a"))]
11030 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11031 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11035 (define_insn "*fp_jcc_3_387"
11037 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11038 [(match_operand 1 "register_operand" "f")
11039 (match_operand 2 "const0_operand" "")])
11040 (label_ref (match_operand 3 "" ""))
11042 (clobber (reg:CCFP FPSR_REG))
11043 (clobber (reg:CCFP FLAGS_REG))
11044 (clobber (match_scratch:HI 4 "=a"))]
11045 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11046 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11047 && SELECT_CC_MODE (GET_CODE (operands[0]),
11048 operands[1], operands[2]) == CCFPmode
11054 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11055 [(match_operand 1 "register_operand" "")
11056 (match_operand 2 "nonimmediate_operand" "")])
11057 (match_operand 3 "" "")
11058 (match_operand 4 "" "")))
11059 (clobber (reg:CCFP FPSR_REG))
11060 (clobber (reg:CCFP FLAGS_REG))]
11064 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11065 operands[3], operands[4], NULL_RTX, NULL_RTX);
11071 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11072 [(match_operand 1 "register_operand" "")
11073 (match_operand 2 "general_operand" "")])
11074 (match_operand 3 "" "")
11075 (match_operand 4 "" "")))
11076 (clobber (reg:CCFP FPSR_REG))
11077 (clobber (reg:CCFP FLAGS_REG))
11078 (clobber (match_scratch:HI 5 "=a"))]
11082 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11083 operands[3], operands[4], operands[5], NULL_RTX);
11087 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11088 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11089 ;; with a precedence over other operators and is always put in the first
11090 ;; place. Swap condition and operands to match ficom instruction.
11092 (define_insn "*fp_jcc_4_<mode>_387"
11095 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11096 [(match_operator 1 "float_operator"
11097 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11098 (match_operand 3 "register_operand" "f,f")])
11099 (label_ref (match_operand 4 "" ""))
11101 (clobber (reg:CCFP FPSR_REG))
11102 (clobber (reg:CCFP FLAGS_REG))
11103 (clobber (match_scratch:HI 5 "=a,a"))]
11104 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11105 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11106 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11107 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11114 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11115 [(match_operator 1 "float_operator"
11116 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11117 (match_operand 3 "register_operand" "")])
11118 (match_operand 4 "" "")
11119 (match_operand 5 "" "")))
11120 (clobber (reg:CCFP FPSR_REG))
11121 (clobber (reg:CCFP FLAGS_REG))
11122 (clobber (match_scratch:HI 6 "=a"))]
11126 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11128 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11129 operands[3], operands[7],
11130 operands[4], operands[5], operands[6], NULL_RTX);
11134 ;; %%% Kill this when reload knows how to do it.
11138 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11139 [(match_operator 1 "float_operator"
11140 [(match_operand:X87MODEI12 2 "register_operand" "")])
11141 (match_operand 3 "register_operand" "")])
11142 (match_operand 4 "" "")
11143 (match_operand 5 "" "")))
11144 (clobber (reg:CCFP FPSR_REG))
11145 (clobber (reg:CCFP FLAGS_REG))
11146 (clobber (match_scratch:HI 6 "=a"))]
11150 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11151 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11153 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11154 operands[3], operands[7],
11155 operands[4], operands[5], operands[6], operands[2]);
11159 ;; Unconditional and other jump instructions
11161 (define_insn "jump"
11163 (label_ref (match_operand 0 "" "")))]
11166 [(set_attr "type" "ibr")
11167 (set (attr "length")
11168 (if_then_else (and (ge (minus (match_dup 0) (pc))
11170 (lt (minus (match_dup 0) (pc))
11174 (set_attr "modrm" "0")])
11176 (define_expand "indirect_jump"
11177 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11181 (define_insn "*indirect_jump"
11182 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11185 [(set_attr "type" "ibr")
11186 (set_attr "length_immediate" "0")])
11188 (define_expand "tablejump"
11189 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11190 (use (label_ref (match_operand 1 "" "")))])]
11193 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11194 relative. Convert the relative address to an absolute address. */
11198 enum rtx_code code;
11200 /* We can't use @GOTOFF for text labels on VxWorks;
11201 see gotoff_operand. */
11202 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11206 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11208 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11212 op1 = pic_offset_table_rtx;
11217 op0 = pic_offset_table_rtx;
11221 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11226 (define_insn "*tablejump_1"
11227 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11228 (use (label_ref (match_operand 1 "" "")))]
11231 [(set_attr "type" "ibr")
11232 (set_attr "length_immediate" "0")])
11234 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11237 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11238 (set (match_operand:QI 1 "register_operand" "")
11239 (match_operator:QI 2 "ix86_comparison_operator"
11240 [(reg FLAGS_REG) (const_int 0)]))
11241 (set (match_operand 3 "q_regs_operand" "")
11242 (zero_extend (match_dup 1)))]
11243 "(peep2_reg_dead_p (3, operands[1])
11244 || operands_match_p (operands[1], operands[3]))
11245 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11246 [(set (match_dup 4) (match_dup 0))
11247 (set (strict_low_part (match_dup 5))
11250 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11251 operands[5] = gen_lowpart (QImode, operands[3]);
11252 ix86_expand_clear (operands[3]);
11255 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11258 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11259 (set (match_operand:QI 1 "register_operand" "")
11260 (match_operator:QI 2 "ix86_comparison_operator"
11261 [(reg FLAGS_REG) (const_int 0)]))
11262 (parallel [(set (match_operand 3 "q_regs_operand" "")
11263 (zero_extend (match_dup 1)))
11264 (clobber (reg:CC FLAGS_REG))])]
11265 "(peep2_reg_dead_p (3, operands[1])
11266 || operands_match_p (operands[1], operands[3]))
11267 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11268 [(set (match_dup 4) (match_dup 0))
11269 (set (strict_low_part (match_dup 5))
11272 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11273 operands[5] = gen_lowpart (QImode, operands[3]);
11274 ix86_expand_clear (operands[3]);
11277 ;; Call instructions.
11279 ;; The predicates normally associated with named expanders are not properly
11280 ;; checked for calls. This is a bug in the generic code, but it isn't that
11281 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11283 ;; P6 processors will jump to the address after the decrement when %esp
11284 ;; is used as a call operand, so they will execute return address as a code.
11285 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11287 ;; Call subroutine returning no value.
11289 (define_expand "call_pop"
11290 [(parallel [(call (match_operand:QI 0 "" "")
11291 (match_operand:SI 1 "" ""))
11292 (set (reg:SI SP_REG)
11293 (plus:SI (reg:SI SP_REG)
11294 (match_operand:SI 3 "" "")))])]
11297 ix86_expand_call (NULL, operands[0], operands[1],
11298 operands[2], operands[3], 0);
11302 (define_insn_and_split "*call_pop_0_vzeroupper"
11304 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11305 (match_operand:SI 1 "" ""))
11306 (set (reg:SI SP_REG)
11307 (plus:SI (reg:SI SP_REG)
11308 (match_operand:SI 2 "immediate_operand" "")))])
11309 (unspec [(match_operand 3 "const_int_operand" "")]
11310 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11311 "TARGET_VZEROUPPER && !TARGET_64BIT"
11313 "&& reload_completed"
11315 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11316 [(set_attr "type" "call")])
11318 (define_insn "*call_pop_0"
11319 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11320 (match_operand:SI 1 "" ""))
11321 (set (reg:SI SP_REG)
11322 (plus:SI (reg:SI SP_REG)
11323 (match_operand:SI 2 "immediate_operand" "")))]
11326 if (SIBLING_CALL_P (insn))
11329 return "call\t%P0";
11331 [(set_attr "type" "call")])
11333 (define_insn_and_split "*call_pop_1_vzeroupper"
11335 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11336 (match_operand:SI 1 "" ""))
11337 (set (reg:SI SP_REG)
11338 (plus:SI (reg:SI SP_REG)
11339 (match_operand:SI 2 "immediate_operand" "i")))])
11340 (unspec [(match_operand 3 "const_int_operand" "")]
11341 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11342 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11344 "&& reload_completed"
11346 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11347 [(set_attr "type" "call")])
11349 (define_insn "*call_pop_1"
11350 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11351 (match_operand:SI 1 "" ""))
11352 (set (reg:SI SP_REG)
11353 (plus:SI (reg:SI SP_REG)
11354 (match_operand:SI 2 "immediate_operand" "i")))]
11355 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11357 if (constant_call_address_operand (operands[0], Pmode))
11358 return "call\t%P0";
11359 return "call\t%A0";
11361 [(set_attr "type" "call")])
11363 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11365 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11366 (match_operand:SI 1 "" ""))
11367 (set (reg:SI SP_REG)
11368 (plus:SI (reg:SI SP_REG)
11369 (match_operand:SI 2 "immediate_operand" "i,i")))])
11370 (unspec [(match_operand 3 "const_int_operand" "")]
11371 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11372 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11374 "&& reload_completed"
11376 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11377 [(set_attr "type" "call")])
11379 (define_insn "*sibcall_pop_1"
11380 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11381 (match_operand:SI 1 "" ""))
11382 (set (reg:SI SP_REG)
11383 (plus:SI (reg:SI SP_REG)
11384 (match_operand:SI 2 "immediate_operand" "i,i")))]
11385 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11389 [(set_attr "type" "call")])
11391 (define_expand "call"
11392 [(call (match_operand:QI 0 "" "")
11393 (match_operand 1 "" ""))
11394 (use (match_operand 2 "" ""))]
11397 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11401 (define_expand "sibcall"
11402 [(call (match_operand:QI 0 "" "")
11403 (match_operand 1 "" ""))
11404 (use (match_operand 2 "" ""))]
11407 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11411 (define_insn_and_split "*call_0_vzeroupper"
11412 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11413 (match_operand 1 "" ""))
11414 (unspec [(match_operand 2 "const_int_operand" "")]
11415 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11416 "TARGET_VZEROUPPER"
11418 "&& reload_completed"
11420 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11421 [(set_attr "type" "call")])
11423 (define_insn "*call_0"
11424 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11425 (match_operand 1 "" ""))]
11427 { return ix86_output_call_insn (insn, operands[0], 0); }
11428 [(set_attr "type" "call")])
11430 (define_insn_and_split "*call_1_vzeroupper"
11431 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11432 (match_operand 1 "" ""))
11433 (unspec [(match_operand 2 "const_int_operand" "")]
11434 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11435 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11437 "&& reload_completed"
11439 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11440 [(set_attr "type" "call")])
11442 (define_insn "*call_1"
11443 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11444 (match_operand 1 "" ""))]
11445 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11446 { return ix86_output_call_insn (insn, operands[0], 0); }
11447 [(set_attr "type" "call")])
11449 (define_insn_and_split "*sibcall_1_vzeroupper"
11450 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11451 (match_operand 1 "" ""))
11452 (unspec [(match_operand 2 "const_int_operand" "")]
11453 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11454 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11456 "&& reload_completed"
11458 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11459 [(set_attr "type" "call")])
11461 (define_insn "*sibcall_1"
11462 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11463 (match_operand 1 "" ""))]
11464 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11465 { return ix86_output_call_insn (insn, operands[0], 0); }
11466 [(set_attr "type" "call")])
11468 (define_insn_and_split "*call_1_rex64_vzeroupper"
11469 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11470 (match_operand 1 "" ""))
11471 (unspec [(match_operand 2 "const_int_operand" "")]
11472 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11473 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11474 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11476 "&& reload_completed"
11478 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11479 [(set_attr "type" "call")])
11481 (define_insn "*call_1_rex64"
11482 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11483 (match_operand 1 "" ""))]
11484 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11485 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11486 { return ix86_output_call_insn (insn, operands[0], 0); }
11487 [(set_attr "type" "call")])
11489 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11491 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11492 (match_operand 1 "" ""))
11493 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11494 (clobber (reg:TI XMM6_REG))
11495 (clobber (reg:TI XMM7_REG))
11496 (clobber (reg:TI XMM8_REG))
11497 (clobber (reg:TI XMM9_REG))
11498 (clobber (reg:TI XMM10_REG))
11499 (clobber (reg:TI XMM11_REG))
11500 (clobber (reg:TI XMM12_REG))
11501 (clobber (reg:TI XMM13_REG))
11502 (clobber (reg:TI XMM14_REG))
11503 (clobber (reg:TI XMM15_REG))
11504 (clobber (reg:DI SI_REG))
11505 (clobber (reg:DI DI_REG))])
11506 (unspec [(match_operand 2 "const_int_operand" "")]
11507 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11508 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11510 "&& reload_completed"
11512 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11513 [(set_attr "type" "call")])
11515 (define_insn "*call_1_rex64_ms_sysv"
11516 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11517 (match_operand 1 "" ""))
11518 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11519 (clobber (reg:TI XMM6_REG))
11520 (clobber (reg:TI XMM7_REG))
11521 (clobber (reg:TI XMM8_REG))
11522 (clobber (reg:TI XMM9_REG))
11523 (clobber (reg:TI XMM10_REG))
11524 (clobber (reg:TI XMM11_REG))
11525 (clobber (reg:TI XMM12_REG))
11526 (clobber (reg:TI XMM13_REG))
11527 (clobber (reg:TI XMM14_REG))
11528 (clobber (reg:TI XMM15_REG))
11529 (clobber (reg:DI SI_REG))
11530 (clobber (reg:DI DI_REG))]
11531 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11532 { return ix86_output_call_insn (insn, operands[0], 0); }
11533 [(set_attr "type" "call")])
11535 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11536 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11537 (match_operand 1 "" ""))
11538 (unspec [(match_operand 2 "const_int_operand" "")]
11539 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11540 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11542 "&& reload_completed"
11544 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11545 [(set_attr "type" "call")])
11547 (define_insn "*call_1_rex64_large"
11548 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11549 (match_operand 1 "" ""))]
11550 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11551 { return ix86_output_call_insn (insn, operands[0], 0); }
11552 [(set_attr "type" "call")])
11554 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11555 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11556 (match_operand 1 "" ""))
11557 (unspec [(match_operand 2 "const_int_operand" "")]
11558 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11559 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11561 "&& reload_completed"
11563 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11564 [(set_attr "type" "call")])
11566 (define_insn "*sibcall_1_rex64"
11567 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11568 (match_operand 1 "" ""))]
11569 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11570 { return ix86_output_call_insn (insn, operands[0], 0); }
11571 [(set_attr "type" "call")])
11573 ;; Call subroutine, returning value in operand 0
11574 (define_expand "call_value_pop"
11575 [(parallel [(set (match_operand 0 "" "")
11576 (call (match_operand:QI 1 "" "")
11577 (match_operand:SI 2 "" "")))
11578 (set (reg:SI SP_REG)
11579 (plus:SI (reg:SI SP_REG)
11580 (match_operand:SI 4 "" "")))])]
11583 ix86_expand_call (operands[0], operands[1], operands[2],
11584 operands[3], operands[4], 0);
11588 (define_expand "call_value"
11589 [(set (match_operand 0 "" "")
11590 (call (match_operand:QI 1 "" "")
11591 (match_operand:SI 2 "" "")))
11592 (use (match_operand:SI 3 "" ""))]
11593 ;; Operand 3 is not used on the i386.
11596 ix86_expand_call (operands[0], operands[1], operands[2],
11597 operands[3], NULL, 0);
11601 (define_expand "sibcall_value"
11602 [(set (match_operand 0 "" "")
11603 (call (match_operand:QI 1 "" "")
11604 (match_operand:SI 2 "" "")))
11605 (use (match_operand:SI 3 "" ""))]
11606 ;; Operand 3 is not used on the i386.
11609 ix86_expand_call (operands[0], operands[1], operands[2],
11610 operands[3], NULL, 1);
11614 ;; Call subroutine returning any type.
11616 (define_expand "untyped_call"
11617 [(parallel [(call (match_operand 0 "" "")
11619 (match_operand 1 "" "")
11620 (match_operand 2 "" "")])]
11625 /* In order to give reg-stack an easier job in validating two
11626 coprocessor registers as containing a possible return value,
11627 simply pretend the untyped call returns a complex long double
11630 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11631 and should have the default ABI. */
11633 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11634 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11635 operands[0], const0_rtx,
11636 GEN_INT ((TARGET_64BIT
11637 ? (ix86_abi == SYSV_ABI
11638 ? X86_64_SSE_REGPARM_MAX
11639 : X86_64_MS_SSE_REGPARM_MAX)
11640 : X86_32_SSE_REGPARM_MAX)
11644 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11646 rtx set = XVECEXP (operands[2], 0, i);
11647 emit_move_insn (SET_DEST (set), SET_SRC (set));
11650 /* The optimizer does not know that the call sets the function value
11651 registers we stored in the result block. We avoid problems by
11652 claiming that all hard registers are used and clobbered at this
11654 emit_insn (gen_blockage ());
11659 ;; Prologue and epilogue instructions
11661 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11662 ;; all of memory. This blocks insns from being moved across this point.
11664 (define_insn "blockage"
11665 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11668 [(set_attr "length" "0")])
11670 ;; Do not schedule instructions accessing memory across this point.
11672 (define_expand "memory_blockage"
11673 [(set (match_dup 0)
11674 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11677 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11678 MEM_VOLATILE_P (operands[0]) = 1;
11681 (define_insn "*memory_blockage"
11682 [(set (match_operand:BLK 0 "" "")
11683 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11686 [(set_attr "length" "0")])
11688 ;; As USE insns aren't meaningful after reload, this is used instead
11689 ;; to prevent deleting instructions setting registers for PIC code
11690 (define_insn "prologue_use"
11691 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11694 [(set_attr "length" "0")])
11696 ;; Insn emitted into the body of a function to return from a function.
11697 ;; This is only done if the function's epilogue is known to be simple.
11698 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11700 (define_expand "return"
11702 "ix86_can_use_return_insn_p ()"
11704 if (crtl->args.pops_args)
11706 rtx popc = GEN_INT (crtl->args.pops_args);
11707 emit_jump_insn (gen_return_pop_internal (popc));
11712 (define_insn "return_internal"
11716 [(set_attr "length" "1")
11717 (set_attr "atom_unit" "jeu")
11718 (set_attr "length_immediate" "0")
11719 (set_attr "modrm" "0")])
11721 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11722 ;; instruction Athlon and K8 have.
11724 (define_insn "return_internal_long"
11726 (unspec [(const_int 0)] UNSPEC_REP)]
11729 [(set_attr "length" "2")
11730 (set_attr "atom_unit" "jeu")
11731 (set_attr "length_immediate" "0")
11732 (set_attr "prefix_rep" "1")
11733 (set_attr "modrm" "0")])
11735 (define_insn "return_pop_internal"
11737 (use (match_operand:SI 0 "const_int_operand" ""))]
11740 [(set_attr "length" "3")
11741 (set_attr "atom_unit" "jeu")
11742 (set_attr "length_immediate" "2")
11743 (set_attr "modrm" "0")])
11745 (define_insn "return_indirect_internal"
11747 (use (match_operand:SI 0 "register_operand" "r"))]
11750 [(set_attr "type" "ibr")
11751 (set_attr "length_immediate" "0")])
11757 [(set_attr "length" "1")
11758 (set_attr "length_immediate" "0")
11759 (set_attr "modrm" "0")])
11761 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11762 (define_insn "nops"
11763 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11767 int num = INTVAL (operands[0]);
11769 gcc_assert (num >= 1 && num <= 8);
11772 fputs ("\tnop\n", asm_out_file);
11776 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11777 (set_attr "length_immediate" "0")
11778 (set_attr "modrm" "0")])
11780 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11781 ;; branch prediction penalty for the third jump in a 16-byte
11785 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11788 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11789 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11791 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11792 The align insn is used to avoid 3 jump instructions in the row to improve
11793 branch prediction and the benefits hardly outweigh the cost of extra 8
11794 nops on the average inserted by full alignment pseudo operation. */
11798 [(set_attr "length" "16")])
11800 (define_expand "prologue"
11803 "ix86_expand_prologue (); DONE;")
11805 (define_insn "set_got"
11806 [(set (match_operand:SI 0 "register_operand" "=r")
11807 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11808 (clobber (reg:CC FLAGS_REG))]
11810 "* return output_set_got (operands[0], NULL_RTX);"
11811 [(set_attr "type" "multi")
11812 (set_attr "length" "12")])
11814 (define_insn "set_got_labelled"
11815 [(set (match_operand:SI 0 "register_operand" "=r")
11816 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11818 (clobber (reg:CC FLAGS_REG))]
11820 "* return output_set_got (operands[0], operands[1]);"
11821 [(set_attr "type" "multi")
11822 (set_attr "length" "12")])
11824 (define_insn "set_got_rex64"
11825 [(set (match_operand:DI 0 "register_operand" "=r")
11826 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11828 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11829 [(set_attr "type" "lea")
11830 (set_attr "length_address" "4")
11831 (set_attr "mode" "DI")])
11833 (define_insn "set_rip_rex64"
11834 [(set (match_operand:DI 0 "register_operand" "=r")
11835 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11837 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11838 [(set_attr "type" "lea")
11839 (set_attr "length_address" "4")
11840 (set_attr "mode" "DI")])
11842 (define_insn "set_got_offset_rex64"
11843 [(set (match_operand:DI 0 "register_operand" "=r")
11845 [(label_ref (match_operand 1 "" ""))]
11846 UNSPEC_SET_GOT_OFFSET))]
11848 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11849 [(set_attr "type" "imov")
11850 (set_attr "length_immediate" "0")
11851 (set_attr "length_address" "8")
11852 (set_attr "mode" "DI")])
11854 (define_expand "epilogue"
11857 "ix86_expand_epilogue (1); DONE;")
11859 (define_expand "sibcall_epilogue"
11862 "ix86_expand_epilogue (0); DONE;")
11864 (define_expand "eh_return"
11865 [(use (match_operand 0 "register_operand" ""))]
11868 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11870 /* Tricky bit: we write the address of the handler to which we will
11871 be returning into someone else's stack frame, one word below the
11872 stack address we wish to restore. */
11873 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11874 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11875 tmp = gen_rtx_MEM (Pmode, tmp);
11876 emit_move_insn (tmp, ra);
11878 emit_jump_insn (gen_eh_return_internal ());
11883 (define_insn_and_split "eh_return_internal"
11887 "epilogue_completed"
11889 "ix86_expand_epilogue (2); DONE;")
11891 (define_insn "leave"
11892 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11893 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11894 (clobber (mem:BLK (scratch)))]
11897 [(set_attr "type" "leave")])
11899 (define_insn "leave_rex64"
11900 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11901 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11902 (clobber (mem:BLK (scratch)))]
11905 [(set_attr "type" "leave")])
11907 ;; Handle -fsplit-stack.
11909 (define_expand "split_stack_prologue"
11913 ix86_expand_split_stack_prologue ();
11917 ;; In order to support the call/return predictor, we use a return
11918 ;; instruction which the middle-end doesn't see.
11919 (define_insn "split_stack_return"
11920 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11921 UNSPECV_SPLIT_STACK_RETURN)]
11924 if (operands[0] == const0_rtx)
11929 [(set_attr "atom_unit" "jeu")
11930 (set_attr "modrm" "0")
11931 (set (attr "length")
11932 (if_then_else (match_operand:SI 0 "const0_operand" "")
11935 (set (attr "length_immediate")
11936 (if_then_else (match_operand:SI 0 "const0_operand" "")
11940 ;; If there are operand 0 bytes available on the stack, jump to
11943 (define_expand "split_stack_space_check"
11944 [(set (pc) (if_then_else
11945 (ltu (minus (reg SP_REG)
11946 (match_operand 0 "register_operand" ""))
11947 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11948 (label_ref (match_operand 1 "" ""))
11952 rtx reg, size, limit;
11954 reg = gen_reg_rtx (Pmode);
11955 size = force_reg (Pmode, operands[0]);
11956 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11957 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11958 UNSPEC_STACK_CHECK);
11959 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11960 ix86_expand_branch (GEU, reg, limit, operands[1]);
11965 ;; Bit manipulation instructions.
11967 (define_expand "ffs<mode>2"
11968 [(set (match_dup 2) (const_int -1))
11969 (parallel [(set (reg:CCZ FLAGS_REG)
11971 (match_operand:SWI48 1 "nonimmediate_operand" "")
11973 (set (match_operand:SWI48 0 "register_operand" "")
11974 (ctz:SWI48 (match_dup 1)))])
11975 (set (match_dup 0) (if_then_else:SWI48
11976 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11979 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11980 (clobber (reg:CC FLAGS_REG))])]
11983 if (<MODE>mode == SImode && !TARGET_CMOVE)
11985 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11988 operands[2] = gen_reg_rtx (<MODE>mode);
11991 (define_insn_and_split "ffssi2_no_cmove"
11992 [(set (match_operand:SI 0 "register_operand" "=r")
11993 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11994 (clobber (match_scratch:SI 2 "=&q"))
11995 (clobber (reg:CC FLAGS_REG))]
11998 "&& reload_completed"
11999 [(parallel [(set (reg:CCZ FLAGS_REG)
12000 (compare:CCZ (match_dup 1) (const_int 0)))
12001 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12002 (set (strict_low_part (match_dup 3))
12003 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12004 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12005 (clobber (reg:CC FLAGS_REG))])
12006 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12007 (clobber (reg:CC FLAGS_REG))])
12008 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12009 (clobber (reg:CC FLAGS_REG))])]
12011 operands[3] = gen_lowpart (QImode, operands[2]);
12012 ix86_expand_clear (operands[2]);
12015 (define_insn "*ffs<mode>_1"
12016 [(set (reg:CCZ FLAGS_REG)
12017 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12019 (set (match_operand:SWI48 0 "register_operand" "=r")
12020 (ctz:SWI48 (match_dup 1)))]
12022 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12023 [(set_attr "type" "alu1")
12024 (set_attr "prefix_0f" "1")
12025 (set_attr "mode" "<MODE>")])
12027 (define_insn "ctz<mode>2"
12028 [(set (match_operand:SWI248 0 "register_operand" "=r")
12029 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12030 (clobber (reg:CC FLAGS_REG))]
12034 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12036 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12038 [(set_attr "type" "alu1")
12039 (set_attr "prefix_0f" "1")
12040 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12041 (set_attr "mode" "<MODE>")])
12043 (define_expand "clz<mode>2"
12045 [(set (match_operand:SWI248 0 "register_operand" "")
12048 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12049 (clobber (reg:CC FLAGS_REG))])
12051 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12052 (clobber (reg:CC FLAGS_REG))])]
12057 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12060 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12063 (define_insn "clz<mode>2_abm"
12064 [(set (match_operand:SWI248 0 "register_operand" "=r")
12065 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12066 (clobber (reg:CC FLAGS_REG))]
12067 "TARGET_ABM || TARGET_BMI"
12068 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12069 [(set_attr "prefix_rep" "1")
12070 (set_attr "type" "bitmanip")
12071 (set_attr "mode" "<MODE>")])
12073 ;; BMI instructions.
12074 (define_insn "*bmi_andn_<mode>"
12075 [(set (match_operand:SWI48 0 "register_operand" "=r")
12078 (match_operand:SWI48 1 "register_operand" "r"))
12079 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12080 (clobber (reg:CC FLAGS_REG))]
12082 "andn\t{%2, %1, %0|%0, %1, %2}"
12083 [(set_attr "type" "bitmanip")
12084 (set_attr "mode" "<MODE>")])
12086 (define_insn "bmi_bextr_<mode>"
12087 [(set (match_operand:SWI48 0 "register_operand" "=r")
12088 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12089 (match_operand:SWI48 2 "register_operand" "r")]
12091 (clobber (reg:CC FLAGS_REG))]
12093 "bextr\t{%2, %1, %0|%0, %1, %2}"
12094 [(set_attr "type" "bitmanip")
12095 (set_attr "mode" "<MODE>")])
12097 (define_insn "*bmi_blsi_<mode>"
12098 [(set (match_operand:SWI48 0 "register_operand" "=r")
12101 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12103 (clobber (reg:CC FLAGS_REG))]
12105 "blsi\t{%1, %0|%0, %1}"
12106 [(set_attr "type" "bitmanip")
12107 (set_attr "mode" "<MODE>")])
12109 (define_insn "*bmi_blsmsk_<mode>"
12110 [(set (match_operand:SWI48 0 "register_operand" "=r")
12113 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12116 (clobber (reg:CC FLAGS_REG))]
12118 "blsmsk\t{%1, %0|%0, %1}"
12119 [(set_attr "type" "bitmanip")
12120 (set_attr "mode" "<MODE>")])
12122 (define_insn "*bmi_blsr_<mode>"
12123 [(set (match_operand:SWI48 0 "register_operand" "=r")
12126 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12129 (clobber (reg:CC FLAGS_REG))]
12131 "blsr\t{%1, %0|%0, %1}"
12132 [(set_attr "type" "bitmanip")
12133 (set_attr "mode" "<MODE>")])
12135 ;; TBM instructions.
12136 (define_insn "tbm_bextri_<mode>"
12137 [(set (match_operand:SWI48 0 "register_operand" "=r")
12138 (zero_extract:SWI48
12139 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12140 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12141 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12142 (clobber (reg:CC FLAGS_REG))]
12145 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12146 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12148 [(set_attr "type" "bitmanip")
12149 (set_attr "mode" "<MODE>")])
12151 (define_insn "*tbm_blcfill_<mode>"
12152 [(set (match_operand:SWI48 0 "register_operand" "=r")
12155 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12158 (clobber (reg:CC FLAGS_REG))]
12160 "blcfill\t{%1, %0|%0, %1}"
12161 [(set_attr "type" "bitmanip")
12162 (set_attr "mode" "<MODE>")])
12164 (define_insn "*tbm_blci_<mode>"
12165 [(set (match_operand:SWI48 0 "register_operand" "=r")
12169 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12172 (clobber (reg:CC FLAGS_REG))]
12174 "blci\t{%1, %0|%0, %1}"
12175 [(set_attr "type" "bitmanip")
12176 (set_attr "mode" "<MODE>")])
12178 (define_insn "*tbm_blcic_<mode>"
12179 [(set (match_operand:SWI48 0 "register_operand" "=r")
12182 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12186 (clobber (reg:CC FLAGS_REG))]
12188 "blcic\t{%1, %0|%0, %1}"
12189 [(set_attr "type" "bitmanip")
12190 (set_attr "mode" "<MODE>")])
12192 (define_insn "*tbm_blcmsk_<mode>"
12193 [(set (match_operand:SWI48 0 "register_operand" "=r")
12196 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12199 (clobber (reg:CC FLAGS_REG))]
12201 "blcmsk\t{%1, %0|%0, %1}"
12202 [(set_attr "type" "bitmanip")
12203 (set_attr "mode" "<MODE>")])
12205 (define_insn "*tbm_blcs_<mode>"
12206 [(set (match_operand:SWI48 0 "register_operand" "=r")
12209 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12212 (clobber (reg:CC FLAGS_REG))]
12214 "blcs\t{%1, %0|%0, %1}"
12215 [(set_attr "type" "bitmanip")
12216 (set_attr "mode" "<MODE>")])
12218 (define_insn "*tbm_blsfill_<mode>"
12219 [(set (match_operand:SWI48 0 "register_operand" "=r")
12222 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12225 (clobber (reg:CC FLAGS_REG))]
12227 "blsfill\t{%1, %0|%0, %1}"
12228 [(set_attr "type" "bitmanip")
12229 (set_attr "mode" "<MODE>")])
12231 (define_insn "*tbm_blsic_<mode>"
12232 [(set (match_operand:SWI48 0 "register_operand" "=r")
12235 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12239 (clobber (reg:CC FLAGS_REG))]
12241 "blsic\t{%1, %0|%0, %1}"
12242 [(set_attr "type" "bitmanip")
12243 (set_attr "mode" "<MODE>")])
12245 (define_insn "*tbm_t1mskc_<mode>"
12246 [(set (match_operand:SWI48 0 "register_operand" "=r")
12249 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12253 (clobber (reg:CC FLAGS_REG))]
12255 "t1mskc\t{%1, %0|%0, %1}"
12256 [(set_attr "type" "bitmanip")
12257 (set_attr "mode" "<MODE>")])
12259 (define_insn "*tbm_tzmsk_<mode>"
12260 [(set (match_operand:SWI48 0 "register_operand" "=r")
12263 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12267 (clobber (reg:CC FLAGS_REG))]
12269 "tzmsk\t{%1, %0|%0, %1}"
12270 [(set_attr "type" "bitmanip")
12271 (set_attr "mode" "<MODE>")])
12273 (define_insn "bsr_rex64"
12274 [(set (match_operand:DI 0 "register_operand" "=r")
12275 (minus:DI (const_int 63)
12276 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12277 (clobber (reg:CC FLAGS_REG))]
12279 "bsr{q}\t{%1, %0|%0, %1}"
12280 [(set_attr "type" "alu1")
12281 (set_attr "prefix_0f" "1")
12282 (set_attr "mode" "DI")])
12285 [(set (match_operand:SI 0 "register_operand" "=r")
12286 (minus:SI (const_int 31)
12287 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12288 (clobber (reg:CC FLAGS_REG))]
12290 "bsr{l}\t{%1, %0|%0, %1}"
12291 [(set_attr "type" "alu1")
12292 (set_attr "prefix_0f" "1")
12293 (set_attr "mode" "SI")])
12295 (define_insn "*bsrhi"
12296 [(set (match_operand:HI 0 "register_operand" "=r")
12297 (minus:HI (const_int 15)
12298 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12299 (clobber (reg:CC FLAGS_REG))]
12301 "bsr{w}\t{%1, %0|%0, %1}"
12302 [(set_attr "type" "alu1")
12303 (set_attr "prefix_0f" "1")
12304 (set_attr "mode" "HI")])
12306 (define_insn "popcount<mode>2"
12307 [(set (match_operand:SWI248 0 "register_operand" "=r")
12309 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12310 (clobber (reg:CC FLAGS_REG))]
12314 return "popcnt\t{%1, %0|%0, %1}";
12316 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12319 [(set_attr "prefix_rep" "1")
12320 (set_attr "type" "bitmanip")
12321 (set_attr "mode" "<MODE>")])
12323 (define_insn "*popcount<mode>2_cmp"
12324 [(set (reg FLAGS_REG)
12327 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12329 (set (match_operand:SWI248 0 "register_operand" "=r")
12330 (popcount:SWI248 (match_dup 1)))]
12331 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12334 return "popcnt\t{%1, %0|%0, %1}";
12336 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12339 [(set_attr "prefix_rep" "1")
12340 (set_attr "type" "bitmanip")
12341 (set_attr "mode" "<MODE>")])
12343 (define_insn "*popcountsi2_cmp_zext"
12344 [(set (reg FLAGS_REG)
12346 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12348 (set (match_operand:DI 0 "register_operand" "=r")
12349 (zero_extend:DI(popcount:SI (match_dup 1))))]
12350 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12353 return "popcnt\t{%1, %0|%0, %1}";
12355 return "popcnt{l}\t{%1, %0|%0, %1}";
12358 [(set_attr "prefix_rep" "1")
12359 (set_attr "type" "bitmanip")
12360 (set_attr "mode" "SI")])
12362 (define_expand "bswap<mode>2"
12363 [(set (match_operand:SWI48 0 "register_operand" "")
12364 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12367 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12369 rtx x = operands[0];
12371 emit_move_insn (x, operands[1]);
12372 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12373 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12374 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12379 (define_insn "*bswap<mode>2_movbe"
12380 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12381 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12383 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12386 movbe\t{%1, %0|%0, %1}
12387 movbe\t{%1, %0|%0, %1}"
12388 [(set_attr "type" "bitmanip,imov,imov")
12389 (set_attr "modrm" "0,1,1")
12390 (set_attr "prefix_0f" "*,1,1")
12391 (set_attr "prefix_extra" "*,1,1")
12392 (set_attr "mode" "<MODE>")])
12394 (define_insn "*bswap<mode>2_1"
12395 [(set (match_operand:SWI48 0 "register_operand" "=r")
12396 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12399 [(set_attr "type" "bitmanip")
12400 (set_attr "modrm" "0")
12401 (set_attr "mode" "<MODE>")])
12403 (define_insn "*bswaphi_lowpart_1"
12404 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12405 (bswap:HI (match_dup 0)))
12406 (clobber (reg:CC FLAGS_REG))]
12407 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12409 xchg{b}\t{%h0, %b0|%b0, %h0}
12410 rol{w}\t{$8, %0|%0, 8}"
12411 [(set_attr "length" "2,4")
12412 (set_attr "mode" "QI,HI")])
12414 (define_insn "bswaphi_lowpart"
12415 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12416 (bswap:HI (match_dup 0)))
12417 (clobber (reg:CC FLAGS_REG))]
12419 "rol{w}\t{$8, %0|%0, 8}"
12420 [(set_attr "length" "4")
12421 (set_attr "mode" "HI")])
12423 (define_expand "paritydi2"
12424 [(set (match_operand:DI 0 "register_operand" "")
12425 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12428 rtx scratch = gen_reg_rtx (QImode);
12431 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12432 NULL_RTX, operands[1]));
12434 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12435 gen_rtx_REG (CCmode, FLAGS_REG),
12437 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12440 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12443 rtx tmp = gen_reg_rtx (SImode);
12445 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12446 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12451 (define_expand "paritysi2"
12452 [(set (match_operand:SI 0 "register_operand" "")
12453 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12456 rtx scratch = gen_reg_rtx (QImode);
12459 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12461 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12462 gen_rtx_REG (CCmode, FLAGS_REG),
12464 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12466 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12470 (define_insn_and_split "paritydi2_cmp"
12471 [(set (reg:CC FLAGS_REG)
12472 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12474 (clobber (match_scratch:DI 0 "=r"))
12475 (clobber (match_scratch:SI 1 "=&r"))
12476 (clobber (match_scratch:HI 2 "=Q"))]
12479 "&& reload_completed"
12481 [(set (match_dup 1)
12482 (xor:SI (match_dup 1) (match_dup 4)))
12483 (clobber (reg:CC FLAGS_REG))])
12485 [(set (reg:CC FLAGS_REG)
12486 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12487 (clobber (match_dup 1))
12488 (clobber (match_dup 2))])]
12490 operands[4] = gen_lowpart (SImode, operands[3]);
12494 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12495 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12498 operands[1] = gen_highpart (SImode, operands[3]);
12501 (define_insn_and_split "paritysi2_cmp"
12502 [(set (reg:CC FLAGS_REG)
12503 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12505 (clobber (match_scratch:SI 0 "=r"))
12506 (clobber (match_scratch:HI 1 "=&Q"))]
12509 "&& reload_completed"
12511 [(set (match_dup 1)
12512 (xor:HI (match_dup 1) (match_dup 3)))
12513 (clobber (reg:CC FLAGS_REG))])
12515 [(set (reg:CC FLAGS_REG)
12516 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12517 (clobber (match_dup 1))])]
12519 operands[3] = gen_lowpart (HImode, operands[2]);
12521 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12522 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12525 (define_insn "*parityhi2_cmp"
12526 [(set (reg:CC FLAGS_REG)
12527 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12529 (clobber (match_scratch:HI 0 "=Q"))]
12531 "xor{b}\t{%h0, %b0|%b0, %h0}"
12532 [(set_attr "length" "2")
12533 (set_attr "mode" "HI")])
12535 ;; Thread-local storage patterns for ELF.
12537 ;; Note that these code sequences must appear exactly as shown
12538 ;; in order to allow linker relaxation.
12540 (define_insn "*tls_global_dynamic_32_gnu"
12541 [(set (match_operand:SI 0 "register_operand" "=a")
12542 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12543 (match_operand:SI 2 "tls_symbolic_operand" "")
12544 (match_operand:SI 3 "call_insn_operand" "")]
12546 (clobber (match_scratch:SI 4 "=d"))
12547 (clobber (match_scratch:SI 5 "=c"))
12548 (clobber (reg:CC FLAGS_REG))]
12549 "!TARGET_64BIT && TARGET_GNU_TLS"
12550 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12551 [(set_attr "type" "multi")
12552 (set_attr "length" "12")])
12554 (define_expand "tls_global_dynamic_32"
12555 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12557 [(match_operand:SI 2 "register_operand" "")
12558 (match_operand:SI 1 "tls_symbolic_operand" "")
12559 (match_operand:SI 3 "call_insn_operand" "")]
12561 (clobber (match_scratch:SI 4 ""))
12562 (clobber (match_scratch:SI 5 ""))
12563 (clobber (reg:CC FLAGS_REG))])])
12565 (define_insn "*tls_global_dynamic_64"
12566 [(set (match_operand:DI 0 "register_operand" "=a")
12567 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12568 (match_operand:DI 3 "" "")))
12569 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12572 { 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"; }
12573 [(set_attr "type" "multi")
12574 (set_attr "length" "16")])
12576 (define_expand "tls_global_dynamic_64"
12577 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12579 (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12581 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12584 (define_insn "*tls_local_dynamic_base_32_gnu"
12585 [(set (match_operand:SI 0 "register_operand" "=a")
12586 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12587 (match_operand:SI 2 "call_insn_operand" "")]
12588 UNSPEC_TLS_LD_BASE))
12589 (clobber (match_scratch:SI 3 "=d"))
12590 (clobber (match_scratch:SI 4 "=c"))
12591 (clobber (reg:CC FLAGS_REG))]
12592 "!TARGET_64BIT && TARGET_GNU_TLS"
12593 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12594 [(set_attr "type" "multi")
12595 (set_attr "length" "11")])
12597 (define_expand "tls_local_dynamic_base_32"
12598 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12599 (unspec:SI [(match_operand:SI 1 "register_operand" "")
12600 (match_operand:SI 2 "call_insn_operand" "")]
12601 UNSPEC_TLS_LD_BASE))
12602 (clobber (match_scratch:SI 3 ""))
12603 (clobber (match_scratch:SI 4 ""))
12604 (clobber (reg:CC FLAGS_REG))])])
12606 (define_insn "*tls_local_dynamic_base_64"
12607 [(set (match_operand:DI 0 "register_operand" "=a")
12608 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12609 (match_operand:DI 2 "" "")))
12610 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12612 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12613 [(set_attr "type" "multi")
12614 (set_attr "length" "12")])
12616 (define_expand "tls_local_dynamic_base_64"
12617 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12619 (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12621 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12623 ;; Local dynamic of a single variable is a lose. Show combine how
12624 ;; to convert that back to global dynamic.
12626 (define_insn_and_split "*tls_local_dynamic_32_once"
12627 [(set (match_operand:SI 0 "register_operand" "=a")
12628 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12629 (match_operand:SI 2 "call_insn_operand" "")]
12630 UNSPEC_TLS_LD_BASE)
12631 (const:SI (unspec:SI
12632 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12634 (clobber (match_scratch:SI 4 "=d"))
12635 (clobber (match_scratch:SI 5 "=c"))
12636 (clobber (reg:CC FLAGS_REG))]
12640 [(parallel [(set (match_dup 0)
12641 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12643 (clobber (match_dup 4))
12644 (clobber (match_dup 5))
12645 (clobber (reg:CC FLAGS_REG))])])
12647 ;; Segment register for the thread base ptr load
12648 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12650 ;; Load and add the thread base pointer from %gs:0.
12651 (define_insn "*load_tp_<mode>"
12652 [(set (match_operand:P 0 "register_operand" "=r")
12653 (unspec:P [(const_int 0)] UNSPEC_TP))]
12655 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12656 [(set_attr "type" "imov")
12657 (set_attr "modrm" "0")
12658 (set_attr "length" "7")
12659 (set_attr "memory" "load")
12660 (set_attr "imm_disp" "false")])
12662 (define_insn "*add_tp_<mode>"
12663 [(set (match_operand:P 0 "register_operand" "=r")
12664 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12665 (match_operand:P 1 "register_operand" "0")))
12666 (clobber (reg:CC FLAGS_REG))]
12668 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12669 [(set_attr "type" "alu")
12670 (set_attr "modrm" "0")
12671 (set_attr "length" "7")
12672 (set_attr "memory" "load")
12673 (set_attr "imm_disp" "false")])
12675 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12676 ;; %rax as destination of the initial executable code sequence.
12677 (define_insn "tls_initial_exec_64_sun"
12678 [(set (match_operand:DI 0 "register_operand" "=a")
12680 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12681 UNSPEC_TLS_IE_SUN))
12682 (clobber (reg:CC FLAGS_REG))]
12683 "TARGET_64BIT && TARGET_SUN_TLS"
12684 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12685 [(set_attr "type" "multi")])
12687 ;; GNU2 TLS patterns can be split.
12689 (define_expand "tls_dynamic_gnu2_32"
12690 [(set (match_dup 3)
12691 (plus:SI (match_operand:SI 2 "register_operand" "")
12693 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12696 [(set (match_operand:SI 0 "register_operand" "")
12697 (unspec:SI [(match_dup 1) (match_dup 3)
12698 (match_dup 2) (reg:SI SP_REG)]
12700 (clobber (reg:CC FLAGS_REG))])]
12701 "!TARGET_64BIT && TARGET_GNU2_TLS"
12703 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12704 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12707 (define_insn "*tls_dynamic_lea_32"
12708 [(set (match_operand:SI 0 "register_operand" "=r")
12709 (plus:SI (match_operand:SI 1 "register_operand" "b")
12711 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12712 UNSPEC_TLSDESC))))]
12713 "!TARGET_64BIT && TARGET_GNU2_TLS"
12714 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12715 [(set_attr "type" "lea")
12716 (set_attr "mode" "SI")
12717 (set_attr "length" "6")
12718 (set_attr "length_address" "4")])
12720 (define_insn "*tls_dynamic_call_32"
12721 [(set (match_operand:SI 0 "register_operand" "=a")
12722 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12723 (match_operand:SI 2 "register_operand" "0")
12724 ;; we have to make sure %ebx still points to the GOT
12725 (match_operand:SI 3 "register_operand" "b")
12728 (clobber (reg:CC FLAGS_REG))]
12729 "!TARGET_64BIT && TARGET_GNU2_TLS"
12730 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12731 [(set_attr "type" "call")
12732 (set_attr "length" "2")
12733 (set_attr "length_address" "0")])
12735 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12736 [(set (match_operand:SI 0 "register_operand" "=&a")
12738 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12739 (match_operand:SI 4 "" "")
12740 (match_operand:SI 2 "register_operand" "b")
12743 (const:SI (unspec:SI
12744 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12746 (clobber (reg:CC FLAGS_REG))]
12747 "!TARGET_64BIT && TARGET_GNU2_TLS"
12750 [(set (match_dup 0) (match_dup 5))]
12752 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12753 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12756 (define_expand "tls_dynamic_gnu2_64"
12757 [(set (match_dup 2)
12758 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12761 [(set (match_operand:DI 0 "register_operand" "")
12762 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12764 (clobber (reg:CC FLAGS_REG))])]
12765 "TARGET_64BIT && TARGET_GNU2_TLS"
12767 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12768 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12771 (define_insn "*tls_dynamic_lea_64"
12772 [(set (match_operand:DI 0 "register_operand" "=r")
12773 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12775 "TARGET_64BIT && TARGET_GNU2_TLS"
12776 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12777 [(set_attr "type" "lea")
12778 (set_attr "mode" "DI")
12779 (set_attr "length" "7")
12780 (set_attr "length_address" "4")])
12782 (define_insn "*tls_dynamic_call_64"
12783 [(set (match_operand:DI 0 "register_operand" "=a")
12784 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12785 (match_operand:DI 2 "register_operand" "0")
12788 (clobber (reg:CC FLAGS_REG))]
12789 "TARGET_64BIT && TARGET_GNU2_TLS"
12790 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12791 [(set_attr "type" "call")
12792 (set_attr "length" "2")
12793 (set_attr "length_address" "0")])
12795 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12796 [(set (match_operand:DI 0 "register_operand" "=&a")
12798 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12799 (match_operand:DI 3 "" "")
12802 (const:DI (unspec:DI
12803 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12805 (clobber (reg:CC FLAGS_REG))]
12806 "TARGET_64BIT && TARGET_GNU2_TLS"
12809 [(set (match_dup 0) (match_dup 4))]
12811 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12812 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12815 ;; These patterns match the binary 387 instructions for addM3, subM3,
12816 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12817 ;; SFmode. The first is the normal insn, the second the same insn but
12818 ;; with one operand a conversion, and the third the same insn but with
12819 ;; the other operand a conversion. The conversion may be SFmode or
12820 ;; SImode if the target mode DFmode, but only SImode if the target mode
12823 ;; Gcc is slightly more smart about handling normal two address instructions
12824 ;; so use special patterns for add and mull.
12826 (define_insn "*fop_<mode>_comm_mixed"
12827 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12828 (match_operator:MODEF 3 "binary_fp_operator"
12829 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12830 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12831 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12832 && COMMUTATIVE_ARITH_P (operands[3])
12833 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12834 "* return output_387_binary_op (insn, operands);"
12835 [(set (attr "type")
12836 (if_then_else (eq_attr "alternative" "1,2")
12837 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12838 (const_string "ssemul")
12839 (const_string "sseadd"))
12840 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12841 (const_string "fmul")
12842 (const_string "fop"))))
12843 (set_attr "isa" "base,noavx,avx")
12844 (set_attr "prefix" "orig,orig,vex")
12845 (set_attr "mode" "<MODE>")])
12847 (define_insn "*fop_<mode>_comm_sse"
12848 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12849 (match_operator:MODEF 3 "binary_fp_operator"
12850 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12851 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12852 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12853 && COMMUTATIVE_ARITH_P (operands[3])
12854 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12855 "* return output_387_binary_op (insn, operands);"
12856 [(set (attr "type")
12857 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12858 (const_string "ssemul")
12859 (const_string "sseadd")))
12860 (set_attr "isa" "noavx,avx")
12861 (set_attr "prefix" "orig,vex")
12862 (set_attr "mode" "<MODE>")])
12864 (define_insn "*fop_<mode>_comm_i387"
12865 [(set (match_operand:MODEF 0 "register_operand" "=f")
12866 (match_operator:MODEF 3 "binary_fp_operator"
12867 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12868 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12869 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12870 && COMMUTATIVE_ARITH_P (operands[3])
12871 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12872 "* return output_387_binary_op (insn, operands);"
12873 [(set (attr "type")
12874 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12875 (const_string "fmul")
12876 (const_string "fop")))
12877 (set_attr "mode" "<MODE>")])
12879 (define_insn "*fop_<mode>_1_mixed"
12880 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12881 (match_operator:MODEF 3 "binary_fp_operator"
12882 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12883 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12884 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12885 && !COMMUTATIVE_ARITH_P (operands[3])
12886 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12887 "* return output_387_binary_op (insn, operands);"
12888 [(set (attr "type")
12889 (cond [(and (eq_attr "alternative" "2,3")
12890 (match_operand:MODEF 3 "mult_operator" ""))
12891 (const_string "ssemul")
12892 (and (eq_attr "alternative" "2,3")
12893 (match_operand:MODEF 3 "div_operator" ""))
12894 (const_string "ssediv")
12895 (eq_attr "alternative" "2,3")
12896 (const_string "sseadd")
12897 (match_operand:MODEF 3 "mult_operator" "")
12898 (const_string "fmul")
12899 (match_operand:MODEF 3 "div_operator" "")
12900 (const_string "fdiv")
12902 (const_string "fop")))
12903 (set_attr "isa" "base,base,noavx,avx")
12904 (set_attr "prefix" "orig,orig,orig,vex")
12905 (set_attr "mode" "<MODE>")])
12907 (define_insn "*rcpsf2_sse"
12908 [(set (match_operand:SF 0 "register_operand" "=x")
12909 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12912 "%vrcpss\t{%1, %d0|%d0, %1}"
12913 [(set_attr "type" "sse")
12914 (set_attr "atom_sse_attr" "rcp")
12915 (set_attr "prefix" "maybe_vex")
12916 (set_attr "mode" "SF")])
12918 (define_insn "*fop_<mode>_1_sse"
12919 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12920 (match_operator:MODEF 3 "binary_fp_operator"
12921 [(match_operand:MODEF 1 "register_operand" "0,x")
12922 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12923 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12924 && !COMMUTATIVE_ARITH_P (operands[3])"
12925 "* return output_387_binary_op (insn, operands);"
12926 [(set (attr "type")
12927 (cond [(match_operand:MODEF 3 "mult_operator" "")
12928 (const_string "ssemul")
12929 (match_operand:MODEF 3 "div_operator" "")
12930 (const_string "ssediv")
12932 (const_string "sseadd")))
12933 (set_attr "isa" "noavx,avx")
12934 (set_attr "prefix" "orig,vex")
12935 (set_attr "mode" "<MODE>")])
12937 ;; This pattern is not fully shadowed by the pattern above.
12938 (define_insn "*fop_<mode>_1_i387"
12939 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12940 (match_operator:MODEF 3 "binary_fp_operator"
12941 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12942 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12943 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12944 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12945 && !COMMUTATIVE_ARITH_P (operands[3])
12946 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12947 "* return output_387_binary_op (insn, operands);"
12948 [(set (attr "type")
12949 (cond [(match_operand:MODEF 3 "mult_operator" "")
12950 (const_string "fmul")
12951 (match_operand:MODEF 3 "div_operator" "")
12952 (const_string "fdiv")
12954 (const_string "fop")))
12955 (set_attr "mode" "<MODE>")])
12957 ;; ??? Add SSE splitters for these!
12958 (define_insn "*fop_<MODEF:mode>_2_i387"
12959 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12960 (match_operator:MODEF 3 "binary_fp_operator"
12962 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12963 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12964 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12965 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12966 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12967 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12968 [(set (attr "type")
12969 (cond [(match_operand:MODEF 3 "mult_operator" "")
12970 (const_string "fmul")
12971 (match_operand:MODEF 3 "div_operator" "")
12972 (const_string "fdiv")
12974 (const_string "fop")))
12975 (set_attr "fp_int_src" "true")
12976 (set_attr "mode" "<X87MODEI12:MODE>")])
12978 (define_insn "*fop_<MODEF:mode>_3_i387"
12979 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12980 (match_operator:MODEF 3 "binary_fp_operator"
12981 [(match_operand:MODEF 1 "register_operand" "0,0")
12983 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12984 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12985 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12986 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12987 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12988 [(set (attr "type")
12989 (cond [(match_operand:MODEF 3 "mult_operator" "")
12990 (const_string "fmul")
12991 (match_operand:MODEF 3 "div_operator" "")
12992 (const_string "fdiv")
12994 (const_string "fop")))
12995 (set_attr "fp_int_src" "true")
12996 (set_attr "mode" "<MODE>")])
12998 (define_insn "*fop_df_4_i387"
12999 [(set (match_operand:DF 0 "register_operand" "=f,f")
13000 (match_operator:DF 3 "binary_fp_operator"
13002 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13003 (match_operand:DF 2 "register_operand" "0,f")]))]
13004 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13005 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13006 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13007 "* return output_387_binary_op (insn, operands);"
13008 [(set (attr "type")
13009 (cond [(match_operand:DF 3 "mult_operator" "")
13010 (const_string "fmul")
13011 (match_operand:DF 3 "div_operator" "")
13012 (const_string "fdiv")
13014 (const_string "fop")))
13015 (set_attr "mode" "SF")])
13017 (define_insn "*fop_df_5_i387"
13018 [(set (match_operand:DF 0 "register_operand" "=f,f")
13019 (match_operator:DF 3 "binary_fp_operator"
13020 [(match_operand:DF 1 "register_operand" "0,f")
13022 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13023 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13024 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13025 "* return output_387_binary_op (insn, operands);"
13026 [(set (attr "type")
13027 (cond [(match_operand:DF 3 "mult_operator" "")
13028 (const_string "fmul")
13029 (match_operand:DF 3 "div_operator" "")
13030 (const_string "fdiv")
13032 (const_string "fop")))
13033 (set_attr "mode" "SF")])
13035 (define_insn "*fop_df_6_i387"
13036 [(set (match_operand:DF 0 "register_operand" "=f,f")
13037 (match_operator:DF 3 "binary_fp_operator"
13039 (match_operand:SF 1 "register_operand" "0,f"))
13041 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13042 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13043 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13044 "* return output_387_binary_op (insn, operands);"
13045 [(set (attr "type")
13046 (cond [(match_operand:DF 3 "mult_operator" "")
13047 (const_string "fmul")
13048 (match_operand:DF 3 "div_operator" "")
13049 (const_string "fdiv")
13051 (const_string "fop")))
13052 (set_attr "mode" "SF")])
13054 (define_insn "*fop_xf_comm_i387"
13055 [(set (match_operand:XF 0 "register_operand" "=f")
13056 (match_operator:XF 3 "binary_fp_operator"
13057 [(match_operand:XF 1 "register_operand" "%0")
13058 (match_operand:XF 2 "register_operand" "f")]))]
13060 && COMMUTATIVE_ARITH_P (operands[3])"
13061 "* return output_387_binary_op (insn, operands);"
13062 [(set (attr "type")
13063 (if_then_else (match_operand:XF 3 "mult_operator" "")
13064 (const_string "fmul")
13065 (const_string "fop")))
13066 (set_attr "mode" "XF")])
13068 (define_insn "*fop_xf_1_i387"
13069 [(set (match_operand:XF 0 "register_operand" "=f,f")
13070 (match_operator:XF 3 "binary_fp_operator"
13071 [(match_operand:XF 1 "register_operand" "0,f")
13072 (match_operand:XF 2 "register_operand" "f,0")]))]
13074 && !COMMUTATIVE_ARITH_P (operands[3])"
13075 "* return output_387_binary_op (insn, operands);"
13076 [(set (attr "type")
13077 (cond [(match_operand:XF 3 "mult_operator" "")
13078 (const_string "fmul")
13079 (match_operand:XF 3 "div_operator" "")
13080 (const_string "fdiv")
13082 (const_string "fop")))
13083 (set_attr "mode" "XF")])
13085 (define_insn "*fop_xf_2_i387"
13086 [(set (match_operand:XF 0 "register_operand" "=f,f")
13087 (match_operator:XF 3 "binary_fp_operator"
13089 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13090 (match_operand:XF 2 "register_operand" "0,0")]))]
13091 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13092 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13093 [(set (attr "type")
13094 (cond [(match_operand:XF 3 "mult_operator" "")
13095 (const_string "fmul")
13096 (match_operand:XF 3 "div_operator" "")
13097 (const_string "fdiv")
13099 (const_string "fop")))
13100 (set_attr "fp_int_src" "true")
13101 (set_attr "mode" "<MODE>")])
13103 (define_insn "*fop_xf_3_i387"
13104 [(set (match_operand:XF 0 "register_operand" "=f,f")
13105 (match_operator:XF 3 "binary_fp_operator"
13106 [(match_operand:XF 1 "register_operand" "0,0")
13108 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13109 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13110 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13111 [(set (attr "type")
13112 (cond [(match_operand:XF 3 "mult_operator" "")
13113 (const_string "fmul")
13114 (match_operand:XF 3 "div_operator" "")
13115 (const_string "fdiv")
13117 (const_string "fop")))
13118 (set_attr "fp_int_src" "true")
13119 (set_attr "mode" "<MODE>")])
13121 (define_insn "*fop_xf_4_i387"
13122 [(set (match_operand:XF 0 "register_operand" "=f,f")
13123 (match_operator:XF 3 "binary_fp_operator"
13125 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13126 (match_operand:XF 2 "register_operand" "0,f")]))]
13128 "* return output_387_binary_op (insn, operands);"
13129 [(set (attr "type")
13130 (cond [(match_operand:XF 3 "mult_operator" "")
13131 (const_string "fmul")
13132 (match_operand:XF 3 "div_operator" "")
13133 (const_string "fdiv")
13135 (const_string "fop")))
13136 (set_attr "mode" "<MODE>")])
13138 (define_insn "*fop_xf_5_i387"
13139 [(set (match_operand:XF 0 "register_operand" "=f,f")
13140 (match_operator:XF 3 "binary_fp_operator"
13141 [(match_operand:XF 1 "register_operand" "0,f")
13143 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13145 "* return output_387_binary_op (insn, operands);"
13146 [(set (attr "type")
13147 (cond [(match_operand:XF 3 "mult_operator" "")
13148 (const_string "fmul")
13149 (match_operand:XF 3 "div_operator" "")
13150 (const_string "fdiv")
13152 (const_string "fop")))
13153 (set_attr "mode" "<MODE>")])
13155 (define_insn "*fop_xf_6_i387"
13156 [(set (match_operand:XF 0 "register_operand" "=f,f")
13157 (match_operator:XF 3 "binary_fp_operator"
13159 (match_operand:MODEF 1 "register_operand" "0,f"))
13161 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
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" "<MODE>")])
13174 [(set (match_operand 0 "register_operand" "")
13175 (match_operator 3 "binary_fp_operator"
13176 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13177 (match_operand 2 "register_operand" "")]))]
13179 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13180 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13183 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13184 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13185 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13186 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13187 GET_MODE (operands[3]),
13190 ix86_free_from_memory (GET_MODE (operands[1]));
13195 [(set (match_operand 0 "register_operand" "")
13196 (match_operator 3 "binary_fp_operator"
13197 [(match_operand 1 "register_operand" "")
13198 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13200 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13201 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13204 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13205 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13206 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13207 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13208 GET_MODE (operands[3]),
13211 ix86_free_from_memory (GET_MODE (operands[2]));
13215 ;; FPU special functions.
13217 ;; This pattern implements a no-op XFmode truncation for
13218 ;; all fancy i386 XFmode math functions.
13220 (define_insn "truncxf<mode>2_i387_noop_unspec"
13221 [(set (match_operand:MODEF 0 "register_operand" "=f")
13222 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13223 UNSPEC_TRUNC_NOOP))]
13224 "TARGET_USE_FANCY_MATH_387"
13225 "* return output_387_reg_move (insn, operands);"
13226 [(set_attr "type" "fmov")
13227 (set_attr "mode" "<MODE>")])
13229 (define_insn "sqrtxf2"
13230 [(set (match_operand:XF 0 "register_operand" "=f")
13231 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13232 "TARGET_USE_FANCY_MATH_387"
13234 [(set_attr "type" "fpspc")
13235 (set_attr "mode" "XF")
13236 (set_attr "athlon_decode" "direct")
13237 (set_attr "amdfam10_decode" "direct")
13238 (set_attr "bdver1_decode" "direct")])
13240 (define_insn "sqrt_extend<mode>xf2_i387"
13241 [(set (match_operand:XF 0 "register_operand" "=f")
13244 (match_operand:MODEF 1 "register_operand" "0"))))]
13245 "TARGET_USE_FANCY_MATH_387"
13247 [(set_attr "type" "fpspc")
13248 (set_attr "mode" "XF")
13249 (set_attr "athlon_decode" "direct")
13250 (set_attr "amdfam10_decode" "direct")
13251 (set_attr "bdver1_decode" "direct")])
13253 (define_insn "*rsqrtsf2_sse"
13254 [(set (match_operand:SF 0 "register_operand" "=x")
13255 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13258 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13259 [(set_attr "type" "sse")
13260 (set_attr "atom_sse_attr" "rcp")
13261 (set_attr "prefix" "maybe_vex")
13262 (set_attr "mode" "SF")])
13264 (define_expand "rsqrtsf2"
13265 [(set (match_operand:SF 0 "register_operand" "")
13266 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13270 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13274 (define_insn "*sqrt<mode>2_sse"
13275 [(set (match_operand:MODEF 0 "register_operand" "=x")
13277 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13278 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13279 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13280 [(set_attr "type" "sse")
13281 (set_attr "atom_sse_attr" "sqrt")
13282 (set_attr "prefix" "maybe_vex")
13283 (set_attr "mode" "<MODE>")
13284 (set_attr "athlon_decode" "*")
13285 (set_attr "amdfam10_decode" "*")
13286 (set_attr "bdver1_decode" "*")])
13288 (define_expand "sqrt<mode>2"
13289 [(set (match_operand:MODEF 0 "register_operand" "")
13291 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13292 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13293 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13295 if (<MODE>mode == SFmode
13296 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13297 && flag_finite_math_only && !flag_trapping_math
13298 && flag_unsafe_math_optimizations)
13300 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13304 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13306 rtx op0 = gen_reg_rtx (XFmode);
13307 rtx op1 = force_reg (<MODE>mode, operands[1]);
13309 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13310 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13315 (define_insn "fpremxf4_i387"
13316 [(set (match_operand:XF 0 "register_operand" "=f")
13317 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13318 (match_operand:XF 3 "register_operand" "1")]
13320 (set (match_operand:XF 1 "register_operand" "=u")
13321 (unspec:XF [(match_dup 2) (match_dup 3)]
13323 (set (reg:CCFP FPSR_REG)
13324 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13326 "TARGET_USE_FANCY_MATH_387"
13328 [(set_attr "type" "fpspc")
13329 (set_attr "mode" "XF")])
13331 (define_expand "fmodxf3"
13332 [(use (match_operand:XF 0 "register_operand" ""))
13333 (use (match_operand:XF 1 "general_operand" ""))
13334 (use (match_operand:XF 2 "general_operand" ""))]
13335 "TARGET_USE_FANCY_MATH_387"
13337 rtx label = gen_label_rtx ();
13339 rtx op1 = gen_reg_rtx (XFmode);
13340 rtx op2 = gen_reg_rtx (XFmode);
13342 emit_move_insn (op2, operands[2]);
13343 emit_move_insn (op1, operands[1]);
13345 emit_label (label);
13346 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13347 ix86_emit_fp_unordered_jump (label);
13348 LABEL_NUSES (label) = 1;
13350 emit_move_insn (operands[0], op1);
13354 (define_expand "fmod<mode>3"
13355 [(use (match_operand:MODEF 0 "register_operand" ""))
13356 (use (match_operand:MODEF 1 "general_operand" ""))
13357 (use (match_operand:MODEF 2 "general_operand" ""))]
13358 "TARGET_USE_FANCY_MATH_387"
13360 rtx (*gen_truncxf) (rtx, rtx);
13362 rtx label = gen_label_rtx ();
13364 rtx op1 = gen_reg_rtx (XFmode);
13365 rtx op2 = gen_reg_rtx (XFmode);
13367 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13368 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13370 emit_label (label);
13371 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13372 ix86_emit_fp_unordered_jump (label);
13373 LABEL_NUSES (label) = 1;
13375 /* Truncate the result properly for strict SSE math. */
13376 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13377 && !TARGET_MIX_SSE_I387)
13378 gen_truncxf = gen_truncxf<mode>2;
13380 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13382 emit_insn (gen_truncxf (operands[0], op1));
13386 (define_insn "fprem1xf4_i387"
13387 [(set (match_operand:XF 0 "register_operand" "=f")
13388 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13389 (match_operand:XF 3 "register_operand" "1")]
13391 (set (match_operand:XF 1 "register_operand" "=u")
13392 (unspec:XF [(match_dup 2) (match_dup 3)]
13394 (set (reg:CCFP FPSR_REG)
13395 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13397 "TARGET_USE_FANCY_MATH_387"
13399 [(set_attr "type" "fpspc")
13400 (set_attr "mode" "XF")])
13402 (define_expand "remainderxf3"
13403 [(use (match_operand:XF 0 "register_operand" ""))
13404 (use (match_operand:XF 1 "general_operand" ""))
13405 (use (match_operand:XF 2 "general_operand" ""))]
13406 "TARGET_USE_FANCY_MATH_387"
13408 rtx label = gen_label_rtx ();
13410 rtx op1 = gen_reg_rtx (XFmode);
13411 rtx op2 = gen_reg_rtx (XFmode);
13413 emit_move_insn (op2, operands[2]);
13414 emit_move_insn (op1, operands[1]);
13416 emit_label (label);
13417 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13418 ix86_emit_fp_unordered_jump (label);
13419 LABEL_NUSES (label) = 1;
13421 emit_move_insn (operands[0], op1);
13425 (define_expand "remainder<mode>3"
13426 [(use (match_operand:MODEF 0 "register_operand" ""))
13427 (use (match_operand:MODEF 1 "general_operand" ""))
13428 (use (match_operand:MODEF 2 "general_operand" ""))]
13429 "TARGET_USE_FANCY_MATH_387"
13431 rtx (*gen_truncxf) (rtx, rtx);
13433 rtx label = gen_label_rtx ();
13435 rtx op1 = gen_reg_rtx (XFmode);
13436 rtx op2 = gen_reg_rtx (XFmode);
13438 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13439 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13441 emit_label (label);
13443 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13444 ix86_emit_fp_unordered_jump (label);
13445 LABEL_NUSES (label) = 1;
13447 /* Truncate the result properly for strict SSE math. */
13448 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13449 && !TARGET_MIX_SSE_I387)
13450 gen_truncxf = gen_truncxf<mode>2;
13452 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13454 emit_insn (gen_truncxf (operands[0], op1));
13458 (define_insn "*sinxf2_i387"
13459 [(set (match_operand:XF 0 "register_operand" "=f")
13460 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13461 "TARGET_USE_FANCY_MATH_387
13462 && flag_unsafe_math_optimizations"
13464 [(set_attr "type" "fpspc")
13465 (set_attr "mode" "XF")])
13467 (define_insn "*sin_extend<mode>xf2_i387"
13468 [(set (match_operand:XF 0 "register_operand" "=f")
13469 (unspec:XF [(float_extend:XF
13470 (match_operand:MODEF 1 "register_operand" "0"))]
13472 "TARGET_USE_FANCY_MATH_387
13473 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13474 || TARGET_MIX_SSE_I387)
13475 && flag_unsafe_math_optimizations"
13477 [(set_attr "type" "fpspc")
13478 (set_attr "mode" "XF")])
13480 (define_insn "*cosxf2_i387"
13481 [(set (match_operand:XF 0 "register_operand" "=f")
13482 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13483 "TARGET_USE_FANCY_MATH_387
13484 && flag_unsafe_math_optimizations"
13486 [(set_attr "type" "fpspc")
13487 (set_attr "mode" "XF")])
13489 (define_insn "*cos_extend<mode>xf2_i387"
13490 [(set (match_operand:XF 0 "register_operand" "=f")
13491 (unspec:XF [(float_extend:XF
13492 (match_operand:MODEF 1 "register_operand" "0"))]
13494 "TARGET_USE_FANCY_MATH_387
13495 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13496 || TARGET_MIX_SSE_I387)
13497 && flag_unsafe_math_optimizations"
13499 [(set_attr "type" "fpspc")
13500 (set_attr "mode" "XF")])
13502 ;; When sincos pattern is defined, sin and cos builtin functions will be
13503 ;; expanded to sincos pattern with one of its outputs left unused.
13504 ;; CSE pass will figure out if two sincos patterns can be combined,
13505 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13506 ;; depending on the unused output.
13508 (define_insn "sincosxf3"
13509 [(set (match_operand:XF 0 "register_operand" "=f")
13510 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13511 UNSPEC_SINCOS_COS))
13512 (set (match_operand:XF 1 "register_operand" "=u")
13513 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13514 "TARGET_USE_FANCY_MATH_387
13515 && flag_unsafe_math_optimizations"
13517 [(set_attr "type" "fpspc")
13518 (set_attr "mode" "XF")])
13521 [(set (match_operand:XF 0 "register_operand" "")
13522 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13523 UNSPEC_SINCOS_COS))
13524 (set (match_operand:XF 1 "register_operand" "")
13525 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13526 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13527 && can_create_pseudo_p ()"
13528 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13531 [(set (match_operand:XF 0 "register_operand" "")
13532 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13533 UNSPEC_SINCOS_COS))
13534 (set (match_operand:XF 1 "register_operand" "")
13535 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13536 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13537 && can_create_pseudo_p ()"
13538 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13540 (define_insn "sincos_extend<mode>xf3_i387"
13541 [(set (match_operand:XF 0 "register_operand" "=f")
13542 (unspec:XF [(float_extend:XF
13543 (match_operand:MODEF 2 "register_operand" "0"))]
13544 UNSPEC_SINCOS_COS))
13545 (set (match_operand:XF 1 "register_operand" "=u")
13546 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13547 "TARGET_USE_FANCY_MATH_387
13548 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13549 || TARGET_MIX_SSE_I387)
13550 && flag_unsafe_math_optimizations"
13552 [(set_attr "type" "fpspc")
13553 (set_attr "mode" "XF")])
13556 [(set (match_operand:XF 0 "register_operand" "")
13557 (unspec:XF [(float_extend:XF
13558 (match_operand:MODEF 2 "register_operand" ""))]
13559 UNSPEC_SINCOS_COS))
13560 (set (match_operand:XF 1 "register_operand" "")
13561 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13562 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13563 && can_create_pseudo_p ()"
13564 [(set (match_dup 1)
13565 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13568 [(set (match_operand:XF 0 "register_operand" "")
13569 (unspec:XF [(float_extend:XF
13570 (match_operand:MODEF 2 "register_operand" ""))]
13571 UNSPEC_SINCOS_COS))
13572 (set (match_operand:XF 1 "register_operand" "")
13573 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13574 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13575 && can_create_pseudo_p ()"
13576 [(set (match_dup 0)
13577 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13579 (define_expand "sincos<mode>3"
13580 [(use (match_operand:MODEF 0 "register_operand" ""))
13581 (use (match_operand:MODEF 1 "register_operand" ""))
13582 (use (match_operand:MODEF 2 "register_operand" ""))]
13583 "TARGET_USE_FANCY_MATH_387
13584 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13585 || TARGET_MIX_SSE_I387)
13586 && flag_unsafe_math_optimizations"
13588 rtx op0 = gen_reg_rtx (XFmode);
13589 rtx op1 = gen_reg_rtx (XFmode);
13591 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13592 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13593 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13597 (define_insn "fptanxf4_i387"
13598 [(set (match_operand:XF 0 "register_operand" "=f")
13599 (match_operand:XF 3 "const_double_operand" "F"))
13600 (set (match_operand:XF 1 "register_operand" "=u")
13601 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13603 "TARGET_USE_FANCY_MATH_387
13604 && flag_unsafe_math_optimizations
13605 && standard_80387_constant_p (operands[3]) == 2"
13607 [(set_attr "type" "fpspc")
13608 (set_attr "mode" "XF")])
13610 (define_insn "fptan_extend<mode>xf4_i387"
13611 [(set (match_operand:MODEF 0 "register_operand" "=f")
13612 (match_operand:MODEF 3 "const_double_operand" "F"))
13613 (set (match_operand:XF 1 "register_operand" "=u")
13614 (unspec:XF [(float_extend:XF
13615 (match_operand:MODEF 2 "register_operand" "0"))]
13617 "TARGET_USE_FANCY_MATH_387
13618 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13619 || TARGET_MIX_SSE_I387)
13620 && flag_unsafe_math_optimizations
13621 && standard_80387_constant_p (operands[3]) == 2"
13623 [(set_attr "type" "fpspc")
13624 (set_attr "mode" "XF")])
13626 (define_expand "tanxf2"
13627 [(use (match_operand:XF 0 "register_operand" ""))
13628 (use (match_operand:XF 1 "register_operand" ""))]
13629 "TARGET_USE_FANCY_MATH_387
13630 && flag_unsafe_math_optimizations"
13632 rtx one = gen_reg_rtx (XFmode);
13633 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13635 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13639 (define_expand "tan<mode>2"
13640 [(use (match_operand:MODEF 0 "register_operand" ""))
13641 (use (match_operand:MODEF 1 "register_operand" ""))]
13642 "TARGET_USE_FANCY_MATH_387
13643 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13644 || TARGET_MIX_SSE_I387)
13645 && flag_unsafe_math_optimizations"
13647 rtx op0 = gen_reg_rtx (XFmode);
13649 rtx one = gen_reg_rtx (<MODE>mode);
13650 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13652 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13653 operands[1], op2));
13654 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13658 (define_insn "*fpatanxf3_i387"
13659 [(set (match_operand:XF 0 "register_operand" "=f")
13660 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13661 (match_operand:XF 2 "register_operand" "u")]
13663 (clobber (match_scratch:XF 3 "=2"))]
13664 "TARGET_USE_FANCY_MATH_387
13665 && flag_unsafe_math_optimizations"
13667 [(set_attr "type" "fpspc")
13668 (set_attr "mode" "XF")])
13670 (define_insn "fpatan_extend<mode>xf3_i387"
13671 [(set (match_operand:XF 0 "register_operand" "=f")
13672 (unspec:XF [(float_extend:XF
13673 (match_operand:MODEF 1 "register_operand" "0"))
13675 (match_operand:MODEF 2 "register_operand" "u"))]
13677 (clobber (match_scratch:XF 3 "=2"))]
13678 "TARGET_USE_FANCY_MATH_387
13679 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13680 || TARGET_MIX_SSE_I387)
13681 && flag_unsafe_math_optimizations"
13683 [(set_attr "type" "fpspc")
13684 (set_attr "mode" "XF")])
13686 (define_expand "atan2xf3"
13687 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13688 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13689 (match_operand:XF 1 "register_operand" "")]
13691 (clobber (match_scratch:XF 3 ""))])]
13692 "TARGET_USE_FANCY_MATH_387
13693 && flag_unsafe_math_optimizations")
13695 (define_expand "atan2<mode>3"
13696 [(use (match_operand:MODEF 0 "register_operand" ""))
13697 (use (match_operand:MODEF 1 "register_operand" ""))
13698 (use (match_operand:MODEF 2 "register_operand" ""))]
13699 "TARGET_USE_FANCY_MATH_387
13700 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13701 || TARGET_MIX_SSE_I387)
13702 && flag_unsafe_math_optimizations"
13704 rtx op0 = gen_reg_rtx (XFmode);
13706 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13707 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13711 (define_expand "atanxf2"
13712 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13713 (unspec:XF [(match_dup 2)
13714 (match_operand:XF 1 "register_operand" "")]
13716 (clobber (match_scratch:XF 3 ""))])]
13717 "TARGET_USE_FANCY_MATH_387
13718 && flag_unsafe_math_optimizations"
13720 operands[2] = gen_reg_rtx (XFmode);
13721 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13724 (define_expand "atan<mode>2"
13725 [(use (match_operand:MODEF 0 "register_operand" ""))
13726 (use (match_operand:MODEF 1 "register_operand" ""))]
13727 "TARGET_USE_FANCY_MATH_387
13728 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13729 || TARGET_MIX_SSE_I387)
13730 && flag_unsafe_math_optimizations"
13732 rtx op0 = gen_reg_rtx (XFmode);
13734 rtx op2 = gen_reg_rtx (<MODE>mode);
13735 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13737 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13738 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13742 (define_expand "asinxf2"
13743 [(set (match_dup 2)
13744 (mult:XF (match_operand:XF 1 "register_operand" "")
13746 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13747 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13748 (parallel [(set (match_operand:XF 0 "register_operand" "")
13749 (unspec:XF [(match_dup 5) (match_dup 1)]
13751 (clobber (match_scratch:XF 6 ""))])]
13752 "TARGET_USE_FANCY_MATH_387
13753 && flag_unsafe_math_optimizations"
13757 if (optimize_insn_for_size_p ())
13760 for (i = 2; i < 6; i++)
13761 operands[i] = gen_reg_rtx (XFmode);
13763 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13766 (define_expand "asin<mode>2"
13767 [(use (match_operand:MODEF 0 "register_operand" ""))
13768 (use (match_operand:MODEF 1 "general_operand" ""))]
13769 "TARGET_USE_FANCY_MATH_387
13770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13771 || TARGET_MIX_SSE_I387)
13772 && flag_unsafe_math_optimizations"
13774 rtx op0 = gen_reg_rtx (XFmode);
13775 rtx op1 = gen_reg_rtx (XFmode);
13777 if (optimize_insn_for_size_p ())
13780 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13781 emit_insn (gen_asinxf2 (op0, op1));
13782 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13786 (define_expand "acosxf2"
13787 [(set (match_dup 2)
13788 (mult:XF (match_operand:XF 1 "register_operand" "")
13790 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13791 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13792 (parallel [(set (match_operand:XF 0 "register_operand" "")
13793 (unspec:XF [(match_dup 1) (match_dup 5)]
13795 (clobber (match_scratch:XF 6 ""))])]
13796 "TARGET_USE_FANCY_MATH_387
13797 && flag_unsafe_math_optimizations"
13801 if (optimize_insn_for_size_p ())
13804 for (i = 2; i < 6; i++)
13805 operands[i] = gen_reg_rtx (XFmode);
13807 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13810 (define_expand "acos<mode>2"
13811 [(use (match_operand:MODEF 0 "register_operand" ""))
13812 (use (match_operand:MODEF 1 "general_operand" ""))]
13813 "TARGET_USE_FANCY_MATH_387
13814 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13815 || TARGET_MIX_SSE_I387)
13816 && flag_unsafe_math_optimizations"
13818 rtx op0 = gen_reg_rtx (XFmode);
13819 rtx op1 = gen_reg_rtx (XFmode);
13821 if (optimize_insn_for_size_p ())
13824 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13825 emit_insn (gen_acosxf2 (op0, op1));
13826 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13830 (define_insn "fyl2xxf3_i387"
13831 [(set (match_operand:XF 0 "register_operand" "=f")
13832 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13833 (match_operand:XF 2 "register_operand" "u")]
13835 (clobber (match_scratch:XF 3 "=2"))]
13836 "TARGET_USE_FANCY_MATH_387
13837 && flag_unsafe_math_optimizations"
13839 [(set_attr "type" "fpspc")
13840 (set_attr "mode" "XF")])
13842 (define_insn "fyl2x_extend<mode>xf3_i387"
13843 [(set (match_operand:XF 0 "register_operand" "=f")
13844 (unspec:XF [(float_extend:XF
13845 (match_operand:MODEF 1 "register_operand" "0"))
13846 (match_operand:XF 2 "register_operand" "u")]
13848 (clobber (match_scratch:XF 3 "=2"))]
13849 "TARGET_USE_FANCY_MATH_387
13850 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13851 || TARGET_MIX_SSE_I387)
13852 && flag_unsafe_math_optimizations"
13854 [(set_attr "type" "fpspc")
13855 (set_attr "mode" "XF")])
13857 (define_expand "logxf2"
13858 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13859 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13860 (match_dup 2)] UNSPEC_FYL2X))
13861 (clobber (match_scratch:XF 3 ""))])]
13862 "TARGET_USE_FANCY_MATH_387
13863 && flag_unsafe_math_optimizations"
13865 operands[2] = gen_reg_rtx (XFmode);
13866 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13869 (define_expand "log<mode>2"
13870 [(use (match_operand:MODEF 0 "register_operand" ""))
13871 (use (match_operand:MODEF 1 "register_operand" ""))]
13872 "TARGET_USE_FANCY_MATH_387
13873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13874 || TARGET_MIX_SSE_I387)
13875 && flag_unsafe_math_optimizations"
13877 rtx op0 = gen_reg_rtx (XFmode);
13879 rtx op2 = gen_reg_rtx (XFmode);
13880 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13882 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13883 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13887 (define_expand "log10xf2"
13888 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13889 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13890 (match_dup 2)] UNSPEC_FYL2X))
13891 (clobber (match_scratch:XF 3 ""))])]
13892 "TARGET_USE_FANCY_MATH_387
13893 && flag_unsafe_math_optimizations"
13895 operands[2] = gen_reg_rtx (XFmode);
13896 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13899 (define_expand "log10<mode>2"
13900 [(use (match_operand:MODEF 0 "register_operand" ""))
13901 (use (match_operand:MODEF 1 "register_operand" ""))]
13902 "TARGET_USE_FANCY_MATH_387
13903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13904 || TARGET_MIX_SSE_I387)
13905 && flag_unsafe_math_optimizations"
13907 rtx op0 = gen_reg_rtx (XFmode);
13909 rtx op2 = gen_reg_rtx (XFmode);
13910 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13912 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13913 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13917 (define_expand "log2xf2"
13918 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13919 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13920 (match_dup 2)] UNSPEC_FYL2X))
13921 (clobber (match_scratch:XF 3 ""))])]
13922 "TARGET_USE_FANCY_MATH_387
13923 && flag_unsafe_math_optimizations"
13925 operands[2] = gen_reg_rtx (XFmode);
13926 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13929 (define_expand "log2<mode>2"
13930 [(use (match_operand:MODEF 0 "register_operand" ""))
13931 (use (match_operand:MODEF 1 "register_operand" ""))]
13932 "TARGET_USE_FANCY_MATH_387
13933 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13934 || TARGET_MIX_SSE_I387)
13935 && flag_unsafe_math_optimizations"
13937 rtx op0 = gen_reg_rtx (XFmode);
13939 rtx op2 = gen_reg_rtx (XFmode);
13940 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13942 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13943 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13947 (define_insn "fyl2xp1xf3_i387"
13948 [(set (match_operand:XF 0 "register_operand" "=f")
13949 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13950 (match_operand:XF 2 "register_operand" "u")]
13952 (clobber (match_scratch:XF 3 "=2"))]
13953 "TARGET_USE_FANCY_MATH_387
13954 && flag_unsafe_math_optimizations"
13956 [(set_attr "type" "fpspc")
13957 (set_attr "mode" "XF")])
13959 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13960 [(set (match_operand:XF 0 "register_operand" "=f")
13961 (unspec:XF [(float_extend:XF
13962 (match_operand:MODEF 1 "register_operand" "0"))
13963 (match_operand:XF 2 "register_operand" "u")]
13965 (clobber (match_scratch:XF 3 "=2"))]
13966 "TARGET_USE_FANCY_MATH_387
13967 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13968 || TARGET_MIX_SSE_I387)
13969 && flag_unsafe_math_optimizations"
13971 [(set_attr "type" "fpspc")
13972 (set_attr "mode" "XF")])
13974 (define_expand "log1pxf2"
13975 [(use (match_operand:XF 0 "register_operand" ""))
13976 (use (match_operand:XF 1 "register_operand" ""))]
13977 "TARGET_USE_FANCY_MATH_387
13978 && flag_unsafe_math_optimizations"
13980 if (optimize_insn_for_size_p ())
13983 ix86_emit_i387_log1p (operands[0], operands[1]);
13987 (define_expand "log1p<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"
13997 if (optimize_insn_for_size_p ())
14000 op0 = gen_reg_rtx (XFmode);
14002 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14004 ix86_emit_i387_log1p (op0, operands[1]);
14005 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14009 (define_insn "fxtractxf3_i387"
14010 [(set (match_operand:XF 0 "register_operand" "=f")
14011 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14012 UNSPEC_XTRACT_FRACT))
14013 (set (match_operand:XF 1 "register_operand" "=u")
14014 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14015 "TARGET_USE_FANCY_MATH_387
14016 && flag_unsafe_math_optimizations"
14018 [(set_attr "type" "fpspc")
14019 (set_attr "mode" "XF")])
14021 (define_insn "fxtract_extend<mode>xf3_i387"
14022 [(set (match_operand:XF 0 "register_operand" "=f")
14023 (unspec:XF [(float_extend:XF
14024 (match_operand:MODEF 2 "register_operand" "0"))]
14025 UNSPEC_XTRACT_FRACT))
14026 (set (match_operand:XF 1 "register_operand" "=u")
14027 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14028 "TARGET_USE_FANCY_MATH_387
14029 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14030 || TARGET_MIX_SSE_I387)
14031 && flag_unsafe_math_optimizations"
14033 [(set_attr "type" "fpspc")
14034 (set_attr "mode" "XF")])
14036 (define_expand "logbxf2"
14037 [(parallel [(set (match_dup 2)
14038 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14039 UNSPEC_XTRACT_FRACT))
14040 (set (match_operand:XF 0 "register_operand" "")
14041 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14042 "TARGET_USE_FANCY_MATH_387
14043 && flag_unsafe_math_optimizations"
14044 "operands[2] = gen_reg_rtx (XFmode);")
14046 (define_expand "logb<mode>2"
14047 [(use (match_operand:MODEF 0 "register_operand" ""))
14048 (use (match_operand:MODEF 1 "register_operand" ""))]
14049 "TARGET_USE_FANCY_MATH_387
14050 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14051 || TARGET_MIX_SSE_I387)
14052 && flag_unsafe_math_optimizations"
14054 rtx op0 = gen_reg_rtx (XFmode);
14055 rtx op1 = gen_reg_rtx (XFmode);
14057 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14058 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14062 (define_expand "ilogbxf2"
14063 [(use (match_operand:SI 0 "register_operand" ""))
14064 (use (match_operand:XF 1 "register_operand" ""))]
14065 "TARGET_USE_FANCY_MATH_387
14066 && flag_unsafe_math_optimizations"
14070 if (optimize_insn_for_size_p ())
14073 op0 = gen_reg_rtx (XFmode);
14074 op1 = gen_reg_rtx (XFmode);
14076 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14077 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14081 (define_expand "ilogb<mode>2"
14082 [(use (match_operand:SI 0 "register_operand" ""))
14083 (use (match_operand:MODEF 1 "register_operand" ""))]
14084 "TARGET_USE_FANCY_MATH_387
14085 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14086 || TARGET_MIX_SSE_I387)
14087 && flag_unsafe_math_optimizations"
14091 if (optimize_insn_for_size_p ())
14094 op0 = gen_reg_rtx (XFmode);
14095 op1 = gen_reg_rtx (XFmode);
14097 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14098 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14102 (define_insn "*f2xm1xf2_i387"
14103 [(set (match_operand:XF 0 "register_operand" "=f")
14104 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14106 "TARGET_USE_FANCY_MATH_387
14107 && flag_unsafe_math_optimizations"
14109 [(set_attr "type" "fpspc")
14110 (set_attr "mode" "XF")])
14112 (define_insn "*fscalexf4_i387"
14113 [(set (match_operand:XF 0 "register_operand" "=f")
14114 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14115 (match_operand:XF 3 "register_operand" "1")]
14116 UNSPEC_FSCALE_FRACT))
14117 (set (match_operand:XF 1 "register_operand" "=u")
14118 (unspec:XF [(match_dup 2) (match_dup 3)]
14119 UNSPEC_FSCALE_EXP))]
14120 "TARGET_USE_FANCY_MATH_387
14121 && flag_unsafe_math_optimizations"
14123 [(set_attr "type" "fpspc")
14124 (set_attr "mode" "XF")])
14126 (define_expand "expNcorexf3"
14127 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14128 (match_operand:XF 2 "register_operand" "")))
14129 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14130 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14131 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14132 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14133 (parallel [(set (match_operand:XF 0 "register_operand" "")
14134 (unspec:XF [(match_dup 8) (match_dup 4)]
14135 UNSPEC_FSCALE_FRACT))
14137 (unspec:XF [(match_dup 8) (match_dup 4)]
14138 UNSPEC_FSCALE_EXP))])]
14139 "TARGET_USE_FANCY_MATH_387
14140 && flag_unsafe_math_optimizations"
14144 if (optimize_insn_for_size_p ())
14147 for (i = 3; i < 10; i++)
14148 operands[i] = gen_reg_rtx (XFmode);
14150 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14153 (define_expand "expxf2"
14154 [(use (match_operand:XF 0 "register_operand" ""))
14155 (use (match_operand:XF 1 "register_operand" ""))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && flag_unsafe_math_optimizations"
14161 if (optimize_insn_for_size_p ())
14164 op2 = gen_reg_rtx (XFmode);
14165 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14167 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14171 (define_expand "exp<mode>2"
14172 [(use (match_operand:MODEF 0 "register_operand" ""))
14173 (use (match_operand:MODEF 1 "general_operand" ""))]
14174 "TARGET_USE_FANCY_MATH_387
14175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14176 || TARGET_MIX_SSE_I387)
14177 && flag_unsafe_math_optimizations"
14181 if (optimize_insn_for_size_p ())
14184 op0 = gen_reg_rtx (XFmode);
14185 op1 = gen_reg_rtx (XFmode);
14187 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14188 emit_insn (gen_expxf2 (op0, op1));
14189 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14193 (define_expand "exp10xf2"
14194 [(use (match_operand:XF 0 "register_operand" ""))
14195 (use (match_operand:XF 1 "register_operand" ""))]
14196 "TARGET_USE_FANCY_MATH_387
14197 && flag_unsafe_math_optimizations"
14201 if (optimize_insn_for_size_p ())
14204 op2 = gen_reg_rtx (XFmode);
14205 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14207 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14211 (define_expand "exp10<mode>2"
14212 [(use (match_operand:MODEF 0 "register_operand" ""))
14213 (use (match_operand:MODEF 1 "general_operand" ""))]
14214 "TARGET_USE_FANCY_MATH_387
14215 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14216 || TARGET_MIX_SSE_I387)
14217 && flag_unsafe_math_optimizations"
14221 if (optimize_insn_for_size_p ())
14224 op0 = gen_reg_rtx (XFmode);
14225 op1 = gen_reg_rtx (XFmode);
14227 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14228 emit_insn (gen_exp10xf2 (op0, op1));
14229 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14233 (define_expand "exp2xf2"
14234 [(use (match_operand:XF 0 "register_operand" ""))
14235 (use (match_operand:XF 1 "register_operand" ""))]
14236 "TARGET_USE_FANCY_MATH_387
14237 && flag_unsafe_math_optimizations"
14241 if (optimize_insn_for_size_p ())
14244 op2 = gen_reg_rtx (XFmode);
14245 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14247 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14251 (define_expand "exp2<mode>2"
14252 [(use (match_operand:MODEF 0 "register_operand" ""))
14253 (use (match_operand:MODEF 1 "general_operand" ""))]
14254 "TARGET_USE_FANCY_MATH_387
14255 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14256 || TARGET_MIX_SSE_I387)
14257 && flag_unsafe_math_optimizations"
14261 if (optimize_insn_for_size_p ())
14264 op0 = gen_reg_rtx (XFmode);
14265 op1 = gen_reg_rtx (XFmode);
14267 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14268 emit_insn (gen_exp2xf2 (op0, op1));
14269 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14273 (define_expand "expm1xf2"
14274 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14276 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14277 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14278 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14279 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14280 (parallel [(set (match_dup 7)
14281 (unspec:XF [(match_dup 6) (match_dup 4)]
14282 UNSPEC_FSCALE_FRACT))
14284 (unspec:XF [(match_dup 6) (match_dup 4)]
14285 UNSPEC_FSCALE_EXP))])
14286 (parallel [(set (match_dup 10)
14287 (unspec:XF [(match_dup 9) (match_dup 8)]
14288 UNSPEC_FSCALE_FRACT))
14289 (set (match_dup 11)
14290 (unspec:XF [(match_dup 9) (match_dup 8)]
14291 UNSPEC_FSCALE_EXP))])
14292 (set (match_dup 12) (minus:XF (match_dup 10)
14293 (float_extend:XF (match_dup 13))))
14294 (set (match_operand:XF 0 "register_operand" "")
14295 (plus:XF (match_dup 12) (match_dup 7)))]
14296 "TARGET_USE_FANCY_MATH_387
14297 && flag_unsafe_math_optimizations"
14301 if (optimize_insn_for_size_p ())
14304 for (i = 2; i < 13; i++)
14305 operands[i] = gen_reg_rtx (XFmode);
14308 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14310 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14313 (define_expand "expm1<mode>2"
14314 [(use (match_operand:MODEF 0 "register_operand" ""))
14315 (use (match_operand:MODEF 1 "general_operand" ""))]
14316 "TARGET_USE_FANCY_MATH_387
14317 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14318 || TARGET_MIX_SSE_I387)
14319 && flag_unsafe_math_optimizations"
14323 if (optimize_insn_for_size_p ())
14326 op0 = gen_reg_rtx (XFmode);
14327 op1 = gen_reg_rtx (XFmode);
14329 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14330 emit_insn (gen_expm1xf2 (op0, op1));
14331 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14335 (define_expand "ldexpxf3"
14336 [(set (match_dup 3)
14337 (float:XF (match_operand:SI 2 "register_operand" "")))
14338 (parallel [(set (match_operand:XF 0 " register_operand" "")
14339 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14341 UNSPEC_FSCALE_FRACT))
14343 (unspec:XF [(match_dup 1) (match_dup 3)]
14344 UNSPEC_FSCALE_EXP))])]
14345 "TARGET_USE_FANCY_MATH_387
14346 && flag_unsafe_math_optimizations"
14348 if (optimize_insn_for_size_p ())
14351 operands[3] = gen_reg_rtx (XFmode);
14352 operands[4] = gen_reg_rtx (XFmode);
14355 (define_expand "ldexp<mode>3"
14356 [(use (match_operand:MODEF 0 "register_operand" ""))
14357 (use (match_operand:MODEF 1 "general_operand" ""))
14358 (use (match_operand:SI 2 "register_operand" ""))]
14359 "TARGET_USE_FANCY_MATH_387
14360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14361 || TARGET_MIX_SSE_I387)
14362 && flag_unsafe_math_optimizations"
14366 if (optimize_insn_for_size_p ())
14369 op0 = gen_reg_rtx (XFmode);
14370 op1 = gen_reg_rtx (XFmode);
14372 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14373 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14374 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14378 (define_expand "scalbxf3"
14379 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14380 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14381 (match_operand:XF 2 "register_operand" "")]
14382 UNSPEC_FSCALE_FRACT))
14384 (unspec:XF [(match_dup 1) (match_dup 2)]
14385 UNSPEC_FSCALE_EXP))])]
14386 "TARGET_USE_FANCY_MATH_387
14387 && flag_unsafe_math_optimizations"
14389 if (optimize_insn_for_size_p ())
14392 operands[3] = gen_reg_rtx (XFmode);
14395 (define_expand "scalb<mode>3"
14396 [(use (match_operand:MODEF 0 "register_operand" ""))
14397 (use (match_operand:MODEF 1 "general_operand" ""))
14398 (use (match_operand:MODEF 2 "general_operand" ""))]
14399 "TARGET_USE_FANCY_MATH_387
14400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14401 || TARGET_MIX_SSE_I387)
14402 && flag_unsafe_math_optimizations"
14406 if (optimize_insn_for_size_p ())
14409 op0 = gen_reg_rtx (XFmode);
14410 op1 = gen_reg_rtx (XFmode);
14411 op2 = gen_reg_rtx (XFmode);
14413 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14414 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14415 emit_insn (gen_scalbxf3 (op0, op1, op2));
14416 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14420 (define_expand "significandxf2"
14421 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14422 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14423 UNSPEC_XTRACT_FRACT))
14425 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14426 "TARGET_USE_FANCY_MATH_387
14427 && flag_unsafe_math_optimizations"
14428 "operands[2] = gen_reg_rtx (XFmode);")
14430 (define_expand "significand<mode>2"
14431 [(use (match_operand:MODEF 0 "register_operand" ""))
14432 (use (match_operand:MODEF 1 "register_operand" ""))]
14433 "TARGET_USE_FANCY_MATH_387
14434 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14435 || TARGET_MIX_SSE_I387)
14436 && flag_unsafe_math_optimizations"
14438 rtx op0 = gen_reg_rtx (XFmode);
14439 rtx op1 = gen_reg_rtx (XFmode);
14441 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14442 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14447 (define_insn "sse4_1_round<mode>2"
14448 [(set (match_operand:MODEF 0 "register_operand" "=x")
14449 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14450 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14453 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14454 [(set_attr "type" "ssecvt")
14455 (set_attr "prefix_extra" "1")
14456 (set_attr "prefix" "maybe_vex")
14457 (set_attr "mode" "<MODE>")])
14459 (define_insn "rintxf2"
14460 [(set (match_operand:XF 0 "register_operand" "=f")
14461 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14463 "TARGET_USE_FANCY_MATH_387
14464 && flag_unsafe_math_optimizations"
14466 [(set_attr "type" "fpspc")
14467 (set_attr "mode" "XF")])
14469 (define_expand "rint<mode>2"
14470 [(use (match_operand:MODEF 0 "register_operand" ""))
14471 (use (match_operand:MODEF 1 "register_operand" ""))]
14472 "(TARGET_USE_FANCY_MATH_387
14473 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14474 || TARGET_MIX_SSE_I387)
14475 && flag_unsafe_math_optimizations)
14476 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14477 && !flag_trapping_math)"
14479 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14480 && !flag_trapping_math)
14482 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14485 emit_insn (gen_sse4_1_round<mode>2
14486 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14488 ix86_expand_rint (operand0, operand1);
14492 rtx op0 = gen_reg_rtx (XFmode);
14493 rtx op1 = gen_reg_rtx (XFmode);
14495 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14496 emit_insn (gen_rintxf2 (op0, op1));
14498 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14503 (define_expand "round<mode>2"
14504 [(match_operand:MODEF 0 "register_operand" "")
14505 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14506 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14507 && !flag_trapping_math && !flag_rounding_math"
14509 if (optimize_insn_for_size_p ())
14511 if (TARGET_64BIT || (<MODE>mode != DFmode))
14512 ix86_expand_round (operand0, operand1);
14514 ix86_expand_rounddf_32 (operand0, operand1);
14518 (define_insn_and_split "*fistdi2_1"
14519 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14520 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14522 "TARGET_USE_FANCY_MATH_387
14523 && can_create_pseudo_p ()"
14528 if (memory_operand (operands[0], VOIDmode))
14529 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14532 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14533 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14538 [(set_attr "type" "fpspc")
14539 (set_attr "mode" "DI")])
14541 (define_insn "fistdi2"
14542 [(set (match_operand:DI 0 "memory_operand" "=m")
14543 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14545 (clobber (match_scratch:XF 2 "=&1f"))]
14546 "TARGET_USE_FANCY_MATH_387"
14547 "* return output_fix_trunc (insn, operands, 0);"
14548 [(set_attr "type" "fpspc")
14549 (set_attr "mode" "DI")])
14551 (define_insn "fistdi2_with_temp"
14552 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14553 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14555 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14556 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14557 "TARGET_USE_FANCY_MATH_387"
14559 [(set_attr "type" "fpspc")
14560 (set_attr "mode" "DI")])
14563 [(set (match_operand:DI 0 "register_operand" "")
14564 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14566 (clobber (match_operand:DI 2 "memory_operand" ""))
14567 (clobber (match_scratch 3 ""))]
14569 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14570 (clobber (match_dup 3))])
14571 (set (match_dup 0) (match_dup 2))])
14574 [(set (match_operand:DI 0 "memory_operand" "")
14575 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14577 (clobber (match_operand:DI 2 "memory_operand" ""))
14578 (clobber (match_scratch 3 ""))]
14580 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14581 (clobber (match_dup 3))])])
14583 (define_insn_and_split "*fist<mode>2_1"
14584 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14585 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14587 "TARGET_USE_FANCY_MATH_387
14588 && can_create_pseudo_p ()"
14593 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14594 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14598 [(set_attr "type" "fpspc")
14599 (set_attr "mode" "<MODE>")])
14601 (define_insn "fist<mode>2"
14602 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14603 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14605 "TARGET_USE_FANCY_MATH_387"
14606 "* return output_fix_trunc (insn, operands, 0);"
14607 [(set_attr "type" "fpspc")
14608 (set_attr "mode" "<MODE>")])
14610 (define_insn "fist<mode>2_with_temp"
14611 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14612 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14614 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14615 "TARGET_USE_FANCY_MATH_387"
14617 [(set_attr "type" "fpspc")
14618 (set_attr "mode" "<MODE>")])
14621 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14622 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14624 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14626 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14627 (set (match_dup 0) (match_dup 2))])
14630 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14631 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14633 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14635 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14637 (define_expand "lrintxf<mode>2"
14638 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14639 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14641 "TARGET_USE_FANCY_MATH_387")
14643 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14644 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14645 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14646 UNSPEC_FIX_NOTRUNC))]
14647 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14648 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14650 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14651 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14652 (match_operand:MODEF 1 "register_operand" "")]
14653 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14654 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14655 && !flag_trapping_math && !flag_rounding_math"
14657 if (optimize_insn_for_size_p ())
14659 ix86_expand_lround (operand0, operand1);
14663 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14664 (define_insn_and_split "frndintxf2_floor"
14665 [(set (match_operand:XF 0 "register_operand" "")
14666 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14667 UNSPEC_FRNDINT_FLOOR))
14668 (clobber (reg:CC FLAGS_REG))]
14669 "TARGET_USE_FANCY_MATH_387
14670 && flag_unsafe_math_optimizations
14671 && can_create_pseudo_p ()"
14676 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14678 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14679 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14681 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14682 operands[2], operands[3]));
14685 [(set_attr "type" "frndint")
14686 (set_attr "i387_cw" "floor")
14687 (set_attr "mode" "XF")])
14689 (define_insn "frndintxf2_floor_i387"
14690 [(set (match_operand:XF 0 "register_operand" "=f")
14691 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14692 UNSPEC_FRNDINT_FLOOR))
14693 (use (match_operand:HI 2 "memory_operand" "m"))
14694 (use (match_operand:HI 3 "memory_operand" "m"))]
14695 "TARGET_USE_FANCY_MATH_387
14696 && flag_unsafe_math_optimizations"
14697 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14698 [(set_attr "type" "frndint")
14699 (set_attr "i387_cw" "floor")
14700 (set_attr "mode" "XF")])
14702 (define_expand "floorxf2"
14703 [(use (match_operand:XF 0 "register_operand" ""))
14704 (use (match_operand:XF 1 "register_operand" ""))]
14705 "TARGET_USE_FANCY_MATH_387
14706 && flag_unsafe_math_optimizations"
14708 if (optimize_insn_for_size_p ())
14710 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14714 (define_expand "floor<mode>2"
14715 [(use (match_operand:MODEF 0 "register_operand" ""))
14716 (use (match_operand:MODEF 1 "register_operand" ""))]
14717 "(TARGET_USE_FANCY_MATH_387
14718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14719 || TARGET_MIX_SSE_I387)
14720 && flag_unsafe_math_optimizations)
14721 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14722 && !flag_trapping_math)"
14724 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14725 && !flag_trapping_math
14726 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14728 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14731 emit_insn (gen_sse4_1_round<mode>2
14732 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14733 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14734 ix86_expand_floorceil (operand0, operand1, true);
14736 ix86_expand_floorceildf_32 (operand0, operand1, true);
14742 if (optimize_insn_for_size_p ())
14745 op0 = gen_reg_rtx (XFmode);
14746 op1 = gen_reg_rtx (XFmode);
14747 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14748 emit_insn (gen_frndintxf2_floor (op0, op1));
14750 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14755 (define_insn_and_split "*fist<mode>2_floor_1"
14756 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14757 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14758 UNSPEC_FIST_FLOOR))
14759 (clobber (reg:CC FLAGS_REG))]
14760 "TARGET_USE_FANCY_MATH_387
14761 && flag_unsafe_math_optimizations
14762 && can_create_pseudo_p ()"
14767 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14769 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14770 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14771 if (memory_operand (operands[0], VOIDmode))
14772 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14773 operands[2], operands[3]));
14776 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14777 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14778 operands[2], operands[3],
14783 [(set_attr "type" "fistp")
14784 (set_attr "i387_cw" "floor")
14785 (set_attr "mode" "<MODE>")])
14787 (define_insn "fistdi2_floor"
14788 [(set (match_operand:DI 0 "memory_operand" "=m")
14789 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14790 UNSPEC_FIST_FLOOR))
14791 (use (match_operand:HI 2 "memory_operand" "m"))
14792 (use (match_operand:HI 3 "memory_operand" "m"))
14793 (clobber (match_scratch:XF 4 "=&1f"))]
14794 "TARGET_USE_FANCY_MATH_387
14795 && flag_unsafe_math_optimizations"
14796 "* return output_fix_trunc (insn, operands, 0);"
14797 [(set_attr "type" "fistp")
14798 (set_attr "i387_cw" "floor")
14799 (set_attr "mode" "DI")])
14801 (define_insn "fistdi2_floor_with_temp"
14802 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14803 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14804 UNSPEC_FIST_FLOOR))
14805 (use (match_operand:HI 2 "memory_operand" "m,m"))
14806 (use (match_operand:HI 3 "memory_operand" "m,m"))
14807 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14808 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14809 "TARGET_USE_FANCY_MATH_387
14810 && flag_unsafe_math_optimizations"
14812 [(set_attr "type" "fistp")
14813 (set_attr "i387_cw" "floor")
14814 (set_attr "mode" "DI")])
14817 [(set (match_operand:DI 0 "register_operand" "")
14818 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14819 UNSPEC_FIST_FLOOR))
14820 (use (match_operand:HI 2 "memory_operand" ""))
14821 (use (match_operand:HI 3 "memory_operand" ""))
14822 (clobber (match_operand:DI 4 "memory_operand" ""))
14823 (clobber (match_scratch 5 ""))]
14825 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14826 (use (match_dup 2))
14827 (use (match_dup 3))
14828 (clobber (match_dup 5))])
14829 (set (match_dup 0) (match_dup 4))])
14832 [(set (match_operand:DI 0 "memory_operand" "")
14833 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14834 UNSPEC_FIST_FLOOR))
14835 (use (match_operand:HI 2 "memory_operand" ""))
14836 (use (match_operand:HI 3 "memory_operand" ""))
14837 (clobber (match_operand:DI 4 "memory_operand" ""))
14838 (clobber (match_scratch 5 ""))]
14840 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14841 (use (match_dup 2))
14842 (use (match_dup 3))
14843 (clobber (match_dup 5))])])
14845 (define_insn "fist<mode>2_floor"
14846 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14847 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14848 UNSPEC_FIST_FLOOR))
14849 (use (match_operand:HI 2 "memory_operand" "m"))
14850 (use (match_operand:HI 3 "memory_operand" "m"))]
14851 "TARGET_USE_FANCY_MATH_387
14852 && flag_unsafe_math_optimizations"
14853 "* return output_fix_trunc (insn, operands, 0);"
14854 [(set_attr "type" "fistp")
14855 (set_attr "i387_cw" "floor")
14856 (set_attr "mode" "<MODE>")])
14858 (define_insn "fist<mode>2_floor_with_temp"
14859 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14860 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14861 UNSPEC_FIST_FLOOR))
14862 (use (match_operand:HI 2 "memory_operand" "m,m"))
14863 (use (match_operand:HI 3 "memory_operand" "m,m"))
14864 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14865 "TARGET_USE_FANCY_MATH_387
14866 && flag_unsafe_math_optimizations"
14868 [(set_attr "type" "fistp")
14869 (set_attr "i387_cw" "floor")
14870 (set_attr "mode" "<MODE>")])
14873 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14874 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14875 UNSPEC_FIST_FLOOR))
14876 (use (match_operand:HI 2 "memory_operand" ""))
14877 (use (match_operand:HI 3 "memory_operand" ""))
14878 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14880 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14881 UNSPEC_FIST_FLOOR))
14882 (use (match_dup 2))
14883 (use (match_dup 3))])
14884 (set (match_dup 0) (match_dup 4))])
14887 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14888 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14889 UNSPEC_FIST_FLOOR))
14890 (use (match_operand:HI 2 "memory_operand" ""))
14891 (use (match_operand:HI 3 "memory_operand" ""))
14892 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14894 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14895 UNSPEC_FIST_FLOOR))
14896 (use (match_dup 2))
14897 (use (match_dup 3))])])
14899 (define_expand "lfloorxf<mode>2"
14900 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14901 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14902 UNSPEC_FIST_FLOOR))
14903 (clobber (reg:CC FLAGS_REG))])]
14904 "TARGET_USE_FANCY_MATH_387
14905 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14906 && flag_unsafe_math_optimizations")
14908 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14909 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14910 (match_operand:MODEF 1 "register_operand" "")]
14911 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14912 && !flag_trapping_math"
14914 if (TARGET_64BIT && optimize_insn_for_size_p ())
14916 ix86_expand_lfloorceil (operand0, operand1, true);
14920 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14921 (define_insn_and_split "frndintxf2_ceil"
14922 [(set (match_operand:XF 0 "register_operand" "")
14923 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14924 UNSPEC_FRNDINT_CEIL))
14925 (clobber (reg:CC FLAGS_REG))]
14926 "TARGET_USE_FANCY_MATH_387
14927 && flag_unsafe_math_optimizations
14928 && can_create_pseudo_p ()"
14933 ix86_optimize_mode_switching[I387_CEIL] = 1;
14935 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14936 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14938 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14939 operands[2], operands[3]));
14942 [(set_attr "type" "frndint")
14943 (set_attr "i387_cw" "ceil")
14944 (set_attr "mode" "XF")])
14946 (define_insn "frndintxf2_ceil_i387"
14947 [(set (match_operand:XF 0 "register_operand" "=f")
14948 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14949 UNSPEC_FRNDINT_CEIL))
14950 (use (match_operand:HI 2 "memory_operand" "m"))
14951 (use (match_operand:HI 3 "memory_operand" "m"))]
14952 "TARGET_USE_FANCY_MATH_387
14953 && flag_unsafe_math_optimizations"
14954 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14955 [(set_attr "type" "frndint")
14956 (set_attr "i387_cw" "ceil")
14957 (set_attr "mode" "XF")])
14959 (define_expand "ceilxf2"
14960 [(use (match_operand:XF 0 "register_operand" ""))
14961 (use (match_operand:XF 1 "register_operand" ""))]
14962 "TARGET_USE_FANCY_MATH_387
14963 && flag_unsafe_math_optimizations"
14965 if (optimize_insn_for_size_p ())
14967 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14971 (define_expand "ceil<mode>2"
14972 [(use (match_operand:MODEF 0 "register_operand" ""))
14973 (use (match_operand:MODEF 1 "register_operand" ""))]
14974 "(TARGET_USE_FANCY_MATH_387
14975 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14976 || TARGET_MIX_SSE_I387)
14977 && flag_unsafe_math_optimizations)
14978 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14979 && !flag_trapping_math)"
14981 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14982 && !flag_trapping_math
14983 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14986 emit_insn (gen_sse4_1_round<mode>2
14987 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14988 else if (optimize_insn_for_size_p ())
14990 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14991 ix86_expand_floorceil (operand0, operand1, false);
14993 ix86_expand_floorceildf_32 (operand0, operand1, false);
14999 if (optimize_insn_for_size_p ())
15002 op0 = gen_reg_rtx (XFmode);
15003 op1 = gen_reg_rtx (XFmode);
15004 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15005 emit_insn (gen_frndintxf2_ceil (op0, op1));
15007 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15012 (define_insn_and_split "*fist<mode>2_ceil_1"
15013 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15014 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15016 (clobber (reg:CC FLAGS_REG))]
15017 "TARGET_USE_FANCY_MATH_387
15018 && flag_unsafe_math_optimizations
15019 && can_create_pseudo_p ()"
15024 ix86_optimize_mode_switching[I387_CEIL] = 1;
15026 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15027 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15028 if (memory_operand (operands[0], VOIDmode))
15029 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15030 operands[2], operands[3]));
15033 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15034 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15035 operands[2], operands[3],
15040 [(set_attr "type" "fistp")
15041 (set_attr "i387_cw" "ceil")
15042 (set_attr "mode" "<MODE>")])
15044 (define_insn "fistdi2_ceil"
15045 [(set (match_operand:DI 0 "memory_operand" "=m")
15046 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15048 (use (match_operand:HI 2 "memory_operand" "m"))
15049 (use (match_operand:HI 3 "memory_operand" "m"))
15050 (clobber (match_scratch:XF 4 "=&1f"))]
15051 "TARGET_USE_FANCY_MATH_387
15052 && flag_unsafe_math_optimizations"
15053 "* return output_fix_trunc (insn, operands, 0);"
15054 [(set_attr "type" "fistp")
15055 (set_attr "i387_cw" "ceil")
15056 (set_attr "mode" "DI")])
15058 (define_insn "fistdi2_ceil_with_temp"
15059 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15060 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15062 (use (match_operand:HI 2 "memory_operand" "m,m"))
15063 (use (match_operand:HI 3 "memory_operand" "m,m"))
15064 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15065 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15066 "TARGET_USE_FANCY_MATH_387
15067 && flag_unsafe_math_optimizations"
15069 [(set_attr "type" "fistp")
15070 (set_attr "i387_cw" "ceil")
15071 (set_attr "mode" "DI")])
15074 [(set (match_operand:DI 0 "register_operand" "")
15075 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15077 (use (match_operand:HI 2 "memory_operand" ""))
15078 (use (match_operand:HI 3 "memory_operand" ""))
15079 (clobber (match_operand:DI 4 "memory_operand" ""))
15080 (clobber (match_scratch 5 ""))]
15082 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15083 (use (match_dup 2))
15084 (use (match_dup 3))
15085 (clobber (match_dup 5))])
15086 (set (match_dup 0) (match_dup 4))])
15089 [(set (match_operand:DI 0 "memory_operand" "")
15090 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15092 (use (match_operand:HI 2 "memory_operand" ""))
15093 (use (match_operand:HI 3 "memory_operand" ""))
15094 (clobber (match_operand:DI 4 "memory_operand" ""))
15095 (clobber (match_scratch 5 ""))]
15097 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15098 (use (match_dup 2))
15099 (use (match_dup 3))
15100 (clobber (match_dup 5))])])
15102 (define_insn "fist<mode>2_ceil"
15103 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15104 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15106 (use (match_operand:HI 2 "memory_operand" "m"))
15107 (use (match_operand:HI 3 "memory_operand" "m"))]
15108 "TARGET_USE_FANCY_MATH_387
15109 && flag_unsafe_math_optimizations"
15110 "* return output_fix_trunc (insn, operands, 0);"
15111 [(set_attr "type" "fistp")
15112 (set_attr "i387_cw" "ceil")
15113 (set_attr "mode" "<MODE>")])
15115 (define_insn "fist<mode>2_ceil_with_temp"
15116 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15117 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15119 (use (match_operand:HI 2 "memory_operand" "m,m"))
15120 (use (match_operand:HI 3 "memory_operand" "m,m"))
15121 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15122 "TARGET_USE_FANCY_MATH_387
15123 && flag_unsafe_math_optimizations"
15125 [(set_attr "type" "fistp")
15126 (set_attr "i387_cw" "ceil")
15127 (set_attr "mode" "<MODE>")])
15130 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15131 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15133 (use (match_operand:HI 2 "memory_operand" ""))
15134 (use (match_operand:HI 3 "memory_operand" ""))
15135 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15137 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15139 (use (match_dup 2))
15140 (use (match_dup 3))])
15141 (set (match_dup 0) (match_dup 4))])
15144 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15145 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15147 (use (match_operand:HI 2 "memory_operand" ""))
15148 (use (match_operand:HI 3 "memory_operand" ""))
15149 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15151 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15153 (use (match_dup 2))
15154 (use (match_dup 3))])])
15156 (define_expand "lceilxf<mode>2"
15157 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15158 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15160 (clobber (reg:CC FLAGS_REG))])]
15161 "TARGET_USE_FANCY_MATH_387
15162 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15163 && flag_unsafe_math_optimizations")
15165 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15166 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15167 (match_operand:MODEF 1 "register_operand" "")]
15168 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15169 && !flag_trapping_math"
15171 ix86_expand_lfloorceil (operand0, operand1, false);
15175 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15176 (define_insn_and_split "frndintxf2_trunc"
15177 [(set (match_operand:XF 0 "register_operand" "")
15178 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15179 UNSPEC_FRNDINT_TRUNC))
15180 (clobber (reg:CC FLAGS_REG))]
15181 "TARGET_USE_FANCY_MATH_387
15182 && flag_unsafe_math_optimizations
15183 && can_create_pseudo_p ()"
15188 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15190 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15191 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15193 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15194 operands[2], operands[3]));
15197 [(set_attr "type" "frndint")
15198 (set_attr "i387_cw" "trunc")
15199 (set_attr "mode" "XF")])
15201 (define_insn "frndintxf2_trunc_i387"
15202 [(set (match_operand:XF 0 "register_operand" "=f")
15203 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15204 UNSPEC_FRNDINT_TRUNC))
15205 (use (match_operand:HI 2 "memory_operand" "m"))
15206 (use (match_operand:HI 3 "memory_operand" "m"))]
15207 "TARGET_USE_FANCY_MATH_387
15208 && flag_unsafe_math_optimizations"
15209 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15210 [(set_attr "type" "frndint")
15211 (set_attr "i387_cw" "trunc")
15212 (set_attr "mode" "XF")])
15214 (define_expand "btruncxf2"
15215 [(use (match_operand:XF 0 "register_operand" ""))
15216 (use (match_operand:XF 1 "register_operand" ""))]
15217 "TARGET_USE_FANCY_MATH_387
15218 && flag_unsafe_math_optimizations"
15220 if (optimize_insn_for_size_p ())
15222 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15226 (define_expand "btrunc<mode>2"
15227 [(use (match_operand:MODEF 0 "register_operand" ""))
15228 (use (match_operand:MODEF 1 "register_operand" ""))]
15229 "(TARGET_USE_FANCY_MATH_387
15230 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15231 || TARGET_MIX_SSE_I387)
15232 && flag_unsafe_math_optimizations)
15233 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15234 && !flag_trapping_math)"
15236 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15237 && !flag_trapping_math
15238 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15241 emit_insn (gen_sse4_1_round<mode>2
15242 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15243 else if (optimize_insn_for_size_p ())
15245 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15246 ix86_expand_trunc (operand0, operand1);
15248 ix86_expand_truncdf_32 (operand0, operand1);
15254 if (optimize_insn_for_size_p ())
15257 op0 = gen_reg_rtx (XFmode);
15258 op1 = gen_reg_rtx (XFmode);
15259 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15260 emit_insn (gen_frndintxf2_trunc (op0, op1));
15262 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15267 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15268 (define_insn_and_split "frndintxf2_mask_pm"
15269 [(set (match_operand:XF 0 "register_operand" "")
15270 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15271 UNSPEC_FRNDINT_MASK_PM))
15272 (clobber (reg:CC FLAGS_REG))]
15273 "TARGET_USE_FANCY_MATH_387
15274 && flag_unsafe_math_optimizations
15275 && can_create_pseudo_p ()"
15280 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15282 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15283 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15285 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15286 operands[2], operands[3]));
15289 [(set_attr "type" "frndint")
15290 (set_attr "i387_cw" "mask_pm")
15291 (set_attr "mode" "XF")])
15293 (define_insn "frndintxf2_mask_pm_i387"
15294 [(set (match_operand:XF 0 "register_operand" "=f")
15295 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15296 UNSPEC_FRNDINT_MASK_PM))
15297 (use (match_operand:HI 2 "memory_operand" "m"))
15298 (use (match_operand:HI 3 "memory_operand" "m"))]
15299 "TARGET_USE_FANCY_MATH_387
15300 && flag_unsafe_math_optimizations"
15301 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15302 [(set_attr "type" "frndint")
15303 (set_attr "i387_cw" "mask_pm")
15304 (set_attr "mode" "XF")])
15306 (define_expand "nearbyintxf2"
15307 [(use (match_operand:XF 0 "register_operand" ""))
15308 (use (match_operand:XF 1 "register_operand" ""))]
15309 "TARGET_USE_FANCY_MATH_387
15310 && flag_unsafe_math_optimizations"
15312 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15316 (define_expand "nearbyint<mode>2"
15317 [(use (match_operand:MODEF 0 "register_operand" ""))
15318 (use (match_operand:MODEF 1 "register_operand" ""))]
15319 "TARGET_USE_FANCY_MATH_387
15320 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15321 || TARGET_MIX_SSE_I387)
15322 && flag_unsafe_math_optimizations"
15324 rtx op0 = gen_reg_rtx (XFmode);
15325 rtx op1 = gen_reg_rtx (XFmode);
15327 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15328 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15330 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15334 (define_insn "fxam<mode>2_i387"
15335 [(set (match_operand:HI 0 "register_operand" "=a")
15337 [(match_operand:X87MODEF 1 "register_operand" "f")]
15339 "TARGET_USE_FANCY_MATH_387"
15340 "fxam\n\tfnstsw\t%0"
15341 [(set_attr "type" "multi")
15342 (set_attr "length" "4")
15343 (set_attr "unit" "i387")
15344 (set_attr "mode" "<MODE>")])
15346 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15347 [(set (match_operand:HI 0 "register_operand" "")
15349 [(match_operand:MODEF 1 "memory_operand" "")]
15351 "TARGET_USE_FANCY_MATH_387
15352 && can_create_pseudo_p ()"
15355 [(set (match_dup 2)(match_dup 1))
15357 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15359 operands[2] = gen_reg_rtx (<MODE>mode);
15361 MEM_VOLATILE_P (operands[1]) = 1;
15363 [(set_attr "type" "multi")
15364 (set_attr "unit" "i387")
15365 (set_attr "mode" "<MODE>")])
15367 (define_expand "isinfxf2"
15368 [(use (match_operand:SI 0 "register_operand" ""))
15369 (use (match_operand:XF 1 "register_operand" ""))]
15370 "TARGET_USE_FANCY_MATH_387
15371 && TARGET_C99_FUNCTIONS"
15373 rtx mask = GEN_INT (0x45);
15374 rtx val = GEN_INT (0x05);
15378 rtx scratch = gen_reg_rtx (HImode);
15379 rtx res = gen_reg_rtx (QImode);
15381 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15383 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15384 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15385 cond = gen_rtx_fmt_ee (EQ, QImode,
15386 gen_rtx_REG (CCmode, FLAGS_REG),
15388 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15389 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15393 (define_expand "isinf<mode>2"
15394 [(use (match_operand:SI 0 "register_operand" ""))
15395 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15396 "TARGET_USE_FANCY_MATH_387
15397 && TARGET_C99_FUNCTIONS
15398 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15400 rtx mask = GEN_INT (0x45);
15401 rtx val = GEN_INT (0x05);
15405 rtx scratch = gen_reg_rtx (HImode);
15406 rtx res = gen_reg_rtx (QImode);
15408 /* Remove excess precision by forcing value through memory. */
15409 if (memory_operand (operands[1], VOIDmode))
15410 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15413 enum ix86_stack_slot slot = (virtuals_instantiated
15416 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15418 emit_move_insn (temp, operands[1]);
15419 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15422 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15423 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15424 cond = gen_rtx_fmt_ee (EQ, QImode,
15425 gen_rtx_REG (CCmode, FLAGS_REG),
15427 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15428 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15432 (define_expand "signbitxf2"
15433 [(use (match_operand:SI 0 "register_operand" ""))
15434 (use (match_operand:XF 1 "register_operand" ""))]
15435 "TARGET_USE_FANCY_MATH_387"
15437 rtx scratch = gen_reg_rtx (HImode);
15439 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15440 emit_insn (gen_andsi3 (operands[0],
15441 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15445 (define_insn "movmsk_df"
15446 [(set (match_operand:SI 0 "register_operand" "=r")
15448 [(match_operand:DF 1 "register_operand" "x")]
15450 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15451 "%vmovmskpd\t{%1, %0|%0, %1}"
15452 [(set_attr "type" "ssemov")
15453 (set_attr "prefix" "maybe_vex")
15454 (set_attr "mode" "DF")])
15456 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15457 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15458 (define_expand "signbitdf2"
15459 [(use (match_operand:SI 0 "register_operand" ""))
15460 (use (match_operand:DF 1 "register_operand" ""))]
15461 "TARGET_USE_FANCY_MATH_387
15462 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15464 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15466 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15467 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15471 rtx scratch = gen_reg_rtx (HImode);
15473 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15474 emit_insn (gen_andsi3 (operands[0],
15475 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15480 (define_expand "signbitsf2"
15481 [(use (match_operand:SI 0 "register_operand" ""))
15482 (use (match_operand:SF 1 "register_operand" ""))]
15483 "TARGET_USE_FANCY_MATH_387
15484 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15486 rtx scratch = gen_reg_rtx (HImode);
15488 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15489 emit_insn (gen_andsi3 (operands[0],
15490 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15494 ;; Block operation instructions
15497 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15500 [(set_attr "length" "1")
15501 (set_attr "length_immediate" "0")
15502 (set_attr "modrm" "0")])
15504 (define_expand "movmem<mode>"
15505 [(use (match_operand:BLK 0 "memory_operand" ""))
15506 (use (match_operand:BLK 1 "memory_operand" ""))
15507 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15508 (use (match_operand:SWI48 3 "const_int_operand" ""))
15509 (use (match_operand:SI 4 "const_int_operand" ""))
15510 (use (match_operand:SI 5 "const_int_operand" ""))]
15513 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15514 operands[4], operands[5]))
15520 ;; Most CPUs don't like single string operations
15521 ;; Handle this case here to simplify previous expander.
15523 (define_expand "strmov"
15524 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15525 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15526 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15527 (clobber (reg:CC FLAGS_REG))])
15528 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15529 (clobber (reg:CC FLAGS_REG))])]
15532 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15534 /* If .md ever supports :P for Pmode, these can be directly
15535 in the pattern above. */
15536 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15537 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15539 /* Can't use this if the user has appropriated esi or edi. */
15540 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15541 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15543 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15544 operands[2], operands[3],
15545 operands[5], operands[6]));
15549 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15552 (define_expand "strmov_singleop"
15553 [(parallel [(set (match_operand 1 "memory_operand" "")
15554 (match_operand 3 "memory_operand" ""))
15555 (set (match_operand 0 "register_operand" "")
15556 (match_operand 4 "" ""))
15557 (set (match_operand 2 "register_operand" "")
15558 (match_operand 5 "" ""))])]
15560 "ix86_current_function_needs_cld = 1;")
15562 (define_insn "*strmovdi_rex_1"
15563 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15564 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15565 (set (match_operand:DI 0 "register_operand" "=D")
15566 (plus:DI (match_dup 2)
15568 (set (match_operand:DI 1 "register_operand" "=S")
15569 (plus:DI (match_dup 3)
15573 [(set_attr "type" "str")
15574 (set_attr "memory" "both")
15575 (set_attr "mode" "DI")])
15577 (define_insn "*strmovsi_1"
15578 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15579 (mem:SI (match_operand:P 3 "register_operand" "1")))
15580 (set (match_operand:P 0 "register_operand" "=D")
15581 (plus:P (match_dup 2)
15583 (set (match_operand:P 1 "register_operand" "=S")
15584 (plus:P (match_dup 3)
15588 [(set_attr "type" "str")
15589 (set_attr "memory" "both")
15590 (set_attr "mode" "SI")])
15592 (define_insn "*strmovhi_1"
15593 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15594 (mem:HI (match_operand:P 3 "register_operand" "1")))
15595 (set (match_operand:P 0 "register_operand" "=D")
15596 (plus:P (match_dup 2)
15598 (set (match_operand:P 1 "register_operand" "=S")
15599 (plus:P (match_dup 3)
15603 [(set_attr "type" "str")
15604 (set_attr "memory" "both")
15605 (set_attr "mode" "HI")])
15607 (define_insn "*strmovqi_1"
15608 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15609 (mem:QI (match_operand:P 3 "register_operand" "1")))
15610 (set (match_operand:P 0 "register_operand" "=D")
15611 (plus:P (match_dup 2)
15613 (set (match_operand:P 1 "register_operand" "=S")
15614 (plus:P (match_dup 3)
15618 [(set_attr "type" "str")
15619 (set_attr "memory" "both")
15620 (set (attr "prefix_rex")
15622 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15624 (const_string "*")))
15625 (set_attr "mode" "QI")])
15627 (define_expand "rep_mov"
15628 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15629 (set (match_operand 0 "register_operand" "")
15630 (match_operand 5 "" ""))
15631 (set (match_operand 2 "register_operand" "")
15632 (match_operand 6 "" ""))
15633 (set (match_operand 1 "memory_operand" "")
15634 (match_operand 3 "memory_operand" ""))
15635 (use (match_dup 4))])]
15637 "ix86_current_function_needs_cld = 1;")
15639 (define_insn "*rep_movdi_rex64"
15640 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15641 (set (match_operand:DI 0 "register_operand" "=D")
15642 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15644 (match_operand:DI 3 "register_operand" "0")))
15645 (set (match_operand:DI 1 "register_operand" "=S")
15646 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15647 (match_operand:DI 4 "register_operand" "1")))
15648 (set (mem:BLK (match_dup 3))
15649 (mem:BLK (match_dup 4)))
15650 (use (match_dup 5))]
15653 [(set_attr "type" "str")
15654 (set_attr "prefix_rep" "1")
15655 (set_attr "memory" "both")
15656 (set_attr "mode" "DI")])
15658 (define_insn "*rep_movsi"
15659 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15660 (set (match_operand:P 0 "register_operand" "=D")
15661 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15663 (match_operand:P 3 "register_operand" "0")))
15664 (set (match_operand:P 1 "register_operand" "=S")
15665 (plus:P (ashift:P (match_dup 5) (const_int 2))
15666 (match_operand:P 4 "register_operand" "1")))
15667 (set (mem:BLK (match_dup 3))
15668 (mem:BLK (match_dup 4)))
15669 (use (match_dup 5))]
15671 "rep{%;} movs{l|d}"
15672 [(set_attr "type" "str")
15673 (set_attr "prefix_rep" "1")
15674 (set_attr "memory" "both")
15675 (set_attr "mode" "SI")])
15677 (define_insn "*rep_movqi"
15678 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15679 (set (match_operand:P 0 "register_operand" "=D")
15680 (plus:P (match_operand:P 3 "register_operand" "0")
15681 (match_operand:P 5 "register_operand" "2")))
15682 (set (match_operand:P 1 "register_operand" "=S")
15683 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15684 (set (mem:BLK (match_dup 3))
15685 (mem:BLK (match_dup 4)))
15686 (use (match_dup 5))]
15689 [(set_attr "type" "str")
15690 (set_attr "prefix_rep" "1")
15691 (set_attr "memory" "both")
15692 (set_attr "mode" "QI")])
15694 (define_expand "setmem<mode>"
15695 [(use (match_operand:BLK 0 "memory_operand" ""))
15696 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15697 (use (match_operand:QI 2 "nonmemory_operand" ""))
15698 (use (match_operand 3 "const_int_operand" ""))
15699 (use (match_operand:SI 4 "const_int_operand" ""))
15700 (use (match_operand:SI 5 "const_int_operand" ""))]
15703 if (ix86_expand_setmem (operands[0], operands[1],
15704 operands[2], operands[3],
15705 operands[4], operands[5]))
15711 ;; Most CPUs don't like single string operations
15712 ;; Handle this case here to simplify previous expander.
15714 (define_expand "strset"
15715 [(set (match_operand 1 "memory_operand" "")
15716 (match_operand 2 "register_operand" ""))
15717 (parallel [(set (match_operand 0 "register_operand" "")
15719 (clobber (reg:CC FLAGS_REG))])]
15722 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15723 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15725 /* If .md ever supports :P for Pmode, this can be directly
15726 in the pattern above. */
15727 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15728 GEN_INT (GET_MODE_SIZE (GET_MODE
15730 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15732 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15738 (define_expand "strset_singleop"
15739 [(parallel [(set (match_operand 1 "memory_operand" "")
15740 (match_operand 2 "register_operand" ""))
15741 (set (match_operand 0 "register_operand" "")
15742 (match_operand 3 "" ""))])]
15744 "ix86_current_function_needs_cld = 1;")
15746 (define_insn "*strsetdi_rex_1"
15747 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15748 (match_operand:DI 2 "register_operand" "a"))
15749 (set (match_operand:DI 0 "register_operand" "=D")
15750 (plus:DI (match_dup 1)
15754 [(set_attr "type" "str")
15755 (set_attr "memory" "store")
15756 (set_attr "mode" "DI")])
15758 (define_insn "*strsetsi_1"
15759 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15760 (match_operand:SI 2 "register_operand" "a"))
15761 (set (match_operand:P 0 "register_operand" "=D")
15762 (plus:P (match_dup 1)
15766 [(set_attr "type" "str")
15767 (set_attr "memory" "store")
15768 (set_attr "mode" "SI")])
15770 (define_insn "*strsethi_1"
15771 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15772 (match_operand:HI 2 "register_operand" "a"))
15773 (set (match_operand:P 0 "register_operand" "=D")
15774 (plus:P (match_dup 1)
15778 [(set_attr "type" "str")
15779 (set_attr "memory" "store")
15780 (set_attr "mode" "HI")])
15782 (define_insn "*strsetqi_1"
15783 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15784 (match_operand:QI 2 "register_operand" "a"))
15785 (set (match_operand:P 0 "register_operand" "=D")
15786 (plus:P (match_dup 1)
15790 [(set_attr "type" "str")
15791 (set_attr "memory" "store")
15792 (set (attr "prefix_rex")
15794 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15796 (const_string "*")))
15797 (set_attr "mode" "QI")])
15799 (define_expand "rep_stos"
15800 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15801 (set (match_operand 0 "register_operand" "")
15802 (match_operand 4 "" ""))
15803 (set (match_operand 2 "memory_operand" "") (const_int 0))
15804 (use (match_operand 3 "register_operand" ""))
15805 (use (match_dup 1))])]
15807 "ix86_current_function_needs_cld = 1;")
15809 (define_insn "*rep_stosdi_rex64"
15810 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15811 (set (match_operand:DI 0 "register_operand" "=D")
15812 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15814 (match_operand:DI 3 "register_operand" "0")))
15815 (set (mem:BLK (match_dup 3))
15817 (use (match_operand:DI 2 "register_operand" "a"))
15818 (use (match_dup 4))]
15821 [(set_attr "type" "str")
15822 (set_attr "prefix_rep" "1")
15823 (set_attr "memory" "store")
15824 (set_attr "mode" "DI")])
15826 (define_insn "*rep_stossi"
15827 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15828 (set (match_operand:P 0 "register_operand" "=D")
15829 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15831 (match_operand:P 3 "register_operand" "0")))
15832 (set (mem:BLK (match_dup 3))
15834 (use (match_operand:SI 2 "register_operand" "a"))
15835 (use (match_dup 4))]
15837 "rep{%;} stos{l|d}"
15838 [(set_attr "type" "str")
15839 (set_attr "prefix_rep" "1")
15840 (set_attr "memory" "store")
15841 (set_attr "mode" "SI")])
15843 (define_insn "*rep_stosqi"
15844 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15845 (set (match_operand:P 0 "register_operand" "=D")
15846 (plus:P (match_operand:P 3 "register_operand" "0")
15847 (match_operand:P 4 "register_operand" "1")))
15848 (set (mem:BLK (match_dup 3))
15850 (use (match_operand:QI 2 "register_operand" "a"))
15851 (use (match_dup 4))]
15854 [(set_attr "type" "str")
15855 (set_attr "prefix_rep" "1")
15856 (set_attr "memory" "store")
15857 (set (attr "prefix_rex")
15859 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15861 (const_string "*")))
15862 (set_attr "mode" "QI")])
15864 (define_expand "cmpstrnsi"
15865 [(set (match_operand:SI 0 "register_operand" "")
15866 (compare:SI (match_operand:BLK 1 "general_operand" "")
15867 (match_operand:BLK 2 "general_operand" "")))
15868 (use (match_operand 3 "general_operand" ""))
15869 (use (match_operand 4 "immediate_operand" ""))]
15872 rtx addr1, addr2, out, outlow, count, countreg, align;
15874 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15877 /* Can't use this if the user has appropriated esi or edi. */
15878 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15883 out = gen_reg_rtx (SImode);
15885 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15886 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15887 if (addr1 != XEXP (operands[1], 0))
15888 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15889 if (addr2 != XEXP (operands[2], 0))
15890 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15892 count = operands[3];
15893 countreg = ix86_zero_extend_to_Pmode (count);
15895 /* %%% Iff we are testing strict equality, we can use known alignment
15896 to good advantage. This may be possible with combine, particularly
15897 once cc0 is dead. */
15898 align = operands[4];
15900 if (CONST_INT_P (count))
15902 if (INTVAL (count) == 0)
15904 emit_move_insn (operands[0], const0_rtx);
15907 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15908 operands[1], operands[2]));
15912 rtx (*gen_cmp) (rtx, rtx);
15914 gen_cmp = (TARGET_64BIT
15915 ? gen_cmpdi_1 : gen_cmpsi_1);
15917 emit_insn (gen_cmp (countreg, countreg));
15918 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15919 operands[1], operands[2]));
15922 outlow = gen_lowpart (QImode, out);
15923 emit_insn (gen_cmpintqi (outlow));
15924 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15926 if (operands[0] != out)
15927 emit_move_insn (operands[0], out);
15932 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15934 (define_expand "cmpintqi"
15935 [(set (match_dup 1)
15936 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15938 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15939 (parallel [(set (match_operand:QI 0 "register_operand" "")
15940 (minus:QI (match_dup 1)
15942 (clobber (reg:CC FLAGS_REG))])]
15945 operands[1] = gen_reg_rtx (QImode);
15946 operands[2] = gen_reg_rtx (QImode);
15949 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15950 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15952 (define_expand "cmpstrnqi_nz_1"
15953 [(parallel [(set (reg:CC FLAGS_REG)
15954 (compare:CC (match_operand 4 "memory_operand" "")
15955 (match_operand 5 "memory_operand" "")))
15956 (use (match_operand 2 "register_operand" ""))
15957 (use (match_operand:SI 3 "immediate_operand" ""))
15958 (clobber (match_operand 0 "register_operand" ""))
15959 (clobber (match_operand 1 "register_operand" ""))
15960 (clobber (match_dup 2))])]
15962 "ix86_current_function_needs_cld = 1;")
15964 (define_insn "*cmpstrnqi_nz_1"
15965 [(set (reg:CC FLAGS_REG)
15966 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15967 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15968 (use (match_operand:P 6 "register_operand" "2"))
15969 (use (match_operand:SI 3 "immediate_operand" "i"))
15970 (clobber (match_operand:P 0 "register_operand" "=S"))
15971 (clobber (match_operand:P 1 "register_operand" "=D"))
15972 (clobber (match_operand:P 2 "register_operand" "=c"))]
15975 [(set_attr "type" "str")
15976 (set_attr "mode" "QI")
15977 (set (attr "prefix_rex")
15979 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15981 (const_string "*")))
15982 (set_attr "prefix_rep" "1")])
15984 ;; The same, but the count is not known to not be zero.
15986 (define_expand "cmpstrnqi_1"
15987 [(parallel [(set (reg:CC FLAGS_REG)
15988 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15990 (compare:CC (match_operand 4 "memory_operand" "")
15991 (match_operand 5 "memory_operand" ""))
15993 (use (match_operand:SI 3 "immediate_operand" ""))
15994 (use (reg:CC FLAGS_REG))
15995 (clobber (match_operand 0 "register_operand" ""))
15996 (clobber (match_operand 1 "register_operand" ""))
15997 (clobber (match_dup 2))])]
15999 "ix86_current_function_needs_cld = 1;")
16001 (define_insn "*cmpstrnqi_1"
16002 [(set (reg:CC FLAGS_REG)
16003 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16005 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16006 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16008 (use (match_operand:SI 3 "immediate_operand" "i"))
16009 (use (reg:CC FLAGS_REG))
16010 (clobber (match_operand:P 0 "register_operand" "=S"))
16011 (clobber (match_operand:P 1 "register_operand" "=D"))
16012 (clobber (match_operand:P 2 "register_operand" "=c"))]
16015 [(set_attr "type" "str")
16016 (set_attr "mode" "QI")
16017 (set (attr "prefix_rex")
16019 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16021 (const_string "*")))
16022 (set_attr "prefix_rep" "1")])
16024 (define_expand "strlen<mode>"
16025 [(set (match_operand:SWI48x 0 "register_operand" "")
16026 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16027 (match_operand:QI 2 "immediate_operand" "")
16028 (match_operand 3 "immediate_operand" "")]
16032 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16038 (define_expand "strlenqi_1"
16039 [(parallel [(set (match_operand 0 "register_operand" "")
16040 (match_operand 2 "" ""))
16041 (clobber (match_operand 1 "register_operand" ""))
16042 (clobber (reg:CC FLAGS_REG))])]
16044 "ix86_current_function_needs_cld = 1;")
16046 (define_insn "*strlenqi_1"
16047 [(set (match_operand:P 0 "register_operand" "=&c")
16048 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16049 (match_operand:QI 2 "register_operand" "a")
16050 (match_operand:P 3 "immediate_operand" "i")
16051 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16052 (clobber (match_operand:P 1 "register_operand" "=D"))
16053 (clobber (reg:CC FLAGS_REG))]
16056 [(set_attr "type" "str")
16057 (set_attr "mode" "QI")
16058 (set (attr "prefix_rex")
16060 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16062 (const_string "*")))
16063 (set_attr "prefix_rep" "1")])
16065 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16066 ;; handled in combine, but it is not currently up to the task.
16067 ;; When used for their truth value, the cmpstrn* expanders generate
16076 ;; The intermediate three instructions are unnecessary.
16078 ;; This one handles cmpstrn*_nz_1...
16081 (set (reg:CC FLAGS_REG)
16082 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16083 (mem:BLK (match_operand 5 "register_operand" ""))))
16084 (use (match_operand 6 "register_operand" ""))
16085 (use (match_operand:SI 3 "immediate_operand" ""))
16086 (clobber (match_operand 0 "register_operand" ""))
16087 (clobber (match_operand 1 "register_operand" ""))
16088 (clobber (match_operand 2 "register_operand" ""))])
16089 (set (match_operand:QI 7 "register_operand" "")
16090 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16091 (set (match_operand:QI 8 "register_operand" "")
16092 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16093 (set (reg FLAGS_REG)
16094 (compare (match_dup 7) (match_dup 8)))
16096 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16098 (set (reg:CC FLAGS_REG)
16099 (compare:CC (mem:BLK (match_dup 4))
16100 (mem:BLK (match_dup 5))))
16101 (use (match_dup 6))
16102 (use (match_dup 3))
16103 (clobber (match_dup 0))
16104 (clobber (match_dup 1))
16105 (clobber (match_dup 2))])])
16107 ;; ...and this one handles cmpstrn*_1.
16110 (set (reg:CC FLAGS_REG)
16111 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16113 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16114 (mem:BLK (match_operand 5 "register_operand" "")))
16116 (use (match_operand:SI 3 "immediate_operand" ""))
16117 (use (reg:CC FLAGS_REG))
16118 (clobber (match_operand 0 "register_operand" ""))
16119 (clobber (match_operand 1 "register_operand" ""))
16120 (clobber (match_operand 2 "register_operand" ""))])
16121 (set (match_operand:QI 7 "register_operand" "")
16122 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16123 (set (match_operand:QI 8 "register_operand" "")
16124 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16125 (set (reg FLAGS_REG)
16126 (compare (match_dup 7) (match_dup 8)))
16128 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16130 (set (reg:CC FLAGS_REG)
16131 (if_then_else:CC (ne (match_dup 6)
16133 (compare:CC (mem:BLK (match_dup 4))
16134 (mem:BLK (match_dup 5)))
16136 (use (match_dup 3))
16137 (use (reg:CC FLAGS_REG))
16138 (clobber (match_dup 0))
16139 (clobber (match_dup 1))
16140 (clobber (match_dup 2))])])
16142 ;; Conditional move instructions.
16144 (define_expand "mov<mode>cc"
16145 [(set (match_operand:SWIM 0 "register_operand" "")
16146 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16147 (match_operand:SWIM 2 "general_operand" "")
16148 (match_operand:SWIM 3 "general_operand" "")))]
16150 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16152 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16153 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16154 ;; So just document what we're doing explicitly.
16156 (define_expand "x86_mov<mode>cc_0_m1"
16158 [(set (match_operand:SWI48 0 "register_operand" "")
16159 (if_then_else:SWI48
16160 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16161 [(match_operand 1 "flags_reg_operand" "")
16165 (clobber (reg:CC FLAGS_REG))])])
16167 (define_insn "*x86_mov<mode>cc_0_m1"
16168 [(set (match_operand:SWI48 0 "register_operand" "=r")
16169 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16170 [(reg FLAGS_REG) (const_int 0)])
16173 (clobber (reg:CC FLAGS_REG))]
16175 "sbb{<imodesuffix>}\t%0, %0"
16176 ; Since we don't have the proper number of operands for an alu insn,
16177 ; fill in all the blanks.
16178 [(set_attr "type" "alu")
16179 (set_attr "use_carry" "1")
16180 (set_attr "pent_pair" "pu")
16181 (set_attr "memory" "none")
16182 (set_attr "imm_disp" "false")
16183 (set_attr "mode" "<MODE>")
16184 (set_attr "length_immediate" "0")])
16186 (define_insn "*x86_mov<mode>cc_0_m1_se"
16187 [(set (match_operand:SWI48 0 "register_operand" "=r")
16188 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16189 [(reg FLAGS_REG) (const_int 0)])
16192 (clobber (reg:CC FLAGS_REG))]
16194 "sbb{<imodesuffix>}\t%0, %0"
16195 [(set_attr "type" "alu")
16196 (set_attr "use_carry" "1")
16197 (set_attr "pent_pair" "pu")
16198 (set_attr "memory" "none")
16199 (set_attr "imm_disp" "false")
16200 (set_attr "mode" "<MODE>")
16201 (set_attr "length_immediate" "0")])
16203 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16204 [(set (match_operand:SWI48 0 "register_operand" "=r")
16205 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16206 [(reg FLAGS_REG) (const_int 0)])))]
16208 "sbb{<imodesuffix>}\t%0, %0"
16209 [(set_attr "type" "alu")
16210 (set_attr "use_carry" "1")
16211 (set_attr "pent_pair" "pu")
16212 (set_attr "memory" "none")
16213 (set_attr "imm_disp" "false")
16214 (set_attr "mode" "<MODE>")
16215 (set_attr "length_immediate" "0")])
16217 (define_insn "*mov<mode>cc_noc"
16218 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16219 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16220 [(reg FLAGS_REG) (const_int 0)])
16221 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16222 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16223 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16225 cmov%O2%C1\t{%2, %0|%0, %2}
16226 cmov%O2%c1\t{%3, %0|%0, %3}"
16227 [(set_attr "type" "icmov")
16228 (set_attr "mode" "<MODE>")])
16230 (define_insn_and_split "*movqicc_noc"
16231 [(set (match_operand:QI 0 "register_operand" "=r,r")
16232 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16233 [(match_operand 4 "flags_reg_operand" "")
16235 (match_operand:QI 2 "register_operand" "r,0")
16236 (match_operand:QI 3 "register_operand" "0,r")))]
16237 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16239 "&& reload_completed"
16240 [(set (match_dup 0)
16241 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16244 "operands[0] = gen_lowpart (SImode, operands[0]);
16245 operands[2] = gen_lowpart (SImode, operands[2]);
16246 operands[3] = gen_lowpart (SImode, operands[3]);"
16247 [(set_attr "type" "icmov")
16248 (set_attr "mode" "SI")])
16250 (define_expand "mov<mode>cc"
16251 [(set (match_operand:X87MODEF 0 "register_operand" "")
16252 (if_then_else:X87MODEF
16253 (match_operand 1 "ix86_fp_comparison_operator" "")
16254 (match_operand:X87MODEF 2 "register_operand" "")
16255 (match_operand:X87MODEF 3 "register_operand" "")))]
16256 "(TARGET_80387 && TARGET_CMOVE)
16257 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16258 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16260 (define_insn "*movxfcc_1"
16261 [(set (match_operand:XF 0 "register_operand" "=f,f")
16262 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16263 [(reg FLAGS_REG) (const_int 0)])
16264 (match_operand:XF 2 "register_operand" "f,0")
16265 (match_operand:XF 3 "register_operand" "0,f")))]
16266 "TARGET_80387 && TARGET_CMOVE"
16268 fcmov%F1\t{%2, %0|%0, %2}
16269 fcmov%f1\t{%3, %0|%0, %3}"
16270 [(set_attr "type" "fcmov")
16271 (set_attr "mode" "XF")])
16273 (define_insn "*movdfcc_1_rex64"
16274 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16275 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16276 [(reg FLAGS_REG) (const_int 0)])
16277 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16278 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16279 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16280 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16282 fcmov%F1\t{%2, %0|%0, %2}
16283 fcmov%f1\t{%3, %0|%0, %3}
16284 cmov%O2%C1\t{%2, %0|%0, %2}
16285 cmov%O2%c1\t{%3, %0|%0, %3}"
16286 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16287 (set_attr "mode" "DF,DF,DI,DI")])
16289 (define_insn "*movdfcc_1"
16290 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16291 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16292 [(reg FLAGS_REG) (const_int 0)])
16293 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16294 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16295 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16296 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16298 fcmov%F1\t{%2, %0|%0, %2}
16299 fcmov%f1\t{%3, %0|%0, %3}
16302 [(set_attr "type" "fcmov,fcmov,multi,multi")
16303 (set_attr "mode" "DF,DF,DI,DI")])
16306 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16307 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16308 [(match_operand 4 "flags_reg_operand" "")
16310 (match_operand:DF 2 "nonimmediate_operand" "")
16311 (match_operand:DF 3 "nonimmediate_operand" "")))]
16312 "!TARGET_64BIT && reload_completed"
16313 [(set (match_dup 2)
16314 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16318 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16322 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16323 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16326 (define_insn "*movsfcc_1_387"
16327 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16328 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16329 [(reg FLAGS_REG) (const_int 0)])
16330 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16331 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16332 "TARGET_80387 && TARGET_CMOVE
16333 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16335 fcmov%F1\t{%2, %0|%0, %2}
16336 fcmov%f1\t{%3, %0|%0, %3}
16337 cmov%O2%C1\t{%2, %0|%0, %2}
16338 cmov%O2%c1\t{%3, %0|%0, %3}"
16339 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16340 (set_attr "mode" "SF,SF,SI,SI")])
16342 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16343 ;; the scalar versions to have only XMM registers as operands.
16345 ;; XOP conditional move
16346 (define_insn "*xop_pcmov_<mode>"
16347 [(set (match_operand:MODEF 0 "register_operand" "=x")
16348 (if_then_else:MODEF
16349 (match_operand:MODEF 1 "register_operand" "x")
16350 (match_operand:MODEF 2 "register_operand" "x")
16351 (match_operand:MODEF 3 "register_operand" "x")))]
16353 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16354 [(set_attr "type" "sse4arg")])
16356 ;; These versions of the min/max patterns are intentionally ignorant of
16357 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16358 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16359 ;; are undefined in this condition, we're certain this is correct.
16361 (define_insn "<code><mode>3"
16362 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16364 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16365 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16366 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16368 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16369 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16370 [(set_attr "isa" "noavx,avx")
16371 (set_attr "prefix" "orig,vex")
16372 (set_attr "type" "sseadd")
16373 (set_attr "mode" "<MODE>")])
16375 ;; These versions of the min/max patterns implement exactly the operations
16376 ;; min = (op1 < op2 ? op1 : op2)
16377 ;; max = (!(op1 < op2) ? op1 : op2)
16378 ;; Their operands are not commutative, and thus they may be used in the
16379 ;; presence of -0.0 and NaN.
16381 (define_insn "*ieee_smin<mode>3"
16382 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16384 [(match_operand:MODEF 1 "register_operand" "0,x")
16385 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16387 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16389 min<ssemodesuffix>\t{%2, %0|%0, %2}
16390 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16391 [(set_attr "isa" "noavx,avx")
16392 (set_attr "prefix" "orig,vex")
16393 (set_attr "type" "sseadd")
16394 (set_attr "mode" "<MODE>")])
16396 (define_insn "*ieee_smax<mode>3"
16397 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16399 [(match_operand:MODEF 1 "register_operand" "0,x")
16400 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16402 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16404 max<ssemodesuffix>\t{%2, %0|%0, %2}
16405 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16406 [(set_attr "isa" "noavx,avx")
16407 (set_attr "prefix" "orig,vex")
16408 (set_attr "type" "sseadd")
16409 (set_attr "mode" "<MODE>")])
16411 ;; Make two stack loads independent:
16413 ;; fld %st(0) -> fld bb
16414 ;; fmul bb fmul %st(1), %st
16416 ;; Actually we only match the last two instructions for simplicity.
16418 [(set (match_operand 0 "fp_register_operand" "")
16419 (match_operand 1 "fp_register_operand" ""))
16421 (match_operator 2 "binary_fp_operator"
16423 (match_operand 3 "memory_operand" "")]))]
16424 "REGNO (operands[0]) != REGNO (operands[1])"
16425 [(set (match_dup 0) (match_dup 3))
16426 (set (match_dup 0) (match_dup 4))]
16428 ;; The % modifier is not operational anymore in peephole2's, so we have to
16429 ;; swap the operands manually in the case of addition and multiplication.
16430 "if (COMMUTATIVE_ARITH_P (operands[2]))
16431 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16432 GET_MODE (operands[2]),
16433 operands[0], operands[1]);
16435 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16436 GET_MODE (operands[2]),
16437 operands[1], operands[0]);")
16439 ;; Conditional addition patterns
16440 (define_expand "add<mode>cc"
16441 [(match_operand:SWI 0 "register_operand" "")
16442 (match_operand 1 "ordered_comparison_operator" "")
16443 (match_operand:SWI 2 "register_operand" "")
16444 (match_operand:SWI 3 "const_int_operand" "")]
16446 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16448 ;; Misc patterns (?)
16450 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16451 ;; Otherwise there will be nothing to keep
16453 ;; [(set (reg ebp) (reg esp))]
16454 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16455 ;; (clobber (eflags)]
16456 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16458 ;; in proper program order.
16460 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16461 [(set (match_operand:P 0 "register_operand" "=r,r")
16462 (plus:P (match_operand:P 1 "register_operand" "0,r")
16463 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16464 (clobber (reg:CC FLAGS_REG))
16465 (clobber (mem:BLK (scratch)))]
16468 switch (get_attr_type (insn))
16471 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16474 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16475 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16476 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16478 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16481 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16482 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16485 [(set (attr "type")
16486 (cond [(and (eq_attr "alternative" "0")
16487 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16488 (const_string "alu")
16489 (match_operand:<MODE> 2 "const0_operand" "")
16490 (const_string "imov")
16492 (const_string "lea")))
16493 (set (attr "length_immediate")
16494 (cond [(eq_attr "type" "imov")
16496 (and (eq_attr "type" "alu")
16497 (match_operand 2 "const128_operand" ""))
16500 (const_string "*")))
16501 (set_attr "mode" "<MODE>")])
16503 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16504 [(set (match_operand:P 0 "register_operand" "=r")
16505 (minus:P (match_operand:P 1 "register_operand" "0")
16506 (match_operand:P 2 "register_operand" "r")))
16507 (clobber (reg:CC FLAGS_REG))
16508 (clobber (mem:BLK (scratch)))]
16510 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16511 [(set_attr "type" "alu")
16512 (set_attr "mode" "<MODE>")])
16514 (define_insn "allocate_stack_worker_probe_<mode>"
16515 [(set (match_operand:P 0 "register_operand" "=a")
16516 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16517 UNSPECV_STACK_PROBE))
16518 (clobber (reg:CC FLAGS_REG))]
16519 "ix86_target_stack_probe ()"
16520 "call\t___chkstk_ms"
16521 [(set_attr "type" "multi")
16522 (set_attr "length" "5")])
16524 (define_expand "allocate_stack"
16525 [(match_operand 0 "register_operand" "")
16526 (match_operand 1 "general_operand" "")]
16527 "ix86_target_stack_probe ()"
16531 #ifndef CHECK_STACK_LIMIT
16532 #define CHECK_STACK_LIMIT 0
16535 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16536 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16538 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16539 stack_pointer_rtx, 0, OPTAB_DIRECT);
16540 if (x != stack_pointer_rtx)
16541 emit_move_insn (stack_pointer_rtx, x);
16545 x = copy_to_mode_reg (Pmode, operands[1]);
16547 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16549 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16550 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16551 stack_pointer_rtx, 0, OPTAB_DIRECT);
16552 if (x != stack_pointer_rtx)
16553 emit_move_insn (stack_pointer_rtx, x);
16556 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16560 ;; Use IOR for stack probes, this is shorter.
16561 (define_expand "probe_stack"
16562 [(match_operand 0 "memory_operand" "")]
16565 rtx (*gen_ior3) (rtx, rtx, rtx);
16567 gen_ior3 = (GET_MODE (operands[0]) == DImode
16568 ? gen_iordi3 : gen_iorsi3);
16570 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16574 (define_insn "adjust_stack_and_probe<mode>"
16575 [(set (match_operand:P 0 "register_operand" "=r")
16576 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16577 UNSPECV_PROBE_STACK_RANGE))
16578 (set (reg:P SP_REG)
16579 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16580 (clobber (reg:CC FLAGS_REG))
16581 (clobber (mem:BLK (scratch)))]
16583 "* return output_adjust_stack_and_probe (operands[0]);"
16584 [(set_attr "type" "multi")])
16586 (define_insn "probe_stack_range<mode>"
16587 [(set (match_operand:P 0 "register_operand" "=r")
16588 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16589 (match_operand:P 2 "const_int_operand" "n")]
16590 UNSPECV_PROBE_STACK_RANGE))
16591 (clobber (reg:CC FLAGS_REG))]
16593 "* return output_probe_stack_range (operands[0], operands[2]);"
16594 [(set_attr "type" "multi")])
16596 (define_expand "builtin_setjmp_receiver"
16597 [(label_ref (match_operand 0 "" ""))]
16598 "!TARGET_64BIT && flag_pic"
16604 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16605 rtx label_rtx = gen_label_rtx ();
16606 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16607 xops[0] = xops[1] = picreg;
16608 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16609 ix86_expand_binary_operator (MINUS, SImode, xops);
16613 emit_insn (gen_set_got (pic_offset_table_rtx));
16617 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16620 [(set (match_operand 0 "register_operand" "")
16621 (match_operator 3 "promotable_binary_operator"
16622 [(match_operand 1 "register_operand" "")
16623 (match_operand 2 "aligned_operand" "")]))
16624 (clobber (reg:CC FLAGS_REG))]
16625 "! TARGET_PARTIAL_REG_STALL && reload_completed
16626 && ((GET_MODE (operands[0]) == HImode
16627 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16628 /* ??? next two lines just !satisfies_constraint_K (...) */
16629 || !CONST_INT_P (operands[2])
16630 || satisfies_constraint_K (operands[2])))
16631 || (GET_MODE (operands[0]) == QImode
16632 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16633 [(parallel [(set (match_dup 0)
16634 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16635 (clobber (reg:CC FLAGS_REG))])]
16636 "operands[0] = gen_lowpart (SImode, operands[0]);
16637 operands[1] = gen_lowpart (SImode, operands[1]);
16638 if (GET_CODE (operands[3]) != ASHIFT)
16639 operands[2] = gen_lowpart (SImode, operands[2]);
16640 PUT_MODE (operands[3], SImode);")
16642 ; Promote the QImode tests, as i386 has encoding of the AND
16643 ; instruction with 32-bit sign-extended immediate and thus the
16644 ; instruction size is unchanged, except in the %eax case for
16645 ; which it is increased by one byte, hence the ! optimize_size.
16647 [(set (match_operand 0 "flags_reg_operand" "")
16648 (match_operator 2 "compare_operator"
16649 [(and (match_operand 3 "aligned_operand" "")
16650 (match_operand 4 "const_int_operand" ""))
16652 (set (match_operand 1 "register_operand" "")
16653 (and (match_dup 3) (match_dup 4)))]
16654 "! TARGET_PARTIAL_REG_STALL && reload_completed
16655 && optimize_insn_for_speed_p ()
16656 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16657 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16658 /* Ensure that the operand will remain sign-extended immediate. */
16659 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16660 [(parallel [(set (match_dup 0)
16661 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16664 (and:SI (match_dup 3) (match_dup 4)))])]
16667 = gen_int_mode (INTVAL (operands[4])
16668 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16669 operands[1] = gen_lowpart (SImode, operands[1]);
16670 operands[3] = gen_lowpart (SImode, operands[3]);
16673 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16674 ; the TEST instruction with 32-bit sign-extended immediate and thus
16675 ; the instruction size would at least double, which is not what we
16676 ; want even with ! optimize_size.
16678 [(set (match_operand 0 "flags_reg_operand" "")
16679 (match_operator 1 "compare_operator"
16680 [(and (match_operand:HI 2 "aligned_operand" "")
16681 (match_operand:HI 3 "const_int_operand" ""))
16683 "! TARGET_PARTIAL_REG_STALL && reload_completed
16684 && ! TARGET_FAST_PREFIX
16685 && optimize_insn_for_speed_p ()
16686 /* Ensure that the operand will remain sign-extended immediate. */
16687 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16688 [(set (match_dup 0)
16689 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16693 = gen_int_mode (INTVAL (operands[3])
16694 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16695 operands[2] = gen_lowpart (SImode, operands[2]);
16699 [(set (match_operand 0 "register_operand" "")
16700 (neg (match_operand 1 "register_operand" "")))
16701 (clobber (reg:CC FLAGS_REG))]
16702 "! TARGET_PARTIAL_REG_STALL && reload_completed
16703 && (GET_MODE (operands[0]) == HImode
16704 || (GET_MODE (operands[0]) == QImode
16705 && (TARGET_PROMOTE_QImode
16706 || optimize_insn_for_size_p ())))"
16707 [(parallel [(set (match_dup 0)
16708 (neg:SI (match_dup 1)))
16709 (clobber (reg:CC FLAGS_REG))])]
16710 "operands[0] = gen_lowpart (SImode, operands[0]);
16711 operands[1] = gen_lowpart (SImode, operands[1]);")
16714 [(set (match_operand 0 "register_operand" "")
16715 (not (match_operand 1 "register_operand" "")))]
16716 "! TARGET_PARTIAL_REG_STALL && reload_completed
16717 && (GET_MODE (operands[0]) == HImode
16718 || (GET_MODE (operands[0]) == QImode
16719 && (TARGET_PROMOTE_QImode
16720 || optimize_insn_for_size_p ())))"
16721 [(set (match_dup 0)
16722 (not:SI (match_dup 1)))]
16723 "operands[0] = gen_lowpart (SImode, operands[0]);
16724 operands[1] = gen_lowpart (SImode, operands[1]);")
16727 [(set (match_operand 0 "register_operand" "")
16728 (if_then_else (match_operator 1 "ordered_comparison_operator"
16729 [(reg FLAGS_REG) (const_int 0)])
16730 (match_operand 2 "register_operand" "")
16731 (match_operand 3 "register_operand" "")))]
16732 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16733 && (GET_MODE (operands[0]) == HImode
16734 || (GET_MODE (operands[0]) == QImode
16735 && (TARGET_PROMOTE_QImode
16736 || optimize_insn_for_size_p ())))"
16737 [(set (match_dup 0)
16738 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16739 "operands[0] = gen_lowpart (SImode, operands[0]);
16740 operands[2] = gen_lowpart (SImode, operands[2]);
16741 operands[3] = gen_lowpart (SImode, operands[3]);")
16743 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16744 ;; transform a complex memory operation into two memory to register operations.
16746 ;; Don't push memory operands
16748 [(set (match_operand:SWI 0 "push_operand" "")
16749 (match_operand:SWI 1 "memory_operand" ""))
16750 (match_scratch:SWI 2 "<r>")]
16751 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16752 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16753 [(set (match_dup 2) (match_dup 1))
16754 (set (match_dup 0) (match_dup 2))])
16756 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16759 [(set (match_operand:SF 0 "push_operand" "")
16760 (match_operand:SF 1 "memory_operand" ""))
16761 (match_scratch:SF 2 "r")]
16762 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16763 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16764 [(set (match_dup 2) (match_dup 1))
16765 (set (match_dup 0) (match_dup 2))])
16767 ;; Don't move an immediate directly to memory when the instruction
16770 [(match_scratch:SWI124 1 "<r>")
16771 (set (match_operand:SWI124 0 "memory_operand" "")
16773 "optimize_insn_for_speed_p ()
16774 && !TARGET_USE_MOV0
16775 && TARGET_SPLIT_LONG_MOVES
16776 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16777 && peep2_regno_dead_p (0, FLAGS_REG)"
16778 [(parallel [(set (match_dup 2) (const_int 0))
16779 (clobber (reg:CC FLAGS_REG))])
16780 (set (match_dup 0) (match_dup 1))]
16781 "operands[2] = gen_lowpart (SImode, operands[1]);")
16784 [(match_scratch:SWI124 2 "<r>")
16785 (set (match_operand:SWI124 0 "memory_operand" "")
16786 (match_operand:SWI124 1 "immediate_operand" ""))]
16787 "optimize_insn_for_speed_p ()
16788 && TARGET_SPLIT_LONG_MOVES
16789 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16790 [(set (match_dup 2) (match_dup 1))
16791 (set (match_dup 0) (match_dup 2))])
16793 ;; Don't compare memory with zero, load and use a test instead.
16795 [(set (match_operand 0 "flags_reg_operand" "")
16796 (match_operator 1 "compare_operator"
16797 [(match_operand:SI 2 "memory_operand" "")
16799 (match_scratch:SI 3 "r")]
16800 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16801 [(set (match_dup 3) (match_dup 2))
16802 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16804 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16805 ;; Don't split NOTs with a displacement operand, because resulting XOR
16806 ;; will not be pairable anyway.
16808 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16809 ;; represented using a modRM byte. The XOR replacement is long decoded,
16810 ;; so this split helps here as well.
16812 ;; Note: Can't do this as a regular split because we can't get proper
16813 ;; lifetime information then.
16816 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16817 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16818 "optimize_insn_for_speed_p ()
16819 && ((TARGET_NOT_UNPAIRABLE
16820 && (!MEM_P (operands[0])
16821 || !memory_displacement_operand (operands[0], <MODE>mode)))
16822 || (TARGET_NOT_VECTORMODE
16823 && long_memory_operand (operands[0], <MODE>mode)))
16824 && peep2_regno_dead_p (0, FLAGS_REG)"
16825 [(parallel [(set (match_dup 0)
16826 (xor:SWI124 (match_dup 1) (const_int -1)))
16827 (clobber (reg:CC FLAGS_REG))])])
16829 ;; Non pairable "test imm, reg" instructions can be translated to
16830 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16831 ;; byte opcode instead of two, have a short form for byte operands),
16832 ;; so do it for other CPUs as well. Given that the value was dead,
16833 ;; this should not create any new dependencies. Pass on the sub-word
16834 ;; versions if we're concerned about partial register stalls.
16837 [(set (match_operand 0 "flags_reg_operand" "")
16838 (match_operator 1 "compare_operator"
16839 [(and:SI (match_operand:SI 2 "register_operand" "")
16840 (match_operand:SI 3 "immediate_operand" ""))
16842 "ix86_match_ccmode (insn, CCNOmode)
16843 && (true_regnum (operands[2]) != AX_REG
16844 || satisfies_constraint_K (operands[3]))
16845 && peep2_reg_dead_p (1, operands[2])"
16847 [(set (match_dup 0)
16848 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16851 (and:SI (match_dup 2) (match_dup 3)))])])
16853 ;; We don't need to handle HImode case, because it will be promoted to SImode
16854 ;; on ! TARGET_PARTIAL_REG_STALL
16857 [(set (match_operand 0 "flags_reg_operand" "")
16858 (match_operator 1 "compare_operator"
16859 [(and:QI (match_operand:QI 2 "register_operand" "")
16860 (match_operand:QI 3 "immediate_operand" ""))
16862 "! TARGET_PARTIAL_REG_STALL
16863 && ix86_match_ccmode (insn, CCNOmode)
16864 && true_regnum (operands[2]) != AX_REG
16865 && peep2_reg_dead_p (1, operands[2])"
16867 [(set (match_dup 0)
16868 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16871 (and:QI (match_dup 2) (match_dup 3)))])])
16874 [(set (match_operand 0 "flags_reg_operand" "")
16875 (match_operator 1 "compare_operator"
16878 (match_operand 2 "ext_register_operand" "")
16881 (match_operand 3 "const_int_operand" ""))
16883 "! TARGET_PARTIAL_REG_STALL
16884 && ix86_match_ccmode (insn, CCNOmode)
16885 && true_regnum (operands[2]) != AX_REG
16886 && peep2_reg_dead_p (1, operands[2])"
16887 [(parallel [(set (match_dup 0)
16896 (set (zero_extract:SI (match_dup 2)
16904 (match_dup 3)))])])
16906 ;; Don't do logical operations with memory inputs.
16908 [(match_scratch:SI 2 "r")
16909 (parallel [(set (match_operand:SI 0 "register_operand" "")
16910 (match_operator:SI 3 "arith_or_logical_operator"
16912 (match_operand:SI 1 "memory_operand" "")]))
16913 (clobber (reg:CC FLAGS_REG))])]
16914 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16915 [(set (match_dup 2) (match_dup 1))
16916 (parallel [(set (match_dup 0)
16917 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16918 (clobber (reg:CC FLAGS_REG))])])
16921 [(match_scratch:SI 2 "r")
16922 (parallel [(set (match_operand:SI 0 "register_operand" "")
16923 (match_operator:SI 3 "arith_or_logical_operator"
16924 [(match_operand:SI 1 "memory_operand" "")
16926 (clobber (reg:CC FLAGS_REG))])]
16927 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16928 [(set (match_dup 2) (match_dup 1))
16929 (parallel [(set (match_dup 0)
16930 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16931 (clobber (reg:CC FLAGS_REG))])])
16933 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16934 ;; refers to the destination of the load!
16937 [(set (match_operand:SI 0 "register_operand" "")
16938 (match_operand:SI 1 "register_operand" ""))
16939 (parallel [(set (match_dup 0)
16940 (match_operator:SI 3 "commutative_operator"
16942 (match_operand:SI 2 "memory_operand" "")]))
16943 (clobber (reg:CC FLAGS_REG))])]
16944 "REGNO (operands[0]) != REGNO (operands[1])
16945 && GENERAL_REGNO_P (REGNO (operands[0]))
16946 && GENERAL_REGNO_P (REGNO (operands[1]))"
16947 [(set (match_dup 0) (match_dup 4))
16948 (parallel [(set (match_dup 0)
16949 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16950 (clobber (reg:CC FLAGS_REG))])]
16951 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16954 [(set (match_operand 0 "register_operand" "")
16955 (match_operand 1 "register_operand" ""))
16957 (match_operator 3 "commutative_operator"
16959 (match_operand 2 "memory_operand" "")]))]
16960 "REGNO (operands[0]) != REGNO (operands[1])
16961 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16962 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16963 [(set (match_dup 0) (match_dup 2))
16965 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16967 ; Don't do logical operations with memory outputs
16969 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16970 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16971 ; the same decoder scheduling characteristics as the original.
16974 [(match_scratch:SI 2 "r")
16975 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16976 (match_operator:SI 3 "arith_or_logical_operator"
16978 (match_operand:SI 1 "nonmemory_operand" "")]))
16979 (clobber (reg:CC FLAGS_REG))])]
16980 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16981 /* Do not split stack checking probes. */
16982 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16983 [(set (match_dup 2) (match_dup 0))
16984 (parallel [(set (match_dup 2)
16985 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16986 (clobber (reg:CC FLAGS_REG))])
16987 (set (match_dup 0) (match_dup 2))])
16990 [(match_scratch:SI 2 "r")
16991 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16992 (match_operator:SI 3 "arith_or_logical_operator"
16993 [(match_operand:SI 1 "nonmemory_operand" "")
16995 (clobber (reg:CC FLAGS_REG))])]
16996 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16997 /* Do not split stack checking probes. */
16998 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16999 [(set (match_dup 2) (match_dup 0))
17000 (parallel [(set (match_dup 2)
17001 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17002 (clobber (reg:CC FLAGS_REG))])
17003 (set (match_dup 0) (match_dup 2))])
17005 ;; Attempt to always use XOR for zeroing registers.
17007 [(set (match_operand 0 "register_operand" "")
17008 (match_operand 1 "const0_operand" ""))]
17009 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17010 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17011 && GENERAL_REG_P (operands[0])
17012 && peep2_regno_dead_p (0, FLAGS_REG)"
17013 [(parallel [(set (match_dup 0) (const_int 0))
17014 (clobber (reg:CC FLAGS_REG))])]
17015 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17018 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17020 "(GET_MODE (operands[0]) == QImode
17021 || GET_MODE (operands[0]) == HImode)
17022 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17023 && peep2_regno_dead_p (0, FLAGS_REG)"
17024 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17025 (clobber (reg:CC FLAGS_REG))])])
17027 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17029 [(set (match_operand:SWI248 0 "register_operand" "")
17031 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17032 && peep2_regno_dead_p (0, FLAGS_REG)"
17033 [(parallel [(set (match_dup 0) (const_int -1))
17034 (clobber (reg:CC FLAGS_REG))])]
17036 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17037 operands[0] = gen_lowpart (SImode, operands[0]);
17040 ;; Attempt to convert simple lea to add/shift.
17041 ;; These can be created by move expanders.
17044 [(set (match_operand:SWI48 0 "register_operand" "")
17045 (plus:SWI48 (match_dup 0)
17046 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17047 "peep2_regno_dead_p (0, FLAGS_REG)"
17048 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17049 (clobber (reg:CC FLAGS_REG))])])
17052 [(set (match_operand:SI 0 "register_operand" "")
17053 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17054 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17056 && peep2_regno_dead_p (0, FLAGS_REG)
17057 && REGNO (operands[0]) == REGNO (operands[1])"
17058 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17059 (clobber (reg:CC FLAGS_REG))])]
17060 "operands[2] = gen_lowpart (SImode, operands[2]);")
17063 [(set (match_operand:SWI48 0 "register_operand" "")
17064 (mult:SWI48 (match_dup 0)
17065 (match_operand:SWI48 1 "const_int_operand" "")))]
17066 "exact_log2 (INTVAL (operands[1])) >= 0
17067 && peep2_regno_dead_p (0, FLAGS_REG)"
17068 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17069 (clobber (reg:CC FLAGS_REG))])]
17070 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17073 [(set (match_operand:SI 0 "register_operand" "")
17074 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17075 (match_operand:DI 2 "const_int_operand" "")) 0))]
17077 && exact_log2 (INTVAL (operands[2])) >= 0
17078 && REGNO (operands[0]) == REGNO (operands[1])
17079 && peep2_regno_dead_p (0, FLAGS_REG)"
17080 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17081 (clobber (reg:CC FLAGS_REG))])]
17082 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17084 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17085 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17086 ;; On many CPUs it is also faster, since special hardware to avoid esp
17087 ;; dependencies is present.
17089 ;; While some of these conversions may be done using splitters, we use
17090 ;; peepholes in order to allow combine_stack_adjustments pass to see
17091 ;; nonobfuscated RTL.
17093 ;; Convert prologue esp subtractions to push.
17094 ;; We need register to push. In order to keep verify_flow_info happy we have
17096 ;; - use scratch and clobber it in order to avoid dependencies
17097 ;; - use already live register
17098 ;; We can't use the second way right now, since there is no reliable way how to
17099 ;; verify that given register is live. First choice will also most likely in
17100 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17101 ;; call clobbered registers are dead. We may want to use base pointer as an
17102 ;; alternative when no register is available later.
17105 [(match_scratch:P 1 "r")
17106 (parallel [(set (reg:P SP_REG)
17107 (plus:P (reg:P SP_REG)
17108 (match_operand:P 0 "const_int_operand" "")))
17109 (clobber (reg:CC FLAGS_REG))
17110 (clobber (mem:BLK (scratch)))])]
17111 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17112 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17113 [(clobber (match_dup 1))
17114 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17115 (clobber (mem:BLK (scratch)))])])
17118 [(match_scratch:P 1 "r")
17119 (parallel [(set (reg:P SP_REG)
17120 (plus:P (reg:P SP_REG)
17121 (match_operand:P 0 "const_int_operand" "")))
17122 (clobber (reg:CC FLAGS_REG))
17123 (clobber (mem:BLK (scratch)))])]
17124 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17125 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17126 [(clobber (match_dup 1))
17127 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17128 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17129 (clobber (mem:BLK (scratch)))])])
17131 ;; Convert esp subtractions to push.
17133 [(match_scratch:P 1 "r")
17134 (parallel [(set (reg:P SP_REG)
17135 (plus:P (reg:P SP_REG)
17136 (match_operand:P 0 "const_int_operand" "")))
17137 (clobber (reg:CC FLAGS_REG))])]
17138 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17139 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17140 [(clobber (match_dup 1))
17141 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17144 [(match_scratch:P 1 "r")
17145 (parallel [(set (reg:P SP_REG)
17146 (plus:P (reg:P SP_REG)
17147 (match_operand:P 0 "const_int_operand" "")))
17148 (clobber (reg:CC FLAGS_REG))])]
17149 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17150 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17151 [(clobber (match_dup 1))
17152 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17153 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17155 ;; Convert epilogue deallocator to pop.
17157 [(match_scratch:P 1 "r")
17158 (parallel [(set (reg:P SP_REG)
17159 (plus:P (reg:P SP_REG)
17160 (match_operand:P 0 "const_int_operand" "")))
17161 (clobber (reg:CC FLAGS_REG))
17162 (clobber (mem:BLK (scratch)))])]
17163 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17164 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17165 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17166 (clobber (mem:BLK (scratch)))])])
17168 ;; Two pops case is tricky, since pop causes dependency
17169 ;; on destination register. We use two registers if available.
17171 [(match_scratch:P 1 "r")
17172 (match_scratch:P 2 "r")
17173 (parallel [(set (reg:P SP_REG)
17174 (plus:P (reg:P SP_REG)
17175 (match_operand:P 0 "const_int_operand" "")))
17176 (clobber (reg:CC FLAGS_REG))
17177 (clobber (mem:BLK (scratch)))])]
17178 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17179 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17180 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17181 (clobber (mem:BLK (scratch)))])
17182 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17185 [(match_scratch:P 1 "r")
17186 (parallel [(set (reg:P SP_REG)
17187 (plus:P (reg:P SP_REG)
17188 (match_operand:P 0 "const_int_operand" "")))
17189 (clobber (reg:CC FLAGS_REG))
17190 (clobber (mem:BLK (scratch)))])]
17191 "optimize_insn_for_size_p ()
17192 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17193 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17194 (clobber (mem:BLK (scratch)))])
17195 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17197 ;; Convert esp additions to pop.
17199 [(match_scratch:P 1 "r")
17200 (parallel [(set (reg:P SP_REG)
17201 (plus:P (reg:P SP_REG)
17202 (match_operand:P 0 "const_int_operand" "")))
17203 (clobber (reg:CC FLAGS_REG))])]
17204 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17205 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17207 ;; Two pops case is tricky, since pop causes dependency
17208 ;; on destination register. We use two registers if available.
17210 [(match_scratch:P 1 "r")
17211 (match_scratch:P 2 "r")
17212 (parallel [(set (reg:P SP_REG)
17213 (plus:P (reg:P SP_REG)
17214 (match_operand:P 0 "const_int_operand" "")))
17215 (clobber (reg:CC FLAGS_REG))])]
17216 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17217 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17218 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
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 "optimize_insn_for_size_p ()
17227 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17228 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17229 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17231 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17232 ;; required and register dies. Similarly for 128 to -128.
17234 [(set (match_operand 0 "flags_reg_operand" "")
17235 (match_operator 1 "compare_operator"
17236 [(match_operand 2 "register_operand" "")
17237 (match_operand 3 "const_int_operand" "")]))]
17238 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17239 && incdec_operand (operands[3], GET_MODE (operands[3])))
17240 || (!TARGET_FUSE_CMP_AND_BRANCH
17241 && INTVAL (operands[3]) == 128))
17242 && ix86_match_ccmode (insn, CCGCmode)
17243 && peep2_reg_dead_p (1, operands[2])"
17244 [(parallel [(set (match_dup 0)
17245 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17246 (clobber (match_dup 2))])])
17248 ;; Convert imul by three, five and nine into lea
17251 [(set (match_operand:SWI48 0 "register_operand" "")
17252 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17253 (match_operand:SWI48 2 "const_int_operand" "")))
17254 (clobber (reg:CC FLAGS_REG))])]
17255 "INTVAL (operands[2]) == 3
17256 || INTVAL (operands[2]) == 5
17257 || INTVAL (operands[2]) == 9"
17258 [(set (match_dup 0)
17259 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17261 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17265 [(set (match_operand:SWI48 0 "register_operand" "")
17266 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17267 (match_operand:SWI48 2 "const_int_operand" "")))
17268 (clobber (reg:CC FLAGS_REG))])]
17269 "optimize_insn_for_speed_p ()
17270 && (INTVAL (operands[2]) == 3
17271 || INTVAL (operands[2]) == 5
17272 || INTVAL (operands[2]) == 9)"
17273 [(set (match_dup 0) (match_dup 1))
17275 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17277 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17279 ;; imul $32bit_imm, mem, reg is vector decoded, while
17280 ;; imul $32bit_imm, reg, reg is direct decoded.
17282 [(match_scratch:SWI48 3 "r")
17283 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17284 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17285 (match_operand:SWI48 2 "immediate_operand" "")))
17286 (clobber (reg:CC FLAGS_REG))])]
17287 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17288 && !satisfies_constraint_K (operands[2])"
17289 [(set (match_dup 3) (match_dup 1))
17290 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17291 (clobber (reg:CC FLAGS_REG))])])
17294 [(match_scratch:SI 3 "r")
17295 (parallel [(set (match_operand:DI 0 "register_operand" "")
17297 (mult:SI (match_operand:SI 1 "memory_operand" "")
17298 (match_operand:SI 2 "immediate_operand" ""))))
17299 (clobber (reg:CC FLAGS_REG))])]
17301 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17302 && !satisfies_constraint_K (operands[2])"
17303 [(set (match_dup 3) (match_dup 1))
17304 (parallel [(set (match_dup 0)
17305 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17306 (clobber (reg:CC FLAGS_REG))])])
17308 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17309 ;; Convert it into imul reg, reg
17310 ;; It would be better to force assembler to encode instruction using long
17311 ;; immediate, but there is apparently no way to do so.
17313 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17315 (match_operand:SWI248 1 "nonimmediate_operand" "")
17316 (match_operand:SWI248 2 "const_int_operand" "")))
17317 (clobber (reg:CC FLAGS_REG))])
17318 (match_scratch:SWI248 3 "r")]
17319 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17320 && satisfies_constraint_K (operands[2])"
17321 [(set (match_dup 3) (match_dup 2))
17322 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17323 (clobber (reg:CC FLAGS_REG))])]
17325 if (!rtx_equal_p (operands[0], operands[1]))
17326 emit_move_insn (operands[0], operands[1]);
17329 ;; After splitting up read-modify operations, array accesses with memory
17330 ;; operands might end up in form:
17332 ;; movl 4(%esp), %edx
17334 ;; instead of pre-splitting:
17336 ;; addl 4(%esp), %eax
17338 ;; movl 4(%esp), %edx
17339 ;; leal (%edx,%eax,4), %eax
17342 [(match_scratch:P 5 "r")
17343 (parallel [(set (match_operand 0 "register_operand" "")
17344 (ashift (match_operand 1 "register_operand" "")
17345 (match_operand 2 "const_int_operand" "")))
17346 (clobber (reg:CC FLAGS_REG))])
17347 (parallel [(set (match_operand 3 "register_operand" "")
17348 (plus (match_dup 0)
17349 (match_operand 4 "x86_64_general_operand" "")))
17350 (clobber (reg:CC FLAGS_REG))])]
17351 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17352 /* Validate MODE for lea. */
17353 && ((!TARGET_PARTIAL_REG_STALL
17354 && (GET_MODE (operands[0]) == QImode
17355 || GET_MODE (operands[0]) == HImode))
17356 || GET_MODE (operands[0]) == SImode
17357 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17358 && (rtx_equal_p (operands[0], operands[3])
17359 || peep2_reg_dead_p (2, operands[0]))
17360 /* We reorder load and the shift. */
17361 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17362 [(set (match_dup 5) (match_dup 4))
17363 (set (match_dup 0) (match_dup 1))]
17365 enum machine_mode op1mode = GET_MODE (operands[1]);
17366 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17367 int scale = 1 << INTVAL (operands[2]);
17368 rtx index = gen_lowpart (Pmode, operands[1]);
17369 rtx base = gen_lowpart (Pmode, operands[5]);
17370 rtx dest = gen_lowpart (mode, operands[3]);
17372 operands[1] = gen_rtx_PLUS (Pmode, base,
17373 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17374 operands[5] = base;
17376 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17377 if (op1mode != Pmode)
17378 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17379 operands[0] = dest;
17382 ;; Call-value patterns last so that the wildcard operand does not
17383 ;; disrupt insn-recog's switch tables.
17385 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17387 [(set (match_operand 0 "" "")
17388 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17389 (match_operand:SI 2 "" "")))
17390 (set (reg:SI SP_REG)
17391 (plus:SI (reg:SI SP_REG)
17392 (match_operand:SI 3 "immediate_operand" "")))])
17393 (unspec [(match_operand 4 "const_int_operand" "")]
17394 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17395 "TARGET_VZEROUPPER && !TARGET_64BIT"
17397 "&& reload_completed"
17399 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17400 [(set_attr "type" "callv")])
17402 (define_insn "*call_value_pop_0"
17403 [(set (match_operand 0 "" "")
17404 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17405 (match_operand:SI 2 "" "")))
17406 (set (reg:SI SP_REG)
17407 (plus:SI (reg:SI SP_REG)
17408 (match_operand:SI 3 "immediate_operand" "")))]
17410 { return ix86_output_call_insn (insn, operands[1], 1); }
17411 [(set_attr "type" "callv")])
17413 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17415 [(set (match_operand 0 "" "")
17416 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17417 (match_operand:SI 2 "" "")))
17418 (set (reg:SI SP_REG)
17419 (plus:SI (reg:SI SP_REG)
17420 (match_operand:SI 3 "immediate_operand" "i")))])
17421 (unspec [(match_operand 4 "const_int_operand" "")]
17422 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17423 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17425 "&& reload_completed"
17427 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17428 [(set_attr "type" "callv")])
17430 (define_insn "*call_value_pop_1"
17431 [(set (match_operand 0 "" "")
17432 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17433 (match_operand:SI 2 "" "")))
17434 (set (reg:SI SP_REG)
17435 (plus:SI (reg:SI SP_REG)
17436 (match_operand:SI 3 "immediate_operand" "i")))]
17437 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17438 { return ix86_output_call_insn (insn, operands[1], 1); }
17439 [(set_attr "type" "callv")])
17441 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17443 [(set (match_operand 0 "" "")
17444 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17445 (match_operand:SI 2 "" "")))
17446 (set (reg:SI SP_REG)
17447 (plus:SI (reg:SI SP_REG)
17448 (match_operand:SI 3 "immediate_operand" "i,i")))])
17449 (unspec [(match_operand 4 "const_int_operand" "")]
17450 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17451 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17453 "&& reload_completed"
17455 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17456 [(set_attr "type" "callv")])
17458 (define_insn "*sibcall_value_pop_1"
17459 [(set (match_operand 0 "" "")
17460 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17461 (match_operand:SI 2 "" "")))
17462 (set (reg:SI SP_REG)
17463 (plus:SI (reg:SI SP_REG)
17464 (match_operand:SI 3 "immediate_operand" "i,i")))]
17465 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17466 { return ix86_output_call_insn (insn, operands[1], 1); }
17467 [(set_attr "type" "callv")])
17469 (define_insn_and_split "*call_value_0_vzeroupper"
17470 [(set (match_operand 0 "" "")
17471 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17472 (match_operand:SI 2 "" "")))
17473 (unspec [(match_operand 3 "const_int_operand" "")]
17474 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17475 "TARGET_VZEROUPPER && !TARGET_64BIT"
17477 "&& reload_completed"
17479 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17480 [(set_attr "type" "callv")])
17482 (define_insn "*call_value_0"
17483 [(set (match_operand 0 "" "")
17484 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17485 (match_operand:SI 2 "" "")))]
17487 { return ix86_output_call_insn (insn, operands[1], 1); }
17488 [(set_attr "type" "callv")])
17490 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17491 [(set (match_operand 0 "" "")
17492 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17493 (match_operand:DI 2 "const_int_operand" "")))
17494 (unspec [(match_operand 3 "const_int_operand" "")]
17495 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17496 "TARGET_VZEROUPPER && TARGET_64BIT"
17498 "&& reload_completed"
17500 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17501 [(set_attr "type" "callv")])
17503 (define_insn "*call_value_0_rex64"
17504 [(set (match_operand 0 "" "")
17505 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17506 (match_operand:DI 2 "const_int_operand" "")))]
17508 { return ix86_output_call_insn (insn, operands[1], 1); }
17509 [(set_attr "type" "callv")])
17511 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17513 [(set (match_operand 0 "" "")
17514 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17515 (match_operand:DI 2 "const_int_operand" "")))
17516 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17517 (clobber (reg:TI XMM6_REG))
17518 (clobber (reg:TI XMM7_REG))
17519 (clobber (reg:TI XMM8_REG))
17520 (clobber (reg:TI XMM9_REG))
17521 (clobber (reg:TI XMM10_REG))
17522 (clobber (reg:TI XMM11_REG))
17523 (clobber (reg:TI XMM12_REG))
17524 (clobber (reg:TI XMM13_REG))
17525 (clobber (reg:TI XMM14_REG))
17526 (clobber (reg:TI XMM15_REG))
17527 (clobber (reg:DI SI_REG))
17528 (clobber (reg:DI DI_REG))])
17529 (unspec [(match_operand 3 "const_int_operand" "")]
17530 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17531 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17533 "&& reload_completed"
17535 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17536 [(set_attr "type" "callv")])
17538 (define_insn "*call_value_0_rex64_ms_sysv"
17539 [(set (match_operand 0 "" "")
17540 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17541 (match_operand:DI 2 "const_int_operand" "")))
17542 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17543 (clobber (reg:TI XMM6_REG))
17544 (clobber (reg:TI XMM7_REG))
17545 (clobber (reg:TI XMM8_REG))
17546 (clobber (reg:TI XMM9_REG))
17547 (clobber (reg:TI XMM10_REG))
17548 (clobber (reg:TI XMM11_REG))
17549 (clobber (reg:TI XMM12_REG))
17550 (clobber (reg:TI XMM13_REG))
17551 (clobber (reg:TI XMM14_REG))
17552 (clobber (reg:TI XMM15_REG))
17553 (clobber (reg:DI SI_REG))
17554 (clobber (reg:DI DI_REG))]
17555 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17556 { return ix86_output_call_insn (insn, operands[1], 1); }
17557 [(set_attr "type" "callv")])
17559 (define_insn_and_split "*call_value_1_vzeroupper"
17560 [(set (match_operand 0 "" "")
17561 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17562 (match_operand:SI 2 "" "")))
17563 (unspec [(match_operand 3 "const_int_operand" "")]
17564 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17565 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17567 "&& reload_completed"
17569 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17570 [(set_attr "type" "callv")])
17572 (define_insn "*call_value_1"
17573 [(set (match_operand 0 "" "")
17574 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17575 (match_operand:SI 2 "" "")))]
17576 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17577 { return ix86_output_call_insn (insn, operands[1], 1); }
17578 [(set_attr "type" "callv")])
17580 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17581 [(set (match_operand 0 "" "")
17582 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17583 (match_operand:SI 2 "" "")))
17584 (unspec [(match_operand 3 "const_int_operand" "")]
17585 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17586 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17588 "&& reload_completed"
17590 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17591 [(set_attr "type" "callv")])
17593 (define_insn "*sibcall_value_1"
17594 [(set (match_operand 0 "" "")
17595 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17596 (match_operand:SI 2 "" "")))]
17597 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17598 { return ix86_output_call_insn (insn, operands[1], 1); }
17599 [(set_attr "type" "callv")])
17601 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17602 [(set (match_operand 0 "" "")
17603 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17604 (match_operand:DI 2 "" "")))
17605 (unspec [(match_operand 3 "const_int_operand" "")]
17606 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17607 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17608 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17610 "&& reload_completed"
17612 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17613 [(set_attr "type" "callv")])
17615 (define_insn "*call_value_1_rex64"
17616 [(set (match_operand 0 "" "")
17617 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17618 (match_operand:DI 2 "" "")))]
17619 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17620 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17621 { return ix86_output_call_insn (insn, operands[1], 1); }
17622 [(set_attr "type" "callv")])
17624 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17626 [(set (match_operand 0 "" "")
17627 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17628 (match_operand:DI 2 "" "")))
17629 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17630 (clobber (reg:TI XMM6_REG))
17631 (clobber (reg:TI XMM7_REG))
17632 (clobber (reg:TI XMM8_REG))
17633 (clobber (reg:TI XMM9_REG))
17634 (clobber (reg:TI XMM10_REG))
17635 (clobber (reg:TI XMM11_REG))
17636 (clobber (reg:TI XMM12_REG))
17637 (clobber (reg:TI XMM13_REG))
17638 (clobber (reg:TI XMM14_REG))
17639 (clobber (reg:TI XMM15_REG))
17640 (clobber (reg:DI SI_REG))
17641 (clobber (reg:DI DI_REG))])
17642 (unspec [(match_operand 3 "const_int_operand" "")]
17643 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17644 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17646 "&& reload_completed"
17648 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17649 [(set_attr "type" "callv")])
17651 (define_insn "*call_value_1_rex64_ms_sysv"
17652 [(set (match_operand 0 "" "")
17653 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17654 (match_operand:DI 2 "" "")))
17655 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17656 (clobber (reg:TI XMM6_REG))
17657 (clobber (reg:TI XMM7_REG))
17658 (clobber (reg:TI XMM8_REG))
17659 (clobber (reg:TI XMM9_REG))
17660 (clobber (reg:TI XMM10_REG))
17661 (clobber (reg:TI XMM11_REG))
17662 (clobber (reg:TI XMM12_REG))
17663 (clobber (reg:TI XMM13_REG))
17664 (clobber (reg:TI XMM14_REG))
17665 (clobber (reg:TI XMM15_REG))
17666 (clobber (reg:DI SI_REG))
17667 (clobber (reg:DI DI_REG))]
17668 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17669 { return ix86_output_call_insn (insn, operands[1], 1); }
17670 [(set_attr "type" "callv")])
17672 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17673 [(set (match_operand 0 "" "")
17674 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17675 (match_operand:DI 2 "" "")))
17676 (unspec [(match_operand 3 "const_int_operand" "")]
17677 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17678 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17680 "&& reload_completed"
17682 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17683 [(set_attr "type" "callv")])
17685 (define_insn "*call_value_1_rex64_large"
17686 [(set (match_operand 0 "" "")
17687 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17688 (match_operand:DI 2 "" "")))]
17689 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17690 { return ix86_output_call_insn (insn, operands[1], 1); }
17691 [(set_attr "type" "callv")])
17693 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17694 [(set (match_operand 0 "" "")
17695 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17696 (match_operand:DI 2 "" "")))
17697 (unspec [(match_operand 3 "const_int_operand" "")]
17698 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17699 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17701 "&& reload_completed"
17703 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17704 [(set_attr "type" "callv")])
17706 (define_insn "*sibcall_value_1_rex64"
17707 [(set (match_operand 0 "" "")
17708 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17709 (match_operand:DI 2 "" "")))]
17710 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17711 { return ix86_output_call_insn (insn, operands[1], 1); }
17712 [(set_attr "type" "callv")])
17714 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17715 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17716 ;; caught for use by garbage collectors and the like. Using an insn that
17717 ;; maps to SIGILL makes it more likely the program will rightfully die.
17718 ;; Keeping with tradition, "6" is in honor of #UD.
17719 (define_insn "trap"
17720 [(trap_if (const_int 1) (const_int 6))]
17722 { return ASM_SHORT "0x0b0f"; }
17723 [(set_attr "length" "2")])
17725 (define_expand "prefetch"
17726 [(prefetch (match_operand 0 "address_operand" "")
17727 (match_operand:SI 1 "const_int_operand" "")
17728 (match_operand:SI 2 "const_int_operand" ""))]
17729 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17731 int rw = INTVAL (operands[1]);
17732 int locality = INTVAL (operands[2]);
17734 gcc_assert (rw == 0 || rw == 1);
17735 gcc_assert (locality >= 0 && locality <= 3);
17736 gcc_assert (GET_MODE (operands[0]) == Pmode
17737 || GET_MODE (operands[0]) == VOIDmode);
17739 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17740 supported by SSE counterpart or the SSE prefetch is not available
17741 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17743 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17744 operands[2] = GEN_INT (3);
17746 operands[1] = const0_rtx;
17749 (define_insn "*prefetch_sse_<mode>"
17750 [(prefetch (match_operand:P 0 "address_operand" "p")
17752 (match_operand:SI 1 "const_int_operand" ""))]
17753 "TARGET_PREFETCH_SSE"
17755 static const char * const patterns[4] = {
17756 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17759 int locality = INTVAL (operands[1]);
17760 gcc_assert (locality >= 0 && locality <= 3);
17762 return patterns[locality];
17764 [(set_attr "type" "sse")
17765 (set_attr "atom_sse_attr" "prefetch")
17766 (set (attr "length_address")
17767 (symbol_ref "memory_address_length (operands[0])"))
17768 (set_attr "memory" "none")])
17770 (define_insn "*prefetch_3dnow_<mode>"
17771 [(prefetch (match_operand:P 0 "address_operand" "p")
17772 (match_operand:SI 1 "const_int_operand" "n")
17776 if (INTVAL (operands[1]) == 0)
17777 return "prefetch\t%a0";
17779 return "prefetchw\t%a0";
17781 [(set_attr "type" "mmx")
17782 (set (attr "length_address")
17783 (symbol_ref "memory_address_length (operands[0])"))
17784 (set_attr "memory" "none")])
17786 (define_expand "stack_protect_set"
17787 [(match_operand 0 "memory_operand" "")
17788 (match_operand 1 "memory_operand" "")]
17791 rtx (*insn)(rtx, rtx);
17793 #ifdef TARGET_THREAD_SSP_OFFSET
17794 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17795 insn = (TARGET_64BIT
17796 ? gen_stack_tls_protect_set_di
17797 : gen_stack_tls_protect_set_si);
17799 insn = (TARGET_64BIT
17800 ? gen_stack_protect_set_di
17801 : gen_stack_protect_set_si);
17804 emit_insn (insn (operands[0], operands[1]));
17808 (define_insn "stack_protect_set_<mode>"
17809 [(set (match_operand:P 0 "memory_operand" "=m")
17810 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17811 (set (match_scratch:P 2 "=&r") (const_int 0))
17812 (clobber (reg:CC FLAGS_REG))]
17814 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17815 [(set_attr "type" "multi")])
17817 (define_insn "stack_tls_protect_set_<mode>"
17818 [(set (match_operand:P 0 "memory_operand" "=m")
17819 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17820 UNSPEC_SP_TLS_SET))
17821 (set (match_scratch:P 2 "=&r") (const_int 0))
17822 (clobber (reg:CC FLAGS_REG))]
17824 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17825 [(set_attr "type" "multi")])
17827 (define_expand "stack_protect_test"
17828 [(match_operand 0 "memory_operand" "")
17829 (match_operand 1 "memory_operand" "")
17830 (match_operand 2 "" "")]
17833 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17835 rtx (*insn)(rtx, rtx, rtx);
17837 #ifdef TARGET_THREAD_SSP_OFFSET
17838 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17839 insn = (TARGET_64BIT
17840 ? gen_stack_tls_protect_test_di
17841 : gen_stack_tls_protect_test_si);
17843 insn = (TARGET_64BIT
17844 ? gen_stack_protect_test_di
17845 : gen_stack_protect_test_si);
17848 emit_insn (insn (flags, operands[0], operands[1]));
17850 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17851 flags, const0_rtx, operands[2]));
17855 (define_insn "stack_protect_test_<mode>"
17856 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17857 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17858 (match_operand:P 2 "memory_operand" "m")]
17860 (clobber (match_scratch:P 3 "=&r"))]
17862 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17863 [(set_attr "type" "multi")])
17865 (define_insn "stack_tls_protect_test_<mode>"
17866 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17867 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17868 (match_operand:P 2 "const_int_operand" "i")]
17869 UNSPEC_SP_TLS_TEST))
17870 (clobber (match_scratch:P 3 "=r"))]
17872 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17873 [(set_attr "type" "multi")])
17875 (define_insn "sse4_2_crc32<mode>"
17876 [(set (match_operand:SI 0 "register_operand" "=r")
17878 [(match_operand:SI 1 "register_operand" "0")
17879 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17881 "TARGET_SSE4_2 || TARGET_CRC32"
17882 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17883 [(set_attr "type" "sselog1")
17884 (set_attr "prefix_rep" "1")
17885 (set_attr "prefix_extra" "1")
17886 (set (attr "prefix_data16")
17887 (if_then_else (match_operand:HI 2 "" "")
17889 (const_string "*")))
17890 (set (attr "prefix_rex")
17891 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17893 (const_string "*")))
17894 (set_attr "mode" "SI")])
17896 (define_insn "sse4_2_crc32di"
17897 [(set (match_operand:DI 0 "register_operand" "=r")
17899 [(match_operand:DI 1 "register_operand" "0")
17900 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17902 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17903 "crc32{q}\t{%2, %0|%0, %2}"
17904 [(set_attr "type" "sselog1")
17905 (set_attr "prefix_rep" "1")
17906 (set_attr "prefix_extra" "1")
17907 (set_attr "mode" "DI")])
17909 (define_expand "rdpmc"
17910 [(match_operand:DI 0 "register_operand" "")
17911 (match_operand:SI 1 "register_operand" "")]
17914 rtx reg = gen_reg_rtx (DImode);
17917 /* Force operand 1 into ECX. */
17918 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17919 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17920 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17925 rtvec vec = rtvec_alloc (2);
17926 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17927 rtx upper = gen_reg_rtx (DImode);
17928 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17929 gen_rtvec (1, const0_rtx),
17931 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17932 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17934 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17935 NULL, 1, OPTAB_DIRECT);
17936 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17940 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17941 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17945 (define_insn "*rdpmc"
17946 [(set (match_operand:DI 0 "register_operand" "=A")
17947 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17951 [(set_attr "type" "other")
17952 (set_attr "length" "2")])
17954 (define_insn "*rdpmc_rex64"
17955 [(set (match_operand:DI 0 "register_operand" "=a")
17956 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17958 (set (match_operand:DI 1 "register_operand" "=d")
17959 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17962 [(set_attr "type" "other")
17963 (set_attr "length" "2")])
17965 (define_expand "rdtsc"
17966 [(set (match_operand:DI 0 "register_operand" "")
17967 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17972 rtvec vec = rtvec_alloc (2);
17973 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17974 rtx upper = gen_reg_rtx (DImode);
17975 rtx lower = gen_reg_rtx (DImode);
17976 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17977 gen_rtvec (1, const0_rtx),
17979 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17980 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17982 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17983 NULL, 1, OPTAB_DIRECT);
17984 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17986 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17991 (define_insn "*rdtsc"
17992 [(set (match_operand:DI 0 "register_operand" "=A")
17993 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17996 [(set_attr "type" "other")
17997 (set_attr "length" "2")])
17999 (define_insn "*rdtsc_rex64"
18000 [(set (match_operand:DI 0 "register_operand" "=a")
18001 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18002 (set (match_operand:DI 1 "register_operand" "=d")
18003 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18006 [(set_attr "type" "other")
18007 (set_attr "length" "2")])
18009 (define_expand "rdtscp"
18010 [(match_operand:DI 0 "register_operand" "")
18011 (match_operand:SI 1 "memory_operand" "")]
18014 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18015 gen_rtvec (1, const0_rtx),
18017 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18018 gen_rtvec (1, const0_rtx),
18020 rtx reg = gen_reg_rtx (DImode);
18021 rtx tmp = gen_reg_rtx (SImode);
18025 rtvec vec = rtvec_alloc (3);
18026 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18027 rtx upper = gen_reg_rtx (DImode);
18028 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18029 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18030 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18032 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18033 NULL, 1, OPTAB_DIRECT);
18034 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18039 rtvec vec = rtvec_alloc (2);
18040 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18041 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18042 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18045 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18046 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18050 (define_insn "*rdtscp"
18051 [(set (match_operand:DI 0 "register_operand" "=A")
18052 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18053 (set (match_operand:SI 1 "register_operand" "=c")
18054 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18057 [(set_attr "type" "other")
18058 (set_attr "length" "3")])
18060 (define_insn "*rdtscp_rex64"
18061 [(set (match_operand:DI 0 "register_operand" "=a")
18062 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18063 (set (match_operand:DI 1 "register_operand" "=d")
18064 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18065 (set (match_operand:SI 2 "register_operand" "=c")
18066 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18069 [(set_attr "type" "other")
18070 (set_attr "length" "3")])
18072 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18074 ;; LWP instructions
18076 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18078 (define_expand "lwp_llwpcb"
18079 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18080 UNSPECV_LLWP_INTRINSIC)]
18083 (define_insn "*lwp_llwpcb<mode>1"
18084 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18085 UNSPECV_LLWP_INTRINSIC)]
18088 [(set_attr "type" "lwp")
18089 (set_attr "mode" "<MODE>")
18090 (set_attr "length" "5")])
18092 (define_expand "lwp_slwpcb"
18093 [(set (match_operand 0 "register_operand" "=r")
18094 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18099 insn = (TARGET_64BIT
18101 : gen_lwp_slwpcbsi);
18103 emit_insn (insn (operands[0]));
18107 (define_insn "lwp_slwpcb<mode>"
18108 [(set (match_operand:P 0 "register_operand" "=r")
18109 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18112 [(set_attr "type" "lwp")
18113 (set_attr "mode" "<MODE>")
18114 (set_attr "length" "5")])
18116 (define_expand "lwp_lwpval<mode>3"
18117 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18118 (match_operand:SI 2 "nonimmediate_operand" "rm")
18119 (match_operand:SI 3 "const_int_operand" "i")]
18120 UNSPECV_LWPVAL_INTRINSIC)]
18122 "/* Avoid unused variable warning. */
18125 (define_insn "*lwp_lwpval<mode>3_1"
18126 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18127 (match_operand:SI 1 "nonimmediate_operand" "rm")
18128 (match_operand:SI 2 "const_int_operand" "i")]
18129 UNSPECV_LWPVAL_INTRINSIC)]
18131 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18132 [(set_attr "type" "lwp")
18133 (set_attr "mode" "<MODE>")
18134 (set (attr "length")
18135 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18137 (define_expand "lwp_lwpins<mode>3"
18138 [(set (reg:CCC FLAGS_REG)
18139 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18140 (match_operand:SI 2 "nonimmediate_operand" "rm")
18141 (match_operand:SI 3 "const_int_operand" "i")]
18142 UNSPECV_LWPINS_INTRINSIC))
18143 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18144 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18147 (define_insn "*lwp_lwpins<mode>3_1"
18148 [(set (reg:CCC FLAGS_REG)
18149 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18150 (match_operand:SI 1 "nonimmediate_operand" "rm")
18151 (match_operand:SI 2 "const_int_operand" "i")]
18152 UNSPECV_LWPINS_INTRINSIC))]
18154 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18155 [(set_attr "type" "lwp")
18156 (set_attr "mode" "<MODE>")
18157 (set (attr "length")
18158 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18160 (define_insn "rdfsbase<mode>"
18161 [(set (match_operand:SWI48 0 "register_operand" "=r")
18162 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18163 "TARGET_64BIT && TARGET_FSGSBASE"
18165 [(set_attr "type" "other")
18166 (set_attr "prefix_extra" "2")])
18168 (define_insn "rdgsbase<mode>"
18169 [(set (match_operand:SWI48 0 "register_operand" "=r")
18170 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18171 "TARGET_64BIT && TARGET_FSGSBASE"
18173 [(set_attr "type" "other")
18174 (set_attr "prefix_extra" "2")])
18176 (define_insn "wrfsbase<mode>"
18177 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18179 "TARGET_64BIT && TARGET_FSGSBASE"
18181 [(set_attr "type" "other")
18182 (set_attr "prefix_extra" "2")])
18184 (define_insn "wrgsbase<mode>"
18185 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18187 "TARGET_64BIT && TARGET_FSGSBASE"
18189 [(set_attr "type" "other")
18190 (set_attr "prefix_extra" "2")])
18192 (define_insn "rdrand<mode>_1"
18193 [(set (match_operand:SWI248 0 "register_operand" "=r")
18194 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18195 (set (reg:CCC FLAGS_REG)
18196 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18199 [(set_attr "type" "other")
18200 (set_attr "prefix_extra" "1")])
18204 (include "sync.md")