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 && (reload_in_progress || reload_completed
2870 || GET_CODE (operands[1]) != CONST_DOUBLE
2871 || memory_operand (operands[0], XFmode))"
2873 switch (which_alternative)
2877 return output_387_reg_move (insn, operands);
2880 return standard_80387_constant_opcode (operands[1]);
2889 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2890 (set_attr "mode" "XF,XF,XF,SI,SI")])
2892 ;; Do not use integer registers when optimizing for size
2893 (define_insn "*movxf_internal_nointeger"
2894 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2895 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2896 "optimize_function_for_size_p (cfun)
2897 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2898 && (reload_in_progress || reload_completed
2899 || standard_80387_constant_p (operands[1])
2900 || GET_CODE (operands[1]) != CONST_DOUBLE
2901 || memory_operand (operands[0], XFmode))"
2903 switch (which_alternative)
2907 return output_387_reg_move (insn, operands);
2910 return standard_80387_constant_opcode (operands[1]);
2918 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2919 (set_attr "mode" "XF,XF,XF,SI,SI")])
2922 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2923 (match_operand:XF 1 "general_operand" ""))]
2925 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2926 && ! (FP_REG_P (operands[0]) ||
2927 (GET_CODE (operands[0]) == SUBREG
2928 && FP_REG_P (SUBREG_REG (operands[0]))))
2929 && ! (FP_REG_P (operands[1]) ||
2930 (GET_CODE (operands[1]) == SUBREG
2931 && FP_REG_P (SUBREG_REG (operands[1]))))"
2933 "ix86_split_long_move (operands); DONE;")
2935 (define_insn "*movdf_internal_rex64"
2936 [(set (match_operand:DF 0 "nonimmediate_operand"
2937 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2938 (match_operand:DF 1 "general_operand"
2939 "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2940 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2941 && (reload_in_progress || reload_completed
2942 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2943 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2944 && optimize_function_for_size_p (cfun)
2945 && standard_80387_constant_p (operands[1]))
2946 || GET_CODE (operands[1]) != CONST_DOUBLE
2947 || memory_operand (operands[0], DFmode))"
2949 switch (which_alternative)
2953 return output_387_reg_move (insn, operands);
2956 return standard_80387_constant_opcode (operands[1]);
2960 return "mov{q}\t{%1, %0|%0, %1}";
2963 return "movabs{q}\t{%1, %0|%0, %1}";
2969 switch (get_attr_mode (insn))
2972 return "%vxorps\t%0, %d0";
2974 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2975 return "%vxorps\t%0, %d0";
2977 return "%vxorpd\t%0, %d0";
2979 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2980 return "%vxorps\t%0, %d0";
2982 return "%vpxor\t%0, %d0";
2989 switch (get_attr_mode (insn))
2992 return "%vmovaps\t{%1, %0|%0, %1}";
2994 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2995 return "%vmovaps\t{%1, %0|%0, %1}";
2997 return "%vmovapd\t{%1, %0|%0, %1}";
2999 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3000 return "%vmovaps\t{%1, %0|%0, %1}";
3002 return "%vmovdqa\t{%1, %0|%0, %1}";
3004 return "%vmovq\t{%1, %0|%0, %1}";
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 && (reload_in_progress || reload_completed
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 && (reload_in_progress || reload_completed
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 || reload_in_progress || reload_completed)
3268 && memory_operand (operands[0], DFmode)))"
3270 switch (which_alternative)
3274 return output_387_reg_move (insn, operands);
3277 return standard_80387_constant_opcode (operands[1]);
3284 switch (get_attr_mode (insn))
3287 return "%vxorps\t%0, %d0";
3289 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3290 return "%vxorps\t%0, %d0";
3292 return "%vxorpd\t%0, %d0";
3294 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3295 return "%vxorps\t%0, %d0";
3297 return "%vpxor\t%0, %d0";
3304 switch (get_attr_mode (insn))
3307 return "%vmovaps\t{%1, %0|%0, %1}";
3309 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3310 return "%vmovaps\t{%1, %0|%0, %1}";
3312 return "%vmovapd\t{%1, %0|%0, %1}";
3314 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3315 return "%vmovaps\t{%1, %0|%0, %1}";
3317 return "%vmovdqa\t{%1, %0|%0, %1}";
3319 return "%vmovq\t{%1, %0|%0, %1}";
3321 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3322 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3324 return "%vmovsd\t{%1, %0|%0, %1}";
3326 if (TARGET_AVX && REG_P (operands[0]))
3327 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3329 return "%vmovlpd\t{%1, %0|%0, %1}";
3331 if (TARGET_AVX && REG_P (operands[0]))
3332 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3334 return "%vmovlps\t{%1, %0|%0, %1}";
3343 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3344 (set (attr "prefix")
3345 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3346 (const_string "orig")
3347 (const_string "maybe_vex")))
3348 (set (attr "prefix_data16")
3349 (if_then_else (eq_attr "mode" "V1DF")
3351 (const_string "*")))
3353 (cond [(eq_attr "alternative" "0,1,2")
3355 (eq_attr "alternative" "3,4")
3358 /* For SSE1, we have many fewer alternatives. */
3359 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3360 (cond [(eq_attr "alternative" "5,6")
3361 (const_string "V4SF")
3363 (const_string "V2SF"))
3365 /* xorps is one byte shorter. */
3366 (eq_attr "alternative" "5")
3367 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3369 (const_string "V4SF")
3370 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3374 (const_string "V2DF"))
3376 /* For architectures resolving dependencies on
3377 whole SSE registers use APD move to break dependency
3378 chains, otherwise use short move to avoid extra work.
3380 movaps encodes one byte shorter. */
3381 (eq_attr "alternative" "6")
3383 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3385 (const_string "V4SF")
3386 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3388 (const_string "V2DF")
3390 (const_string "DF"))
3391 /* For architectures resolving dependencies on register
3392 parts we may avoid extra work to zero out upper part
3394 (eq_attr "alternative" "7")
3396 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3398 (const_string "V1DF")
3399 (const_string "DF"))
3401 (const_string "DF")))])
3404 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3405 (match_operand:DF 1 "general_operand" ""))]
3407 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3408 && ! (ANY_FP_REG_P (operands[0]) ||
3409 (GET_CODE (operands[0]) == SUBREG
3410 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3411 && ! (ANY_FP_REG_P (operands[1]) ||
3412 (GET_CODE (operands[1]) == SUBREG
3413 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3415 "ix86_split_long_move (operands); DONE;")
3417 (define_insn "*movsf_internal"
3418 [(set (match_operand:SF 0 "nonimmediate_operand"
3419 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3420 (match_operand:SF 1 "general_operand"
3421 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3422 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3423 && (reload_in_progress || reload_completed
3424 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3425 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3426 && standard_80387_constant_p (operands[1]))
3427 || GET_CODE (operands[1]) != CONST_DOUBLE
3428 || memory_operand (operands[0], SFmode))"
3430 switch (which_alternative)
3434 return output_387_reg_move (insn, operands);
3437 return standard_80387_constant_opcode (operands[1]);
3441 return "mov{l}\t{%1, %0|%0, %1}";
3443 if (get_attr_mode (insn) == MODE_TI)
3444 return "%vpxor\t%0, %d0";
3446 return "%vxorps\t%0, %d0";
3448 if (get_attr_mode (insn) == MODE_V4SF)
3449 return "%vmovaps\t{%1, %0|%0, %1}";
3451 return "%vmovss\t{%1, %d0|%d0, %1}";
3453 if (TARGET_AVX && REG_P (operands[1]))
3454 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3456 return "%vmovss\t{%1, %0|%0, %1}";
3458 return "%vmovss\t{%1, %0|%0, %1}";
3460 case 9: case 10: case 14: case 15:
3461 return "movd\t{%1, %0|%0, %1}";
3464 return "movq\t{%1, %0|%0, %1}";
3467 return "%vmovd\t{%1, %0|%0, %1}";
3473 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3474 (set (attr "prefix")
3475 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3476 (const_string "maybe_vex")
3477 (const_string "orig")))
3479 (cond [(eq_attr "alternative" "3,4,9,10")
3481 (eq_attr "alternative" "5")
3483 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3485 (ne (symbol_ref "TARGET_SSE2")
3487 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3490 (const_string "V4SF"))
3491 /* For architectures resolving dependencies on
3492 whole SSE registers use APS move to break dependency
3493 chains, otherwise use short move to avoid extra work.
3495 Do the same for architectures resolving dependencies on
3496 the parts. While in DF mode it is better to always handle
3497 just register parts, the SF mode is different due to lack
3498 of instructions to load just part of the register. It is
3499 better to maintain the whole registers in single format
3500 to avoid problems on using packed logical operations. */
3501 (eq_attr "alternative" "6")
3503 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3505 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3507 (const_string "V4SF")
3508 (const_string "SF"))
3509 (eq_attr "alternative" "11")
3510 (const_string "DI")]
3511 (const_string "SF")))])
3514 [(set (match_operand 0 "register_operand" "")
3515 (match_operand 1 "memory_operand" ""))]
3517 && MEM_P (operands[1])
3518 && (GET_MODE (operands[0]) == TFmode
3519 || GET_MODE (operands[0]) == XFmode
3520 || GET_MODE (operands[0]) == DFmode
3521 || GET_MODE (operands[0]) == SFmode)
3522 && (operands[2] = find_constant_src (insn))"
3523 [(set (match_dup 0) (match_dup 2))]
3525 rtx c = operands[2];
3526 rtx r = operands[0];
3528 if (GET_CODE (r) == SUBREG)
3533 if (!standard_sse_constant_p (c))
3536 else if (FP_REG_P (r))
3538 if (!standard_80387_constant_p (c))
3541 else if (MMX_REG_P (r))
3546 [(set (match_operand 0 "register_operand" "")
3547 (float_extend (match_operand 1 "memory_operand" "")))]
3549 && MEM_P (operands[1])
3550 && (GET_MODE (operands[0]) == TFmode
3551 || GET_MODE (operands[0]) == XFmode
3552 || GET_MODE (operands[0]) == DFmode
3553 || GET_MODE (operands[0]) == SFmode)
3554 && (operands[2] = find_constant_src (insn))"
3555 [(set (match_dup 0) (match_dup 2))]
3557 rtx c = operands[2];
3558 rtx r = operands[0];
3560 if (GET_CODE (r) == SUBREG)
3565 if (!standard_sse_constant_p (c))
3568 else if (FP_REG_P (r))
3570 if (!standard_80387_constant_p (c))
3573 else if (MMX_REG_P (r))
3577 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3579 [(set (match_operand:X87MODEF 0 "register_operand" "")
3580 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3581 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3582 && (standard_80387_constant_p (operands[1]) == 8
3583 || standard_80387_constant_p (operands[1]) == 9)"
3584 [(set (match_dup 0)(match_dup 1))
3586 (neg:X87MODEF (match_dup 0)))]
3590 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3591 if (real_isnegzero (&r))
3592 operands[1] = CONST0_RTX (<MODE>mode);
3594 operands[1] = CONST1_RTX (<MODE>mode);
3597 (define_insn "swapxf"
3598 [(set (match_operand:XF 0 "register_operand" "+f")
3599 (match_operand:XF 1 "register_operand" "+f"))
3604 if (STACK_TOP_P (operands[0]))
3609 [(set_attr "type" "fxch")
3610 (set_attr "mode" "XF")])
3612 (define_insn "*swap<mode>"
3613 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3614 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3617 "TARGET_80387 || reload_completed"
3619 if (STACK_TOP_P (operands[0]))
3624 [(set_attr "type" "fxch")
3625 (set_attr "mode" "<MODE>")])
3627 ;; Zero extension instructions
3629 (define_expand "zero_extendsidi2"
3630 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3631 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3636 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3641 (define_insn "*zero_extendsidi2_rex64"
3642 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3644 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3647 mov\t{%k1, %k0|%k0, %k1}
3649 movd\t{%1, %0|%0, %1}
3650 movd\t{%1, %0|%0, %1}
3651 %vmovd\t{%1, %0|%0, %1}
3652 %vmovd\t{%1, %0|%0, %1}"
3653 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3654 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3655 (set_attr "prefix_0f" "0,*,*,*,*,*")
3656 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3659 [(set (match_operand:DI 0 "memory_operand" "")
3660 (zero_extend:DI (match_dup 0)))]
3662 [(set (match_dup 4) (const_int 0))]
3663 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3665 ;; %%% Kill me once multi-word ops are sane.
3666 (define_insn "zero_extendsidi2_1"
3667 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3669 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3670 (clobber (reg:CC FLAGS_REG))]
3676 movd\t{%1, %0|%0, %1}
3677 movd\t{%1, %0|%0, %1}
3678 %vmovd\t{%1, %0|%0, %1}
3679 %vmovd\t{%1, %0|%0, %1}"
3680 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3681 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3682 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3685 [(set (match_operand:DI 0 "register_operand" "")
3686 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3687 (clobber (reg:CC FLAGS_REG))]
3688 "!TARGET_64BIT && reload_completed
3689 && true_regnum (operands[0]) == true_regnum (operands[1])"
3690 [(set (match_dup 4) (const_int 0))]
3691 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3694 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3695 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3696 (clobber (reg:CC FLAGS_REG))]
3697 "!TARGET_64BIT && reload_completed
3698 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3699 [(set (match_dup 3) (match_dup 1))
3700 (set (match_dup 4) (const_int 0))]
3701 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3703 (define_insn "zero_extend<mode>di2"
3704 [(set (match_operand:DI 0 "register_operand" "=r")
3706 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3708 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3709 [(set_attr "type" "imovx")
3710 (set_attr "mode" "SI")])
3712 (define_expand "zero_extendhisi2"
3713 [(set (match_operand:SI 0 "register_operand" "")
3714 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3717 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3719 operands[1] = force_reg (HImode, operands[1]);
3720 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3725 (define_insn_and_split "zero_extendhisi2_and"
3726 [(set (match_operand:SI 0 "register_operand" "=r")
3727 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3728 (clobber (reg:CC FLAGS_REG))]
3729 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3731 "&& reload_completed"
3732 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3733 (clobber (reg:CC FLAGS_REG))])]
3735 [(set_attr "type" "alu1")
3736 (set_attr "mode" "SI")])
3738 (define_insn "*zero_extendhisi2_movzwl"
3739 [(set (match_operand:SI 0 "register_operand" "=r")
3740 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3741 "!TARGET_ZERO_EXTEND_WITH_AND
3742 || optimize_function_for_size_p (cfun)"
3743 "movz{wl|x}\t{%1, %0|%0, %1}"
3744 [(set_attr "type" "imovx")
3745 (set_attr "mode" "SI")])
3747 (define_expand "zero_extendqi<mode>2"
3749 [(set (match_operand:SWI24 0 "register_operand" "")
3750 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3751 (clobber (reg:CC FLAGS_REG))])])
3753 (define_insn "*zero_extendqi<mode>2_and"
3754 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3755 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3756 (clobber (reg:CC FLAGS_REG))]
3757 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3759 [(set_attr "type" "alu1")
3760 (set_attr "mode" "<MODE>")])
3762 ;; When source and destination does not overlap, clear destination
3763 ;; first and then do the movb
3765 [(set (match_operand:SWI24 0 "register_operand" "")
3766 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3767 (clobber (reg:CC FLAGS_REG))]
3769 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3770 && ANY_QI_REG_P (operands[0])
3771 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3772 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3773 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3775 operands[2] = gen_lowpart (QImode, operands[0]);
3776 ix86_expand_clear (operands[0]);
3779 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3780 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3781 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3782 (clobber (reg:CC FLAGS_REG))]
3783 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3785 [(set_attr "type" "imovx,alu1")
3786 (set_attr "mode" "<MODE>")])
3788 ;; For the movzbl case strip only the clobber
3790 [(set (match_operand:SWI24 0 "register_operand" "")
3791 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3792 (clobber (reg:CC FLAGS_REG))]
3794 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3795 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3797 (zero_extend:SWI24 (match_dup 1)))])
3799 ; zero extend to SImode to avoid partial register stalls
3800 (define_insn "*zero_extendqi<mode>2_movzbl"
3801 [(set (match_operand:SWI24 0 "register_operand" "=r")
3802 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3804 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3805 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3806 [(set_attr "type" "imovx")
3807 (set_attr "mode" "SI")])
3809 ;; Rest is handled by single and.
3811 [(set (match_operand:SWI24 0 "register_operand" "")
3812 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3813 (clobber (reg:CC FLAGS_REG))]
3815 && true_regnum (operands[0]) == true_regnum (operands[1])"
3816 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3817 (clobber (reg:CC FLAGS_REG))])])
3819 ;; Sign extension instructions
3821 (define_expand "extendsidi2"
3822 [(set (match_operand:DI 0 "register_operand" "")
3823 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3828 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3833 (define_insn "*extendsidi2_rex64"
3834 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3835 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3839 movs{lq|x}\t{%1, %0|%0, %1}"
3840 [(set_attr "type" "imovx")
3841 (set_attr "mode" "DI")
3842 (set_attr "prefix_0f" "0")
3843 (set_attr "modrm" "0,1")])
3845 (define_insn "extendsidi2_1"
3846 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3847 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3848 (clobber (reg:CC FLAGS_REG))
3849 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3853 ;; Extend to memory case when source register does die.
3855 [(set (match_operand:DI 0 "memory_operand" "")
3856 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3857 (clobber (reg:CC FLAGS_REG))
3858 (clobber (match_operand:SI 2 "register_operand" ""))]
3860 && dead_or_set_p (insn, operands[1])
3861 && !reg_mentioned_p (operands[1], operands[0]))"
3862 [(set (match_dup 3) (match_dup 1))
3863 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3864 (clobber (reg:CC FLAGS_REG))])
3865 (set (match_dup 4) (match_dup 1))]
3866 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3868 ;; Extend to memory case when source register does not die.
3870 [(set (match_operand:DI 0 "memory_operand" "")
3871 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3872 (clobber (reg:CC FLAGS_REG))
3873 (clobber (match_operand:SI 2 "register_operand" ""))]
3877 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3879 emit_move_insn (operands[3], operands[1]);
3881 /* Generate a cltd if possible and doing so it profitable. */
3882 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3883 && true_regnum (operands[1]) == AX_REG
3884 && true_regnum (operands[2]) == DX_REG)
3886 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3890 emit_move_insn (operands[2], operands[1]);
3891 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3893 emit_move_insn (operands[4], operands[2]);
3897 ;; Extend to register case. Optimize case where source and destination
3898 ;; registers match and cases where we can use cltd.
3900 [(set (match_operand:DI 0 "register_operand" "")
3901 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3902 (clobber (reg:CC FLAGS_REG))
3903 (clobber (match_scratch:SI 2 ""))]
3907 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3909 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3910 emit_move_insn (operands[3], operands[1]);
3912 /* Generate a cltd if possible and doing so it profitable. */
3913 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3914 && true_regnum (operands[3]) == AX_REG
3915 && true_regnum (operands[4]) == DX_REG)
3917 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3921 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3922 emit_move_insn (operands[4], operands[1]);
3924 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3928 (define_insn "extend<mode>di2"
3929 [(set (match_operand:DI 0 "register_operand" "=r")
3931 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3933 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3934 [(set_attr "type" "imovx")
3935 (set_attr "mode" "DI")])
3937 (define_insn "extendhisi2"
3938 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3939 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3942 switch (get_attr_prefix_0f (insn))
3945 return "{cwtl|cwde}";
3947 return "movs{wl|x}\t{%1, %0|%0, %1}";
3950 [(set_attr "type" "imovx")
3951 (set_attr "mode" "SI")
3952 (set (attr "prefix_0f")
3953 ;; movsx is short decodable while cwtl is vector decoded.
3954 (if_then_else (and (eq_attr "cpu" "!k6")
3955 (eq_attr "alternative" "0"))
3957 (const_string "1")))
3959 (if_then_else (eq_attr "prefix_0f" "0")
3961 (const_string "1")))])
3963 (define_insn "*extendhisi2_zext"
3964 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3967 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3970 switch (get_attr_prefix_0f (insn))
3973 return "{cwtl|cwde}";
3975 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3978 [(set_attr "type" "imovx")
3979 (set_attr "mode" "SI")
3980 (set (attr "prefix_0f")
3981 ;; movsx is short decodable while cwtl is vector decoded.
3982 (if_then_else (and (eq_attr "cpu" "!k6")
3983 (eq_attr "alternative" "0"))
3985 (const_string "1")))
3987 (if_then_else (eq_attr "prefix_0f" "0")
3989 (const_string "1")))])
3991 (define_insn "extendqisi2"
3992 [(set (match_operand:SI 0 "register_operand" "=r")
3993 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3995 "movs{bl|x}\t{%1, %0|%0, %1}"
3996 [(set_attr "type" "imovx")
3997 (set_attr "mode" "SI")])
3999 (define_insn "*extendqisi2_zext"
4000 [(set (match_operand:DI 0 "register_operand" "=r")
4002 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4004 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4005 [(set_attr "type" "imovx")
4006 (set_attr "mode" "SI")])
4008 (define_insn "extendqihi2"
4009 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4010 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4013 switch (get_attr_prefix_0f (insn))
4016 return "{cbtw|cbw}";
4018 return "movs{bw|x}\t{%1, %0|%0, %1}";
4021 [(set_attr "type" "imovx")
4022 (set_attr "mode" "HI")
4023 (set (attr "prefix_0f")
4024 ;; movsx is short decodable while cwtl is vector decoded.
4025 (if_then_else (and (eq_attr "cpu" "!k6")
4026 (eq_attr "alternative" "0"))
4028 (const_string "1")))
4030 (if_then_else (eq_attr "prefix_0f" "0")
4032 (const_string "1")))])
4034 ;; Conversions between float and double.
4036 ;; These are all no-ops in the model used for the 80387.
4037 ;; So just emit moves.
4039 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4041 [(set (match_operand:DF 0 "push_operand" "")
4042 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4044 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4045 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4048 [(set (match_operand:XF 0 "push_operand" "")
4049 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4051 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4052 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4053 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4055 (define_expand "extendsfdf2"
4056 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4057 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4058 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4060 /* ??? Needed for compress_float_constant since all fp constants
4061 are TARGET_LEGITIMATE_CONSTANT_P. */
4062 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4064 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4065 && standard_80387_constant_p (operands[1]) > 0)
4067 operands[1] = simplify_const_unary_operation
4068 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4069 emit_move_insn_1 (operands[0], operands[1]);
4072 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4076 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4078 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4080 We do the conversion post reload to avoid producing of 128bit spills
4081 that might lead to ICE on 32bit target. The sequence unlikely combine
4084 [(set (match_operand:DF 0 "register_operand" "")
4086 (match_operand:SF 1 "nonimmediate_operand" "")))]
4087 "TARGET_USE_VECTOR_FP_CONVERTS
4088 && optimize_insn_for_speed_p ()
4089 && reload_completed && SSE_REG_P (operands[0])"
4094 (parallel [(const_int 0) (const_int 1)]))))]
4096 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4097 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4098 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4099 Try to avoid move when unpacking can be done in source. */
4100 if (REG_P (operands[1]))
4102 /* If it is unsafe to overwrite upper half of source, we need
4103 to move to destination and unpack there. */
4104 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4105 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4106 && true_regnum (operands[0]) != true_regnum (operands[1]))
4108 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4109 emit_move_insn (tmp, operands[1]);
4112 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4113 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4117 emit_insn (gen_vec_setv4sf_0 (operands[3],
4118 CONST0_RTX (V4SFmode), operands[1]));
4121 (define_insn "*extendsfdf2_mixed"
4122 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4124 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4125 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4127 switch (which_alternative)
4131 return output_387_reg_move (insn, operands);
4134 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4140 [(set_attr "type" "fmov,fmov,ssecvt")
4141 (set_attr "prefix" "orig,orig,maybe_vex")
4142 (set_attr "mode" "SF,XF,DF")])
4144 (define_insn "*extendsfdf2_sse"
4145 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4146 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4147 "TARGET_SSE2 && TARGET_SSE_MATH"
4148 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4149 [(set_attr "type" "ssecvt")
4150 (set_attr "prefix" "maybe_vex")
4151 (set_attr "mode" "DF")])
4153 (define_insn "*extendsfdf2_i387"
4154 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4155 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4157 "* return output_387_reg_move (insn, operands);"
4158 [(set_attr "type" "fmov")
4159 (set_attr "mode" "SF,XF")])
4161 (define_expand "extend<mode>xf2"
4162 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4163 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4166 /* ??? Needed for compress_float_constant since all fp constants
4167 are TARGET_LEGITIMATE_CONSTANT_P. */
4168 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4170 if (standard_80387_constant_p (operands[1]) > 0)
4172 operands[1] = simplify_const_unary_operation
4173 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4174 emit_move_insn_1 (operands[0], operands[1]);
4177 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4181 (define_insn "*extend<mode>xf2_i387"
4182 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4184 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4186 "* return output_387_reg_move (insn, operands);"
4187 [(set_attr "type" "fmov")
4188 (set_attr "mode" "<MODE>,XF")])
4190 ;; %%% This seems bad bad news.
4191 ;; This cannot output into an f-reg because there is no way to be sure
4192 ;; of truncating in that case. Otherwise this is just like a simple move
4193 ;; insn. So we pretend we can output to a reg in order to get better
4194 ;; register preferencing, but we really use a stack slot.
4196 ;; Conversion from DFmode to SFmode.
4198 (define_expand "truncdfsf2"
4199 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4201 (match_operand:DF 1 "nonimmediate_operand" "")))]
4202 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4204 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4206 else if (flag_unsafe_math_optimizations)
4210 enum ix86_stack_slot slot = (virtuals_instantiated
4213 rtx temp = assign_386_stack_local (SFmode, slot);
4214 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4219 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4221 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4223 We do the conversion post reload to avoid producing of 128bit spills
4224 that might lead to ICE on 32bit target. The sequence unlikely combine
4227 [(set (match_operand:SF 0 "register_operand" "")
4229 (match_operand:DF 1 "nonimmediate_operand" "")))]
4230 "TARGET_USE_VECTOR_FP_CONVERTS
4231 && optimize_insn_for_speed_p ()
4232 && reload_completed && SSE_REG_P (operands[0])"
4235 (float_truncate:V2SF
4239 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4240 operands[3] = CONST0_RTX (V2SFmode);
4241 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4242 /* Use movsd for loading from memory, unpcklpd for registers.
4243 Try to avoid move when unpacking can be done in source, or SSE3
4244 movddup is available. */
4245 if (REG_P (operands[1]))
4248 && true_regnum (operands[0]) != true_regnum (operands[1])
4249 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4250 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4252 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4253 emit_move_insn (tmp, operands[1]);
4256 else if (!TARGET_SSE3)
4257 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4258 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4261 emit_insn (gen_sse2_loadlpd (operands[4],
4262 CONST0_RTX (V2DFmode), operands[1]));
4265 (define_expand "truncdfsf2_with_temp"
4266 [(parallel [(set (match_operand:SF 0 "" "")
4267 (float_truncate:SF (match_operand:DF 1 "" "")))
4268 (clobber (match_operand:SF 2 "" ""))])])
4270 (define_insn "*truncdfsf_fast_mixed"
4271 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4273 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4274 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4276 switch (which_alternative)
4279 return output_387_reg_move (insn, operands);
4281 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4286 [(set_attr "type" "fmov,ssecvt")
4287 (set_attr "prefix" "orig,maybe_vex")
4288 (set_attr "mode" "SF")])
4290 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4291 ;; because nothing we do here is unsafe.
4292 (define_insn "*truncdfsf_fast_sse"
4293 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4295 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4296 "TARGET_SSE2 && TARGET_SSE_MATH"
4297 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4298 [(set_attr "type" "ssecvt")
4299 (set_attr "prefix" "maybe_vex")
4300 (set_attr "mode" "SF")])
4302 (define_insn "*truncdfsf_fast_i387"
4303 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4305 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4306 "TARGET_80387 && flag_unsafe_math_optimizations"
4307 "* return output_387_reg_move (insn, operands);"
4308 [(set_attr "type" "fmov")
4309 (set_attr "mode" "SF")])
4311 (define_insn "*truncdfsf_mixed"
4312 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4314 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4315 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4316 "TARGET_MIX_SSE_I387"
4318 switch (which_alternative)
4321 return output_387_reg_move (insn, operands);
4323 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4329 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4330 (set_attr "unit" "*,*,i387,i387,i387")
4331 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4332 (set_attr "mode" "SF")])
4334 (define_insn "*truncdfsf_i387"
4335 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4337 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4338 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4341 switch (which_alternative)
4344 return output_387_reg_move (insn, operands);
4350 [(set_attr "type" "fmov,multi,multi,multi")
4351 (set_attr "unit" "*,i387,i387,i387")
4352 (set_attr "mode" "SF")])
4354 (define_insn "*truncdfsf2_i387_1"
4355 [(set (match_operand:SF 0 "memory_operand" "=m")
4357 (match_operand:DF 1 "register_operand" "f")))]
4359 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4360 && !TARGET_MIX_SSE_I387"
4361 "* return output_387_reg_move (insn, operands);"
4362 [(set_attr "type" "fmov")
4363 (set_attr "mode" "SF")])
4366 [(set (match_operand:SF 0 "register_operand" "")
4368 (match_operand:DF 1 "fp_register_operand" "")))
4369 (clobber (match_operand 2 "" ""))]
4371 [(set (match_dup 2) (match_dup 1))
4372 (set (match_dup 0) (match_dup 2))]
4373 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4375 ;; Conversion from XFmode to {SF,DF}mode
4377 (define_expand "truncxf<mode>2"
4378 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4379 (float_truncate:MODEF
4380 (match_operand:XF 1 "register_operand" "")))
4381 (clobber (match_dup 2))])]
4384 if (flag_unsafe_math_optimizations)
4386 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4387 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4388 if (reg != operands[0])
4389 emit_move_insn (operands[0], reg);
4394 enum ix86_stack_slot slot = (virtuals_instantiated
4397 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4401 (define_insn "*truncxfsf2_mixed"
4402 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4404 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4405 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4408 gcc_assert (!which_alternative);
4409 return output_387_reg_move (insn, operands);
4411 [(set_attr "type" "fmov,multi,multi,multi")
4412 (set_attr "unit" "*,i387,i387,i387")
4413 (set_attr "mode" "SF")])
4415 (define_insn "*truncxfdf2_mixed"
4416 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4418 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4419 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4422 gcc_assert (!which_alternative);
4423 return output_387_reg_move (insn, operands);
4425 [(set_attr "type" "fmov,multi,multi,multi")
4426 (set_attr "unit" "*,i387,i387,i387")
4427 (set_attr "mode" "DF")])
4429 (define_insn "truncxf<mode>2_i387_noop"
4430 [(set (match_operand:MODEF 0 "register_operand" "=f")
4431 (float_truncate:MODEF
4432 (match_operand:XF 1 "register_operand" "f")))]
4433 "TARGET_80387 && flag_unsafe_math_optimizations"
4434 "* return output_387_reg_move (insn, operands);"
4435 [(set_attr "type" "fmov")
4436 (set_attr "mode" "<MODE>")])
4438 (define_insn "*truncxf<mode>2_i387"
4439 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4440 (float_truncate:MODEF
4441 (match_operand:XF 1 "register_operand" "f")))]
4443 "* return output_387_reg_move (insn, operands);"
4444 [(set_attr "type" "fmov")
4445 (set_attr "mode" "<MODE>")])
4448 [(set (match_operand:MODEF 0 "register_operand" "")
4449 (float_truncate:MODEF
4450 (match_operand:XF 1 "register_operand" "")))
4451 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4452 "TARGET_80387 && reload_completed"
4453 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4454 (set (match_dup 0) (match_dup 2))])
4457 [(set (match_operand:MODEF 0 "memory_operand" "")
4458 (float_truncate:MODEF
4459 (match_operand:XF 1 "register_operand" "")))
4460 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4462 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4464 ;; Signed conversion to DImode.
4466 (define_expand "fix_truncxfdi2"
4467 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4468 (fix:DI (match_operand:XF 1 "register_operand" "")))
4469 (clobber (reg:CC FLAGS_REG))])]
4474 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4479 (define_expand "fix_trunc<mode>di2"
4480 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4481 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4482 (clobber (reg:CC FLAGS_REG))])]
4483 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4486 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4488 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4491 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4493 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4494 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4495 if (out != operands[0])
4496 emit_move_insn (operands[0], out);
4501 ;; Signed conversion to SImode.
4503 (define_expand "fix_truncxfsi2"
4504 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4505 (fix:SI (match_operand:XF 1 "register_operand" "")))
4506 (clobber (reg:CC FLAGS_REG))])]
4511 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4516 (define_expand "fix_trunc<mode>si2"
4517 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4518 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4519 (clobber (reg:CC FLAGS_REG))])]
4520 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4523 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4525 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4528 if (SSE_FLOAT_MODE_P (<MODE>mode))
4530 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4531 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4532 if (out != operands[0])
4533 emit_move_insn (operands[0], out);
4538 ;; Signed conversion to HImode.
4540 (define_expand "fix_trunc<mode>hi2"
4541 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4542 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4543 (clobber (reg:CC FLAGS_REG))])]
4545 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4549 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4554 ;; Unsigned conversion to SImode.
4556 (define_expand "fixuns_trunc<mode>si2"
4558 [(set (match_operand:SI 0 "register_operand" "")
4560 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4562 (clobber (match_scratch:<ssevecmode> 3 ""))
4563 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4564 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4566 enum machine_mode mode = <MODE>mode;
4567 enum machine_mode vecmode = <ssevecmode>mode;
4568 REAL_VALUE_TYPE TWO31r;
4571 if (optimize_insn_for_size_p ())
4574 real_ldexp (&TWO31r, &dconst1, 31);
4575 two31 = const_double_from_real_value (TWO31r, mode);
4576 two31 = ix86_build_const_vector (vecmode, true, two31);
4577 operands[2] = force_reg (vecmode, two31);
4580 (define_insn_and_split "*fixuns_trunc<mode>_1"
4581 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4583 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4584 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4585 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4586 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4587 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4588 && optimize_function_for_speed_p (cfun)"
4590 "&& reload_completed"
4593 ix86_split_convert_uns_si_sse (operands);
4597 ;; Unsigned conversion to HImode.
4598 ;; Without these patterns, we'll try the unsigned SI conversion which
4599 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4601 (define_expand "fixuns_trunc<mode>hi2"
4603 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4604 (set (match_operand:HI 0 "nonimmediate_operand" "")
4605 (subreg:HI (match_dup 2) 0))]
4606 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4607 "operands[2] = gen_reg_rtx (SImode);")
4609 ;; When SSE is available, it is always faster to use it!
4610 (define_insn "fix_trunc<mode>di_sse"
4611 [(set (match_operand:DI 0 "register_operand" "=r,r")
4612 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4613 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4614 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4615 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4616 [(set_attr "type" "sseicvt")
4617 (set_attr "prefix" "maybe_vex")
4618 (set_attr "prefix_rex" "1")
4619 (set_attr "mode" "<MODE>")
4620 (set_attr "athlon_decode" "double,vector")
4621 (set_attr "amdfam10_decode" "double,double")
4622 (set_attr "bdver1_decode" "double,double")])
4624 (define_insn "fix_trunc<mode>si_sse"
4625 [(set (match_operand:SI 0 "register_operand" "=r,r")
4626 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4627 "SSE_FLOAT_MODE_P (<MODE>mode)
4628 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4629 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4630 [(set_attr "type" "sseicvt")
4631 (set_attr "prefix" "maybe_vex")
4632 (set_attr "mode" "<MODE>")
4633 (set_attr "athlon_decode" "double,vector")
4634 (set_attr "amdfam10_decode" "double,double")
4635 (set_attr "bdver1_decode" "double,double")])
4637 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4639 [(set (match_operand:MODEF 0 "register_operand" "")
4640 (match_operand:MODEF 1 "memory_operand" ""))
4641 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4642 (fix:SSEMODEI24 (match_dup 0)))]
4643 "TARGET_SHORTEN_X87_SSE
4644 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4645 && peep2_reg_dead_p (2, operands[0])"
4646 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4648 ;; Avoid vector decoded forms of the instruction.
4650 [(match_scratch:DF 2 "Y2")
4651 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4652 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4653 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4654 [(set (match_dup 2) (match_dup 1))
4655 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4658 [(match_scratch:SF 2 "x")
4659 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4660 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4661 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4662 [(set (match_dup 2) (match_dup 1))
4663 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4665 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4666 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4667 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4668 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4670 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4671 && (TARGET_64BIT || <MODE>mode != DImode))
4673 && can_create_pseudo_p ()"
4678 if (memory_operand (operands[0], VOIDmode))
4679 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4682 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4683 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4689 [(set_attr "type" "fisttp")
4690 (set_attr "mode" "<MODE>")])
4692 (define_insn "fix_trunc<mode>_i387_fisttp"
4693 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4694 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4695 (clobber (match_scratch:XF 2 "=&1f"))]
4696 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4698 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4699 && (TARGET_64BIT || <MODE>mode != DImode))
4700 && TARGET_SSE_MATH)"
4701 "* return output_fix_trunc (insn, operands, 1);"
4702 [(set_attr "type" "fisttp")
4703 (set_attr "mode" "<MODE>")])
4705 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4706 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4707 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4708 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4709 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4710 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4712 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4713 && (TARGET_64BIT || <MODE>mode != DImode))
4714 && TARGET_SSE_MATH)"
4716 [(set_attr "type" "fisttp")
4717 (set_attr "mode" "<MODE>")])
4720 [(set (match_operand:X87MODEI 0 "register_operand" "")
4721 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4722 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4723 (clobber (match_scratch 3 ""))]
4725 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4726 (clobber (match_dup 3))])
4727 (set (match_dup 0) (match_dup 2))])
4730 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4731 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4732 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4733 (clobber (match_scratch 3 ""))]
4735 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4736 (clobber (match_dup 3))])])
4738 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4739 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4740 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4741 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4742 ;; function in i386.c.
4743 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4744 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4745 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4746 (clobber (reg:CC FLAGS_REG))]
4747 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4749 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4750 && (TARGET_64BIT || <MODE>mode != DImode))
4751 && can_create_pseudo_p ()"
4756 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4758 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4759 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4760 if (memory_operand (operands[0], VOIDmode))
4761 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4762 operands[2], operands[3]));
4765 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4766 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4767 operands[2], operands[3],
4772 [(set_attr "type" "fistp")
4773 (set_attr "i387_cw" "trunc")
4774 (set_attr "mode" "<MODE>")])
4776 (define_insn "fix_truncdi_i387"
4777 [(set (match_operand:DI 0 "memory_operand" "=m")
4778 (fix:DI (match_operand 1 "register_operand" "f")))
4779 (use (match_operand:HI 2 "memory_operand" "m"))
4780 (use (match_operand:HI 3 "memory_operand" "m"))
4781 (clobber (match_scratch:XF 4 "=&1f"))]
4782 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4784 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4785 "* return output_fix_trunc (insn, operands, 0);"
4786 [(set_attr "type" "fistp")
4787 (set_attr "i387_cw" "trunc")
4788 (set_attr "mode" "DI")])
4790 (define_insn "fix_truncdi_i387_with_temp"
4791 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4792 (fix:DI (match_operand 1 "register_operand" "f,f")))
4793 (use (match_operand:HI 2 "memory_operand" "m,m"))
4794 (use (match_operand:HI 3 "memory_operand" "m,m"))
4795 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4796 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4797 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4799 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4801 [(set_attr "type" "fistp")
4802 (set_attr "i387_cw" "trunc")
4803 (set_attr "mode" "DI")])
4806 [(set (match_operand:DI 0 "register_operand" "")
4807 (fix:DI (match_operand 1 "register_operand" "")))
4808 (use (match_operand:HI 2 "memory_operand" ""))
4809 (use (match_operand:HI 3 "memory_operand" ""))
4810 (clobber (match_operand:DI 4 "memory_operand" ""))
4811 (clobber (match_scratch 5 ""))]
4813 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4816 (clobber (match_dup 5))])
4817 (set (match_dup 0) (match_dup 4))])
4820 [(set (match_operand:DI 0 "memory_operand" "")
4821 (fix:DI (match_operand 1 "register_operand" "")))
4822 (use (match_operand:HI 2 "memory_operand" ""))
4823 (use (match_operand:HI 3 "memory_operand" ""))
4824 (clobber (match_operand:DI 4 "memory_operand" ""))
4825 (clobber (match_scratch 5 ""))]
4827 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4830 (clobber (match_dup 5))])])
4832 (define_insn "fix_trunc<mode>_i387"
4833 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4834 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4835 (use (match_operand:HI 2 "memory_operand" "m"))
4836 (use (match_operand:HI 3 "memory_operand" "m"))]
4837 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4839 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4840 "* return output_fix_trunc (insn, operands, 0);"
4841 [(set_attr "type" "fistp")
4842 (set_attr "i387_cw" "trunc")
4843 (set_attr "mode" "<MODE>")])
4845 (define_insn "fix_trunc<mode>_i387_with_temp"
4846 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4847 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4848 (use (match_operand:HI 2 "memory_operand" "m,m"))
4849 (use (match_operand:HI 3 "memory_operand" "m,m"))
4850 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4851 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4853 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4855 [(set_attr "type" "fistp")
4856 (set_attr "i387_cw" "trunc")
4857 (set_attr "mode" "<MODE>")])
4860 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4861 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4862 (use (match_operand:HI 2 "memory_operand" ""))
4863 (use (match_operand:HI 3 "memory_operand" ""))
4864 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4866 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4868 (use (match_dup 3))])
4869 (set (match_dup 0) (match_dup 4))])
4872 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4873 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4874 (use (match_operand:HI 2 "memory_operand" ""))
4875 (use (match_operand:HI 3 "memory_operand" ""))
4876 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4878 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4880 (use (match_dup 3))])])
4882 (define_insn "x86_fnstcw_1"
4883 [(set (match_operand:HI 0 "memory_operand" "=m")
4884 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4887 [(set (attr "length")
4888 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4889 (set_attr "mode" "HI")
4890 (set_attr "unit" "i387")
4891 (set_attr "bdver1_decode" "vector")])
4893 (define_insn "x86_fldcw_1"
4894 [(set (reg:HI FPCR_REG)
4895 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4898 [(set (attr "length")
4899 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4900 (set_attr "mode" "HI")
4901 (set_attr "unit" "i387")
4902 (set_attr "athlon_decode" "vector")
4903 (set_attr "amdfam10_decode" "vector")
4904 (set_attr "bdver1_decode" "vector")])
4906 ;; Conversion between fixed point and floating point.
4908 ;; Even though we only accept memory inputs, the backend _really_
4909 ;; wants to be able to do this between registers.
4911 (define_expand "floathi<mode>2"
4912 [(set (match_operand:X87MODEF 0 "register_operand" "")
4913 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4916 || TARGET_MIX_SSE_I387)")
4918 ;; Pre-reload splitter to add memory clobber to the pattern.
4919 (define_insn_and_split "*floathi<mode>2_1"
4920 [(set (match_operand:X87MODEF 0 "register_operand" "")
4921 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4923 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4924 || TARGET_MIX_SSE_I387)
4925 && can_create_pseudo_p ()"
4928 [(parallel [(set (match_dup 0)
4929 (float:X87MODEF (match_dup 1)))
4930 (clobber (match_dup 2))])]
4931 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4933 (define_insn "*floathi<mode>2_i387_with_temp"
4934 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4935 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4936 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4938 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4939 || TARGET_MIX_SSE_I387)"
4941 [(set_attr "type" "fmov,multi")
4942 (set_attr "mode" "<MODE>")
4943 (set_attr "unit" "*,i387")
4944 (set_attr "fp_int_src" "true")])
4946 (define_insn "*floathi<mode>2_i387"
4947 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4948 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4950 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4951 || TARGET_MIX_SSE_I387)"
4953 [(set_attr "type" "fmov")
4954 (set_attr "mode" "<MODE>")
4955 (set_attr "fp_int_src" "true")])
4958 [(set (match_operand:X87MODEF 0 "register_operand" "")
4959 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4960 (clobber (match_operand:HI 2 "memory_operand" ""))]
4962 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4963 || TARGET_MIX_SSE_I387)
4964 && reload_completed"
4965 [(set (match_dup 2) (match_dup 1))
4966 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4969 [(set (match_operand:X87MODEF 0 "register_operand" "")
4970 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4971 (clobber (match_operand:HI 2 "memory_operand" ""))]
4973 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4974 || TARGET_MIX_SSE_I387)
4975 && reload_completed"
4976 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4978 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4979 [(set (match_operand:X87MODEF 0 "register_operand" "")
4981 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4983 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4984 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4986 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4987 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4988 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4990 rtx reg = gen_reg_rtx (XFmode);
4991 rtx (*insn)(rtx, rtx);
4993 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4995 if (<X87MODEF:MODE>mode == SFmode)
4996 insn = gen_truncxfsf2;
4997 else if (<X87MODEF:MODE>mode == DFmode)
4998 insn = gen_truncxfdf2;
5002 emit_insn (insn (operands[0], reg));
5007 ;; Pre-reload splitter to add memory clobber to the pattern.
5008 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5009 [(set (match_operand:X87MODEF 0 "register_operand" "")
5010 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5012 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5013 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5014 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5015 || TARGET_MIX_SSE_I387))
5016 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5017 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5018 && ((<SSEMODEI24:MODE>mode == SImode
5019 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5020 && optimize_function_for_speed_p (cfun)
5021 && flag_trapping_math)
5022 || !(TARGET_INTER_UNIT_CONVERSIONS
5023 || optimize_function_for_size_p (cfun)))))
5024 && can_create_pseudo_p ()"
5027 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5028 (clobber (match_dup 2))])]
5030 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5032 /* Avoid store forwarding (partial memory) stall penalty
5033 by passing DImode value through XMM registers. */
5034 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5035 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5036 && optimize_function_for_speed_p (cfun))
5038 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5045 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5046 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5048 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5049 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5050 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5051 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5053 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5054 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5055 (set_attr "unit" "*,i387,*,*,*")
5056 (set_attr "athlon_decode" "*,*,double,direct,double")
5057 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5058 (set_attr "bdver1_decode" "*,*,double,direct,double")
5059 (set_attr "fp_int_src" "true")])
5061 (define_insn "*floatsi<mode>2_vector_mixed"
5062 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5063 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5064 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5065 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5069 [(set_attr "type" "fmov,sseicvt")
5070 (set_attr "mode" "<MODE>,<ssevecmode>")
5071 (set_attr "unit" "i387,*")
5072 (set_attr "athlon_decode" "*,direct")
5073 (set_attr "amdfam10_decode" "*,double")
5074 (set_attr "bdver1_decode" "*,direct")
5075 (set_attr "fp_int_src" "true")])
5077 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5078 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5080 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5081 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5082 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5083 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5085 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5086 (set_attr "mode" "<MODEF:MODE>")
5087 (set_attr "unit" "*,i387,*,*")
5088 (set_attr "athlon_decode" "*,*,double,direct")
5089 (set_attr "amdfam10_decode" "*,*,vector,double")
5090 (set_attr "bdver1_decode" "*,*,double,direct")
5091 (set_attr "fp_int_src" "true")])
5094 [(set (match_operand:MODEF 0 "register_operand" "")
5095 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5096 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5097 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5098 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5099 && TARGET_INTER_UNIT_CONVERSIONS
5101 && (SSE_REG_P (operands[0])
5102 || (GET_CODE (operands[0]) == SUBREG
5103 && SSE_REG_P (operands[0])))"
5104 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5107 [(set (match_operand:MODEF 0 "register_operand" "")
5108 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5109 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5110 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5111 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5112 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5114 && (SSE_REG_P (operands[0])
5115 || (GET_CODE (operands[0]) == SUBREG
5116 && SSE_REG_P (operands[0])))"
5117 [(set (match_dup 2) (match_dup 1))
5118 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5120 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5121 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5123 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5124 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5125 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5126 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5129 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5130 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5131 [(set_attr "type" "fmov,sseicvt,sseicvt")
5132 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5133 (set_attr "mode" "<MODEF:MODE>")
5134 (set (attr "prefix_rex")
5136 (and (eq_attr "prefix" "maybe_vex")
5137 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5139 (const_string "*")))
5140 (set_attr "unit" "i387,*,*")
5141 (set_attr "athlon_decode" "*,double,direct")
5142 (set_attr "amdfam10_decode" "*,vector,double")
5143 (set_attr "bdver1_decode" "*,double,direct")
5144 (set_attr "fp_int_src" "true")])
5146 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5147 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5149 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5150 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5151 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5152 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5155 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5156 [(set_attr "type" "fmov,sseicvt")
5157 (set_attr "prefix" "orig,maybe_vex")
5158 (set_attr "mode" "<MODEF:MODE>")
5159 (set (attr "prefix_rex")
5161 (and (eq_attr "prefix" "maybe_vex")
5162 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5164 (const_string "*")))
5165 (set_attr "athlon_decode" "*,direct")
5166 (set_attr "amdfam10_decode" "*,double")
5167 (set_attr "bdver1_decode" "*,direct")
5168 (set_attr "fp_int_src" "true")])
5170 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5171 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5173 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5174 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5175 "TARGET_SSE2 && TARGET_SSE_MATH
5176 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5178 [(set_attr "type" "sseicvt")
5179 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5180 (set_attr "athlon_decode" "double,direct,double")
5181 (set_attr "amdfam10_decode" "vector,double,double")
5182 (set_attr "bdver1_decode" "double,direct,double")
5183 (set_attr "fp_int_src" "true")])
5185 (define_insn "*floatsi<mode>2_vector_sse"
5186 [(set (match_operand:MODEF 0 "register_operand" "=x")
5187 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5188 "TARGET_SSE2 && TARGET_SSE_MATH
5189 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5191 [(set_attr "type" "sseicvt")
5192 (set_attr "mode" "<MODE>")
5193 (set_attr "athlon_decode" "direct")
5194 (set_attr "amdfam10_decode" "double")
5195 (set_attr "bdver1_decode" "direct")
5196 (set_attr "fp_int_src" "true")])
5199 [(set (match_operand:MODEF 0 "register_operand" "")
5200 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5201 (clobber (match_operand:SI 2 "memory_operand" ""))]
5202 "TARGET_SSE2 && TARGET_SSE_MATH
5203 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5205 && (SSE_REG_P (operands[0])
5206 || (GET_CODE (operands[0]) == SUBREG
5207 && SSE_REG_P (operands[0])))"
5210 rtx op1 = operands[1];
5212 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5214 if (GET_CODE (op1) == SUBREG)
5215 op1 = SUBREG_REG (op1);
5217 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5219 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5220 emit_insn (gen_sse2_loadld (operands[4],
5221 CONST0_RTX (V4SImode), operands[1]));
5223 /* We can ignore possible trapping value in the
5224 high part of SSE register for non-trapping math. */
5225 else if (SSE_REG_P (op1) && !flag_trapping_math)
5226 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5229 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5230 emit_move_insn (operands[2], operands[1]);
5231 emit_insn (gen_sse2_loadld (operands[4],
5232 CONST0_RTX (V4SImode), operands[2]));
5235 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5240 [(set (match_operand:MODEF 0 "register_operand" "")
5241 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5242 (clobber (match_operand:SI 2 "memory_operand" ""))]
5243 "TARGET_SSE2 && TARGET_SSE_MATH
5244 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5246 && (SSE_REG_P (operands[0])
5247 || (GET_CODE (operands[0]) == SUBREG
5248 && SSE_REG_P (operands[0])))"
5251 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5253 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5255 emit_insn (gen_sse2_loadld (operands[4],
5256 CONST0_RTX (V4SImode), operands[1]));
5258 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5263 [(set (match_operand:MODEF 0 "register_operand" "")
5264 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5265 "TARGET_SSE2 && TARGET_SSE_MATH
5266 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5268 && (SSE_REG_P (operands[0])
5269 || (GET_CODE (operands[0]) == SUBREG
5270 && SSE_REG_P (operands[0])))"
5273 rtx op1 = operands[1];
5275 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5277 if (GET_CODE (op1) == SUBREG)
5278 op1 = SUBREG_REG (op1);
5280 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5282 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5283 emit_insn (gen_sse2_loadld (operands[4],
5284 CONST0_RTX (V4SImode), operands[1]));
5286 /* We can ignore possible trapping value in the
5287 high part of SSE register for non-trapping math. */
5288 else if (SSE_REG_P (op1) && !flag_trapping_math)
5289 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5293 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5298 [(set (match_operand:MODEF 0 "register_operand" "")
5299 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5300 "TARGET_SSE2 && TARGET_SSE_MATH
5301 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5303 && (SSE_REG_P (operands[0])
5304 || (GET_CODE (operands[0]) == SUBREG
5305 && SSE_REG_P (operands[0])))"
5308 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5310 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5312 emit_insn (gen_sse2_loadld (operands[4],
5313 CONST0_RTX (V4SImode), operands[1]));
5315 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5319 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5320 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5322 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5323 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5324 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5325 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5327 [(set_attr "type" "sseicvt")
5328 (set_attr "mode" "<MODEF:MODE>")
5329 (set_attr "athlon_decode" "double,direct")
5330 (set_attr "amdfam10_decode" "vector,double")
5331 (set_attr "bdver1_decode" "double,direct")
5332 (set_attr "fp_int_src" "true")])
5334 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5335 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5337 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5338 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5339 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5340 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5341 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5342 [(set_attr "type" "sseicvt")
5343 (set_attr "prefix" "maybe_vex")
5344 (set_attr "mode" "<MODEF:MODE>")
5345 (set (attr "prefix_rex")
5347 (and (eq_attr "prefix" "maybe_vex")
5348 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5350 (const_string "*")))
5351 (set_attr "athlon_decode" "double,direct")
5352 (set_attr "amdfam10_decode" "vector,double")
5353 (set_attr "bdver1_decode" "double,direct")
5354 (set_attr "fp_int_src" "true")])
5357 [(set (match_operand:MODEF 0 "register_operand" "")
5358 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5359 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5360 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5361 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5362 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5364 && (SSE_REG_P (operands[0])
5365 || (GET_CODE (operands[0]) == SUBREG
5366 && SSE_REG_P (operands[0])))"
5367 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5369 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5370 [(set (match_operand:MODEF 0 "register_operand" "=x")
5372 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5373 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5374 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5375 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5376 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5377 [(set_attr "type" "sseicvt")
5378 (set_attr "prefix" "maybe_vex")
5379 (set_attr "mode" "<MODEF:MODE>")
5380 (set (attr "prefix_rex")
5382 (and (eq_attr "prefix" "maybe_vex")
5383 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5385 (const_string "*")))
5386 (set_attr "athlon_decode" "direct")
5387 (set_attr "amdfam10_decode" "double")
5388 (set_attr "bdver1_decode" "direct")
5389 (set_attr "fp_int_src" "true")])
5392 [(set (match_operand:MODEF 0 "register_operand" "")
5393 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5394 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5395 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5396 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5397 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5399 && (SSE_REG_P (operands[0])
5400 || (GET_CODE (operands[0]) == SUBREG
5401 && SSE_REG_P (operands[0])))"
5402 [(set (match_dup 2) (match_dup 1))
5403 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5406 [(set (match_operand:MODEF 0 "register_operand" "")
5407 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5408 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5409 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5410 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5412 && (SSE_REG_P (operands[0])
5413 || (GET_CODE (operands[0]) == SUBREG
5414 && SSE_REG_P (operands[0])))"
5415 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5417 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5418 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5420 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5421 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5423 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5427 [(set_attr "type" "fmov,multi")
5428 (set_attr "mode" "<X87MODEF:MODE>")
5429 (set_attr "unit" "*,i387")
5430 (set_attr "fp_int_src" "true")])
5432 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5433 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5435 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5437 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5439 [(set_attr "type" "fmov")
5440 (set_attr "mode" "<X87MODEF:MODE>")
5441 (set_attr "fp_int_src" "true")])
5444 [(set (match_operand:X87MODEF 0 "register_operand" "")
5445 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5446 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5448 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5450 && FP_REG_P (operands[0])"
5451 [(set (match_dup 2) (match_dup 1))
5452 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5455 [(set (match_operand:X87MODEF 0 "register_operand" "")
5456 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5457 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5459 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5461 && FP_REG_P (operands[0])"
5462 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5464 ;; Avoid store forwarding (partial memory) stall penalty
5465 ;; by passing DImode value through XMM registers. */
5467 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5468 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5470 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5471 (clobber (match_scratch:V4SI 3 "=X,x"))
5472 (clobber (match_scratch:V4SI 4 "=X,x"))
5473 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5474 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5475 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5476 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5478 [(set_attr "type" "multi")
5479 (set_attr "mode" "<X87MODEF:MODE>")
5480 (set_attr "unit" "i387")
5481 (set_attr "fp_int_src" "true")])
5484 [(set (match_operand:X87MODEF 0 "register_operand" "")
5485 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5486 (clobber (match_scratch:V4SI 3 ""))
5487 (clobber (match_scratch:V4SI 4 ""))
5488 (clobber (match_operand:DI 2 "memory_operand" ""))]
5489 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5490 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5491 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5493 && FP_REG_P (operands[0])"
5494 [(set (match_dup 2) (match_dup 3))
5495 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5497 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5498 Assemble the 64-bit DImode value in an xmm register. */
5499 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5500 gen_rtx_SUBREG (SImode, operands[1], 0)));
5501 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5502 gen_rtx_SUBREG (SImode, operands[1], 4)));
5503 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5506 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5510 [(set (match_operand:X87MODEF 0 "register_operand" "")
5511 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5512 (clobber (match_scratch:V4SI 3 ""))
5513 (clobber (match_scratch:V4SI 4 ""))
5514 (clobber (match_operand:DI 2 "memory_operand" ""))]
5515 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5516 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5517 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5519 && FP_REG_P (operands[0])"
5520 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5522 ;; Avoid store forwarding (partial memory) stall penalty by extending
5523 ;; SImode value to DImode through XMM register instead of pushing two
5524 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5525 ;; targets benefit from this optimization. Also note that fild
5526 ;; loads from memory only.
5528 (define_insn "*floatunssi<mode>2_1"
5529 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5530 (unsigned_float:X87MODEF
5531 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5532 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5533 (clobber (match_scratch:SI 3 "=X,x"))]
5535 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5538 [(set_attr "type" "multi")
5539 (set_attr "mode" "<MODE>")])
5542 [(set (match_operand:X87MODEF 0 "register_operand" "")
5543 (unsigned_float:X87MODEF
5544 (match_operand:SI 1 "register_operand" "")))
5545 (clobber (match_operand:DI 2 "memory_operand" ""))
5546 (clobber (match_scratch:SI 3 ""))]
5548 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5550 && reload_completed"
5551 [(set (match_dup 2) (match_dup 1))
5553 (float:X87MODEF (match_dup 2)))]
5554 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5557 [(set (match_operand:X87MODEF 0 "register_operand" "")
5558 (unsigned_float:X87MODEF
5559 (match_operand:SI 1 "memory_operand" "")))
5560 (clobber (match_operand:DI 2 "memory_operand" ""))
5561 (clobber (match_scratch:SI 3 ""))]
5563 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5565 && reload_completed"
5566 [(set (match_dup 2) (match_dup 3))
5568 (float:X87MODEF (match_dup 2)))]
5570 emit_move_insn (operands[3], operands[1]);
5571 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5574 (define_expand "floatunssi<mode>2"
5576 [(set (match_operand:X87MODEF 0 "register_operand" "")
5577 (unsigned_float:X87MODEF
5578 (match_operand:SI 1 "nonimmediate_operand" "")))
5579 (clobber (match_dup 2))
5580 (clobber (match_scratch:SI 3 ""))])]
5582 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5584 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5586 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5588 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5593 enum ix86_stack_slot slot = (virtuals_instantiated
5596 operands[2] = assign_386_stack_local (DImode, slot);
5600 (define_expand "floatunsdisf2"
5601 [(use (match_operand:SF 0 "register_operand" ""))
5602 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5603 "TARGET_64BIT && TARGET_SSE_MATH"
5604 "x86_emit_floatuns (operands); DONE;")
5606 (define_expand "floatunsdidf2"
5607 [(use (match_operand:DF 0 "register_operand" ""))
5608 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5609 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5610 && TARGET_SSE2 && TARGET_SSE_MATH"
5613 x86_emit_floatuns (operands);
5615 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5621 (define_expand "add<mode>3"
5622 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5623 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5624 (match_operand:SDWIM 2 "<general_operand>" "")))]
5626 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5628 (define_insn_and_split "*add<dwi>3_doubleword"
5629 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5631 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5632 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5633 (clobber (reg:CC FLAGS_REG))]
5634 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5637 [(parallel [(set (reg:CC FLAGS_REG)
5638 (unspec:CC [(match_dup 1) (match_dup 2)]
5641 (plus:DWIH (match_dup 1) (match_dup 2)))])
5642 (parallel [(set (match_dup 3)
5646 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5648 (clobber (reg:CC FLAGS_REG))])]
5649 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5651 (define_insn "*add<mode>3_cc"
5652 [(set (reg:CC FLAGS_REG)
5654 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5655 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5657 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5658 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5659 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5660 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5661 [(set_attr "type" "alu")
5662 (set_attr "mode" "<MODE>")])
5664 (define_insn "addqi3_cc"
5665 [(set (reg:CC FLAGS_REG)
5667 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5668 (match_operand:QI 2 "general_operand" "qn,qm")]
5670 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5671 (plus:QI (match_dup 1) (match_dup 2)))]
5672 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5673 "add{b}\t{%2, %0|%0, %2}"
5674 [(set_attr "type" "alu")
5675 (set_attr "mode" "QI")])
5677 (define_insn "*lea_1"
5678 [(set (match_operand:P 0 "register_operand" "=r")
5679 (match_operand:P 1 "no_seg_address_operand" "p"))]
5681 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5682 [(set_attr "type" "lea")
5683 (set_attr "mode" "<MODE>")])
5685 (define_insn "*lea_2"
5686 [(set (match_operand:SI 0 "register_operand" "=r")
5687 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5689 "lea{l}\t{%a1, %0|%0, %a1}"
5690 [(set_attr "type" "lea")
5691 (set_attr "mode" "SI")])
5693 (define_insn "*lea_2_zext"
5694 [(set (match_operand:DI 0 "register_operand" "=r")
5696 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5698 "lea{l}\t{%a1, %k0|%k0, %a1}"
5699 [(set_attr "type" "lea")
5700 (set_attr "mode" "SI")])
5702 (define_insn "*add<mode>_1"
5703 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5705 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5706 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5707 (clobber (reg:CC FLAGS_REG))]
5708 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5710 switch (get_attr_type (insn))
5716 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5717 if (operands[2] == const1_rtx)
5718 return "inc{<imodesuffix>}\t%0";
5721 gcc_assert (operands[2] == constm1_rtx);
5722 return "dec{<imodesuffix>}\t%0";
5726 /* For most processors, ADD is faster than LEA. This alternative
5727 was added to use ADD as much as possible. */
5728 if (which_alternative == 2)
5731 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5734 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5735 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5736 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5738 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5742 (cond [(eq_attr "alternative" "3")
5743 (const_string "lea")
5744 (match_operand:SWI48 2 "incdec_operand" "")
5745 (const_string "incdec")
5747 (const_string "alu")))
5748 (set (attr "length_immediate")
5750 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5752 (const_string "*")))
5753 (set_attr "mode" "<MODE>")])
5755 ;; It may seem that nonimmediate operand is proper one for operand 1.
5756 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5757 ;; we take care in ix86_binary_operator_ok to not allow two memory
5758 ;; operands so proper swapping will be done in reload. This allow
5759 ;; patterns constructed from addsi_1 to match.
5761 (define_insn "*addsi_1_zext"
5762 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5764 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5765 (match_operand:SI 2 "general_operand" "g,0,li"))))
5766 (clobber (reg:CC FLAGS_REG))]
5767 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5769 switch (get_attr_type (insn))
5775 if (operands[2] == const1_rtx)
5776 return "inc{l}\t%k0";
5779 gcc_assert (operands[2] == constm1_rtx);
5780 return "dec{l}\t%k0";
5784 /* For most processors, ADD is faster than LEA. This alternative
5785 was added to use ADD as much as possible. */
5786 if (which_alternative == 1)
5789 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5792 if (x86_maybe_negate_const_int (&operands[2], SImode))
5793 return "sub{l}\t{%2, %k0|%k0, %2}";
5795 return "add{l}\t{%2, %k0|%k0, %2}";
5799 (cond [(eq_attr "alternative" "2")
5800 (const_string "lea")
5801 (match_operand:SI 2 "incdec_operand" "")
5802 (const_string "incdec")
5804 (const_string "alu")))
5805 (set (attr "length_immediate")
5807 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5809 (const_string "*")))
5810 (set_attr "mode" "SI")])
5812 (define_insn "*addhi_1"
5813 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5814 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5815 (match_operand:HI 2 "general_operand" "rn,rm")))
5816 (clobber (reg:CC FLAGS_REG))]
5817 "TARGET_PARTIAL_REG_STALL
5818 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5820 switch (get_attr_type (insn))
5823 if (operands[2] == const1_rtx)
5824 return "inc{w}\t%0";
5827 gcc_assert (operands[2] == constm1_rtx);
5828 return "dec{w}\t%0";
5832 if (x86_maybe_negate_const_int (&operands[2], HImode))
5833 return "sub{w}\t{%2, %0|%0, %2}";
5835 return "add{w}\t{%2, %0|%0, %2}";
5839 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5840 (const_string "incdec")
5841 (const_string "alu")))
5842 (set (attr "length_immediate")
5844 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5846 (const_string "*")))
5847 (set_attr "mode" "HI")])
5849 (define_insn "*addhi_1_lea"
5850 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5851 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5852 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5853 (clobber (reg:CC FLAGS_REG))]
5854 "!TARGET_PARTIAL_REG_STALL
5855 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5857 switch (get_attr_type (insn))
5863 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5864 if (operands[2] == const1_rtx)
5865 return "inc{w}\t%0";
5868 gcc_assert (operands[2] == constm1_rtx);
5869 return "dec{w}\t%0";
5873 /* For most processors, ADD is faster than LEA. This alternative
5874 was added to use ADD as much as possible. */
5875 if (which_alternative == 2)
5878 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5881 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5882 if (x86_maybe_negate_const_int (&operands[2], HImode))
5883 return "sub{w}\t{%2, %0|%0, %2}";
5885 return "add{w}\t{%2, %0|%0, %2}";
5889 (cond [(eq_attr "alternative" "3")
5890 (const_string "lea")
5891 (match_operand:HI 2 "incdec_operand" "")
5892 (const_string "incdec")
5894 (const_string "alu")))
5895 (set (attr "length_immediate")
5897 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5899 (const_string "*")))
5900 (set_attr "mode" "HI,HI,HI,SI")])
5902 ;; %%% Potential partial reg stall on alternative 2. What to do?
5903 (define_insn "*addqi_1"
5904 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5905 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5906 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5907 (clobber (reg:CC FLAGS_REG))]
5908 "TARGET_PARTIAL_REG_STALL
5909 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5911 int widen = (which_alternative == 2);
5912 switch (get_attr_type (insn))
5915 if (operands[2] == const1_rtx)
5916 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5919 gcc_assert (operands[2] == constm1_rtx);
5920 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5924 if (x86_maybe_negate_const_int (&operands[2], QImode))
5927 return "sub{l}\t{%2, %k0|%k0, %2}";
5929 return "sub{b}\t{%2, %0|%0, %2}";
5932 return "add{l}\t{%k2, %k0|%k0, %k2}";
5934 return "add{b}\t{%2, %0|%0, %2}";
5938 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5939 (const_string "incdec")
5940 (const_string "alu")))
5941 (set (attr "length_immediate")
5943 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5945 (const_string "*")))
5946 (set_attr "mode" "QI,QI,SI")])
5948 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5949 (define_insn "*addqi_1_lea"
5950 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5951 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5952 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5953 (clobber (reg:CC FLAGS_REG))]
5954 "!TARGET_PARTIAL_REG_STALL
5955 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5957 int widen = (which_alternative == 3 || which_alternative == 4);
5959 switch (get_attr_type (insn))
5965 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5966 if (operands[2] == const1_rtx)
5967 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5970 gcc_assert (operands[2] == constm1_rtx);
5971 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5975 /* For most processors, ADD is faster than LEA. These alternatives
5976 were added to use ADD as much as possible. */
5977 if (which_alternative == 2 || which_alternative == 4)
5980 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5983 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5984 if (x86_maybe_negate_const_int (&operands[2], QImode))
5987 return "sub{l}\t{%2, %k0|%k0, %2}";
5989 return "sub{b}\t{%2, %0|%0, %2}";
5992 return "add{l}\t{%k2, %k0|%k0, %k2}";
5994 return "add{b}\t{%2, %0|%0, %2}";
5998 (cond [(eq_attr "alternative" "5")
5999 (const_string "lea")
6000 (match_operand:QI 2 "incdec_operand" "")
6001 (const_string "incdec")
6003 (const_string "alu")))
6004 (set (attr "length_immediate")
6006 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6008 (const_string "*")))
6009 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
6011 (define_insn "*addqi_1_slp"
6012 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6013 (plus:QI (match_dup 0)
6014 (match_operand:QI 1 "general_operand" "qn,qnm")))
6015 (clobber (reg:CC FLAGS_REG))]
6016 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6017 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6019 switch (get_attr_type (insn))
6022 if (operands[1] == const1_rtx)
6023 return "inc{b}\t%0";
6026 gcc_assert (operands[1] == constm1_rtx);
6027 return "dec{b}\t%0";
6031 if (x86_maybe_negate_const_int (&operands[1], QImode))
6032 return "sub{b}\t{%1, %0|%0, %1}";
6034 return "add{b}\t{%1, %0|%0, %1}";
6038 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6039 (const_string "incdec")
6040 (const_string "alu1")))
6041 (set (attr "memory")
6042 (if_then_else (match_operand 1 "memory_operand" "")
6043 (const_string "load")
6044 (const_string "none")))
6045 (set_attr "mode" "QI")])
6047 ;; Convert lea to the lea pattern to avoid flags dependency.
6049 [(set (match_operand 0 "register_operand" "")
6050 (plus (match_operand 1 "register_operand" "")
6051 (match_operand 2 "nonmemory_operand" "")))
6052 (clobber (reg:CC FLAGS_REG))]
6053 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6057 enum machine_mode mode = GET_MODE (operands[0]);
6059 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6060 may confuse gen_lowpart. */
6063 operands[1] = gen_lowpart (Pmode, operands[1]);
6064 operands[2] = gen_lowpart (Pmode, operands[2]);
6067 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6069 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6070 operands[0] = gen_lowpart (SImode, operands[0]);
6072 if (TARGET_64BIT && mode != Pmode)
6073 pat = gen_rtx_SUBREG (SImode, pat, 0);
6075 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6079 ;; Convert lea to the lea pattern to avoid flags dependency.
6080 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6081 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
6083 [(set (match_operand:DI 0 "register_operand" "")
6084 (plus:DI (match_operand:DI 1 "register_operand" "")
6085 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6086 (clobber (reg:CC FLAGS_REG))]
6087 "TARGET_64BIT && reload_completed
6088 && true_regnum (operands[0]) != true_regnum (operands[1])"
6090 (plus:DI (match_dup 1) (match_dup 2)))])
6092 ;; Convert lea to the lea pattern to avoid flags dependency.
6094 [(set (match_operand:DI 0 "register_operand" "")
6096 (plus:SI (match_operand:SI 1 "register_operand" "")
6097 (match_operand:SI 2 "nonmemory_operand" ""))))
6098 (clobber (reg:CC FLAGS_REG))]
6099 "TARGET_64BIT && reload_completed
6100 && ix86_lea_for_add_ok (insn, operands)"
6102 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6104 operands[1] = gen_lowpart (DImode, operands[1]);
6105 operands[2] = gen_lowpart (DImode, operands[2]);
6108 (define_insn "*add<mode>_2"
6109 [(set (reg FLAGS_REG)
6112 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6113 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6115 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6116 (plus:SWI (match_dup 1) (match_dup 2)))]
6117 "ix86_match_ccmode (insn, CCGOCmode)
6118 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6120 switch (get_attr_type (insn))
6123 if (operands[2] == const1_rtx)
6124 return "inc{<imodesuffix>}\t%0";
6127 gcc_assert (operands[2] == constm1_rtx);
6128 return "dec{<imodesuffix>}\t%0";
6132 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6133 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6135 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6139 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6140 (const_string "incdec")
6141 (const_string "alu")))
6142 (set (attr "length_immediate")
6144 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6146 (const_string "*")))
6147 (set_attr "mode" "<MODE>")])
6149 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6150 (define_insn "*addsi_2_zext"
6151 [(set (reg FLAGS_REG)
6153 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6154 (match_operand:SI 2 "general_operand" "g"))
6156 (set (match_operand:DI 0 "register_operand" "=r")
6157 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6158 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6159 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6161 switch (get_attr_type (insn))
6164 if (operands[2] == const1_rtx)
6165 return "inc{l}\t%k0";
6168 gcc_assert (operands[2] == constm1_rtx);
6169 return "dec{l}\t%k0";
6173 if (x86_maybe_negate_const_int (&operands[2], SImode))
6174 return "sub{l}\t{%2, %k0|%k0, %2}";
6176 return "add{l}\t{%2, %k0|%k0, %2}";
6180 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6181 (const_string "incdec")
6182 (const_string "alu")))
6183 (set (attr "length_immediate")
6185 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6187 (const_string "*")))
6188 (set_attr "mode" "SI")])
6190 (define_insn "*add<mode>_3"
6191 [(set (reg FLAGS_REG)
6193 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6194 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6195 (clobber (match_scratch:SWI 0 "=<r>"))]
6196 "ix86_match_ccmode (insn, CCZmode)
6197 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6199 switch (get_attr_type (insn))
6202 if (operands[2] == const1_rtx)
6203 return "inc{<imodesuffix>}\t%0";
6206 gcc_assert (operands[2] == constm1_rtx);
6207 return "dec{<imodesuffix>}\t%0";
6211 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6212 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6214 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6218 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6219 (const_string "incdec")
6220 (const_string "alu")))
6221 (set (attr "length_immediate")
6223 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6225 (const_string "*")))
6226 (set_attr "mode" "<MODE>")])
6228 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6229 (define_insn "*addsi_3_zext"
6230 [(set (reg FLAGS_REG)
6232 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6233 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6234 (set (match_operand:DI 0 "register_operand" "=r")
6235 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6236 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6237 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6239 switch (get_attr_type (insn))
6242 if (operands[2] == const1_rtx)
6243 return "inc{l}\t%k0";
6246 gcc_assert (operands[2] == constm1_rtx);
6247 return "dec{l}\t%k0";
6251 if (x86_maybe_negate_const_int (&operands[2], SImode))
6252 return "sub{l}\t{%2, %k0|%k0, %2}";
6254 return "add{l}\t{%2, %k0|%k0, %2}";
6258 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6259 (const_string "incdec")
6260 (const_string "alu")))
6261 (set (attr "length_immediate")
6263 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6265 (const_string "*")))
6266 (set_attr "mode" "SI")])
6268 ; For comparisons against 1, -1 and 128, we may generate better code
6269 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6270 ; is matched then. We can't accept general immediate, because for
6271 ; case of overflows, the result is messed up.
6272 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6273 ; only for comparisons not depending on it.
6275 (define_insn "*adddi_4"
6276 [(set (reg FLAGS_REG)
6278 (match_operand:DI 1 "nonimmediate_operand" "0")
6279 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6280 (clobber (match_scratch:DI 0 "=rm"))]
6282 && ix86_match_ccmode (insn, CCGCmode)"
6284 switch (get_attr_type (insn))
6287 if (operands[2] == constm1_rtx)
6288 return "inc{q}\t%0";
6291 gcc_assert (operands[2] == const1_rtx);
6292 return "dec{q}\t%0";
6296 if (x86_maybe_negate_const_int (&operands[2], DImode))
6297 return "add{q}\t{%2, %0|%0, %2}";
6299 return "sub{q}\t{%2, %0|%0, %2}";
6303 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6304 (const_string "incdec")
6305 (const_string "alu")))
6306 (set (attr "length_immediate")
6308 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6310 (const_string "*")))
6311 (set_attr "mode" "DI")])
6313 ; For comparisons against 1, -1 and 128, we may generate better code
6314 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6315 ; is matched then. We can't accept general immediate, because for
6316 ; case of overflows, the result is messed up.
6317 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6318 ; only for comparisons not depending on it.
6320 (define_insn "*add<mode>_4"
6321 [(set (reg FLAGS_REG)
6323 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6324 (match_operand:SWI124 2 "const_int_operand" "n")))
6325 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6326 "ix86_match_ccmode (insn, CCGCmode)"
6328 switch (get_attr_type (insn))
6331 if (operands[2] == constm1_rtx)
6332 return "inc{<imodesuffix>}\t%0";
6335 gcc_assert (operands[2] == const1_rtx);
6336 return "dec{<imodesuffix>}\t%0";
6340 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6341 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6343 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6347 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6348 (const_string "incdec")
6349 (const_string "alu")))
6350 (set (attr "length_immediate")
6352 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6354 (const_string "*")))
6355 (set_attr "mode" "<MODE>")])
6357 (define_insn "*add<mode>_5"
6358 [(set (reg FLAGS_REG)
6361 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6362 (match_operand:SWI 2 "<general_operand>" "<g>"))
6364 (clobber (match_scratch:SWI 0 "=<r>"))]
6365 "ix86_match_ccmode (insn, CCGOCmode)
6366 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6368 switch (get_attr_type (insn))
6371 if (operands[2] == const1_rtx)
6372 return "inc{<imodesuffix>}\t%0";
6375 gcc_assert (operands[2] == constm1_rtx);
6376 return "dec{<imodesuffix>}\t%0";
6380 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6381 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6383 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6387 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6388 (const_string "incdec")
6389 (const_string "alu")))
6390 (set (attr "length_immediate")
6392 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6394 (const_string "*")))
6395 (set_attr "mode" "<MODE>")])
6397 (define_insn "*addqi_ext_1_rex64"
6398 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6403 (match_operand 1 "ext_register_operand" "0")
6406 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6407 (clobber (reg:CC FLAGS_REG))]
6410 switch (get_attr_type (insn))
6413 if (operands[2] == const1_rtx)
6414 return "inc{b}\t%h0";
6417 gcc_assert (operands[2] == constm1_rtx);
6418 return "dec{b}\t%h0";
6422 return "add{b}\t{%2, %h0|%h0, %2}";
6426 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6427 (const_string "incdec")
6428 (const_string "alu")))
6429 (set_attr "modrm" "1")
6430 (set_attr "mode" "QI")])
6432 (define_insn "addqi_ext_1"
6433 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6438 (match_operand 1 "ext_register_operand" "0")
6441 (match_operand:QI 2 "general_operand" "Qmn")))
6442 (clobber (reg:CC FLAGS_REG))]
6445 switch (get_attr_type (insn))
6448 if (operands[2] == const1_rtx)
6449 return "inc{b}\t%h0";
6452 gcc_assert (operands[2] == constm1_rtx);
6453 return "dec{b}\t%h0";
6457 return "add{b}\t{%2, %h0|%h0, %2}";
6461 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6462 (const_string "incdec")
6463 (const_string "alu")))
6464 (set_attr "modrm" "1")
6465 (set_attr "mode" "QI")])
6467 (define_insn "*addqi_ext_2"
6468 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6473 (match_operand 1 "ext_register_operand" "%0")
6477 (match_operand 2 "ext_register_operand" "Q")
6480 (clobber (reg:CC FLAGS_REG))]
6482 "add{b}\t{%h2, %h0|%h0, %h2}"
6483 [(set_attr "type" "alu")
6484 (set_attr "mode" "QI")])
6486 ;; The lea patterns for non-Pmodes needs to be matched by
6487 ;; several insns converted to real lea by splitters.
6489 (define_insn_and_split "*lea_general_1"
6490 [(set (match_operand 0 "register_operand" "=r")
6491 (plus (plus (match_operand 1 "index_register_operand" "l")
6492 (match_operand 2 "register_operand" "r"))
6493 (match_operand 3 "immediate_operand" "i")))]
6494 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6495 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6496 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6497 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6498 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6499 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6500 || GET_MODE (operands[3]) == VOIDmode)"
6502 "&& reload_completed"
6506 operands[0] = gen_lowpart (SImode, operands[0]);
6507 operands[1] = gen_lowpart (Pmode, operands[1]);
6508 operands[2] = gen_lowpart (Pmode, operands[2]);
6509 operands[3] = gen_lowpart (Pmode, operands[3]);
6510 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6512 if (Pmode != SImode)
6513 pat = gen_rtx_SUBREG (SImode, pat, 0);
6514 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6517 [(set_attr "type" "lea")
6518 (set_attr "mode" "SI")])
6520 (define_insn_and_split "*lea_general_1_zext"
6521 [(set (match_operand:DI 0 "register_operand" "=r")
6524 (match_operand:SI 1 "index_register_operand" "l")
6525 (match_operand:SI 2 "register_operand" "r"))
6526 (match_operand:SI 3 "immediate_operand" "i"))))]
6529 "&& reload_completed"
6531 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6533 (match_dup 3)) 0)))]
6535 operands[1] = gen_lowpart (Pmode, operands[1]);
6536 operands[2] = gen_lowpart (Pmode, operands[2]);
6537 operands[3] = gen_lowpart (Pmode, operands[3]);
6539 [(set_attr "type" "lea")
6540 (set_attr "mode" "SI")])
6542 (define_insn_and_split "*lea_general_2"
6543 [(set (match_operand 0 "register_operand" "=r")
6544 (plus (mult (match_operand 1 "index_register_operand" "l")
6545 (match_operand 2 "const248_operand" "i"))
6546 (match_operand 3 "nonmemory_operand" "ri")))]
6547 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6548 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6549 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6550 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6551 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6552 || GET_MODE (operands[3]) == VOIDmode)"
6554 "&& reload_completed"
6558 operands[0] = gen_lowpart (SImode, operands[0]);
6559 operands[1] = gen_lowpart (Pmode, operands[1]);
6560 operands[3] = gen_lowpart (Pmode, operands[3]);
6561 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6563 if (Pmode != SImode)
6564 pat = gen_rtx_SUBREG (SImode, pat, 0);
6565 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6568 [(set_attr "type" "lea")
6569 (set_attr "mode" "SI")])
6571 (define_insn_and_split "*lea_general_2_zext"
6572 [(set (match_operand:DI 0 "register_operand" "=r")
6575 (match_operand:SI 1 "index_register_operand" "l")
6576 (match_operand:SI 2 "const248_operand" "n"))
6577 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6580 "&& reload_completed"
6582 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6584 (match_dup 3)) 0)))]
6586 operands[1] = gen_lowpart (Pmode, operands[1]);
6587 operands[3] = gen_lowpart (Pmode, operands[3]);
6589 [(set_attr "type" "lea")
6590 (set_attr "mode" "SI")])
6592 (define_insn_and_split "*lea_general_3"
6593 [(set (match_operand 0 "register_operand" "=r")
6594 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6595 (match_operand 2 "const248_operand" "i"))
6596 (match_operand 3 "register_operand" "r"))
6597 (match_operand 4 "immediate_operand" "i")))]
6598 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6599 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6600 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6601 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6602 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6604 "&& reload_completed"
6608 operands[0] = gen_lowpart (SImode, operands[0]);
6609 operands[1] = gen_lowpart (Pmode, operands[1]);
6610 operands[3] = gen_lowpart (Pmode, operands[3]);
6611 operands[4] = gen_lowpart (Pmode, operands[4]);
6612 pat = gen_rtx_PLUS (Pmode,
6613 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6617 if (Pmode != SImode)
6618 pat = gen_rtx_SUBREG (SImode, pat, 0);
6619 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6622 [(set_attr "type" "lea")
6623 (set_attr "mode" "SI")])
6625 (define_insn_and_split "*lea_general_3_zext"
6626 [(set (match_operand:DI 0 "register_operand" "=r")
6630 (match_operand:SI 1 "index_register_operand" "l")
6631 (match_operand:SI 2 "const248_operand" "n"))
6632 (match_operand:SI 3 "register_operand" "r"))
6633 (match_operand:SI 4 "immediate_operand" "i"))))]
6636 "&& reload_completed"
6638 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6641 (match_dup 4)) 0)))]
6643 operands[1] = gen_lowpart (Pmode, operands[1]);
6644 operands[3] = gen_lowpart (Pmode, operands[3]);
6645 operands[4] = gen_lowpart (Pmode, operands[4]);
6647 [(set_attr "type" "lea")
6648 (set_attr "mode" "SI")])
6650 ;; Subtract instructions
6652 (define_expand "sub<mode>3"
6653 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6654 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6655 (match_operand:SDWIM 2 "<general_operand>" "")))]
6657 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6659 (define_insn_and_split "*sub<dwi>3_doubleword"
6660 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6662 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6663 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6664 (clobber (reg:CC FLAGS_REG))]
6665 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6668 [(parallel [(set (reg:CC FLAGS_REG)
6669 (compare:CC (match_dup 1) (match_dup 2)))
6671 (minus:DWIH (match_dup 1) (match_dup 2)))])
6672 (parallel [(set (match_dup 3)
6676 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6678 (clobber (reg:CC FLAGS_REG))])]
6679 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6681 (define_insn "*sub<mode>_1"
6682 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6684 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6685 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6686 (clobber (reg:CC FLAGS_REG))]
6687 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6688 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6689 [(set_attr "type" "alu")
6690 (set_attr "mode" "<MODE>")])
6692 (define_insn "*subsi_1_zext"
6693 [(set (match_operand:DI 0 "register_operand" "=r")
6695 (minus:SI (match_operand:SI 1 "register_operand" "0")
6696 (match_operand:SI 2 "general_operand" "g"))))
6697 (clobber (reg:CC FLAGS_REG))]
6698 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6699 "sub{l}\t{%2, %k0|%k0, %2}"
6700 [(set_attr "type" "alu")
6701 (set_attr "mode" "SI")])
6703 (define_insn "*subqi_1_slp"
6704 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6705 (minus:QI (match_dup 0)
6706 (match_operand:QI 1 "general_operand" "qn,qm")))
6707 (clobber (reg:CC FLAGS_REG))]
6708 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6709 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6710 "sub{b}\t{%1, %0|%0, %1}"
6711 [(set_attr "type" "alu1")
6712 (set_attr "mode" "QI")])
6714 (define_insn "*sub<mode>_2"
6715 [(set (reg FLAGS_REG)
6718 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6719 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6721 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6722 (minus:SWI (match_dup 1) (match_dup 2)))]
6723 "ix86_match_ccmode (insn, CCGOCmode)
6724 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6725 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6726 [(set_attr "type" "alu")
6727 (set_attr "mode" "<MODE>")])
6729 (define_insn "*subsi_2_zext"
6730 [(set (reg FLAGS_REG)
6732 (minus:SI (match_operand:SI 1 "register_operand" "0")
6733 (match_operand:SI 2 "general_operand" "g"))
6735 (set (match_operand:DI 0 "register_operand" "=r")
6737 (minus:SI (match_dup 1)
6739 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6740 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6741 "sub{l}\t{%2, %k0|%k0, %2}"
6742 [(set_attr "type" "alu")
6743 (set_attr "mode" "SI")])
6745 (define_insn "*sub<mode>_3"
6746 [(set (reg FLAGS_REG)
6747 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6748 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6749 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6750 (minus:SWI (match_dup 1) (match_dup 2)))]
6751 "ix86_match_ccmode (insn, CCmode)
6752 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6753 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6754 [(set_attr "type" "alu")
6755 (set_attr "mode" "<MODE>")])
6757 (define_insn "*subsi_3_zext"
6758 [(set (reg FLAGS_REG)
6759 (compare (match_operand:SI 1 "register_operand" "0")
6760 (match_operand:SI 2 "general_operand" "g")))
6761 (set (match_operand:DI 0 "register_operand" "=r")
6763 (minus:SI (match_dup 1)
6765 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6766 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6767 "sub{l}\t{%2, %1|%1, %2}"
6768 [(set_attr "type" "alu")
6769 (set_attr "mode" "SI")])
6771 ;; Add with carry and subtract with borrow
6773 (define_expand "<plusminus_insn><mode>3_carry"
6775 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6777 (match_operand:SWI 1 "nonimmediate_operand" "")
6778 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6779 [(match_operand 3 "flags_reg_operand" "")
6781 (match_operand:SWI 2 "<general_operand>" ""))))
6782 (clobber (reg:CC FLAGS_REG))])]
6783 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6785 (define_insn "*<plusminus_insn><mode>3_carry"
6786 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6788 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6790 (match_operator 3 "ix86_carry_flag_operator"
6791 [(reg FLAGS_REG) (const_int 0)])
6792 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6793 (clobber (reg:CC FLAGS_REG))]
6794 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6795 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6796 [(set_attr "type" "alu")
6797 (set_attr "use_carry" "1")
6798 (set_attr "pent_pair" "pu")
6799 (set_attr "mode" "<MODE>")])
6801 (define_insn "*addsi3_carry_zext"
6802 [(set (match_operand:DI 0 "register_operand" "=r")
6804 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6805 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6806 [(reg FLAGS_REG) (const_int 0)])
6807 (match_operand:SI 2 "general_operand" "g")))))
6808 (clobber (reg:CC FLAGS_REG))]
6809 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6810 "adc{l}\t{%2, %k0|%k0, %2}"
6811 [(set_attr "type" "alu")
6812 (set_attr "use_carry" "1")
6813 (set_attr "pent_pair" "pu")
6814 (set_attr "mode" "SI")])
6816 (define_insn "*subsi3_carry_zext"
6817 [(set (match_operand:DI 0 "register_operand" "=r")
6819 (minus:SI (match_operand:SI 1 "register_operand" "0")
6820 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6821 [(reg FLAGS_REG) (const_int 0)])
6822 (match_operand:SI 2 "general_operand" "g")))))
6823 (clobber (reg:CC FLAGS_REG))]
6824 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6825 "sbb{l}\t{%2, %k0|%k0, %2}"
6826 [(set_attr "type" "alu")
6827 (set_attr "pent_pair" "pu")
6828 (set_attr "mode" "SI")])
6830 ;; Overflow setting add and subtract instructions
6832 (define_insn "*add<mode>3_cconly_overflow"
6833 [(set (reg:CCC FLAGS_REG)
6836 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6837 (match_operand:SWI 2 "<general_operand>" "<g>"))
6839 (clobber (match_scratch:SWI 0 "=<r>"))]
6840 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6841 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6842 [(set_attr "type" "alu")
6843 (set_attr "mode" "<MODE>")])
6845 (define_insn "*sub<mode>3_cconly_overflow"
6846 [(set (reg:CCC FLAGS_REG)
6849 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6850 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6853 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6854 [(set_attr "type" "icmp")
6855 (set_attr "mode" "<MODE>")])
6857 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6858 [(set (reg:CCC FLAGS_REG)
6861 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6862 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6864 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6865 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6866 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6867 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6868 [(set_attr "type" "alu")
6869 (set_attr "mode" "<MODE>")])
6871 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6872 [(set (reg:CCC FLAGS_REG)
6875 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6876 (match_operand:SI 2 "general_operand" "g"))
6878 (set (match_operand:DI 0 "register_operand" "=r")
6879 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6880 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6881 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6882 [(set_attr "type" "alu")
6883 (set_attr "mode" "SI")])
6885 ;; The patterns that match these are at the end of this file.
6887 (define_expand "<plusminus_insn>xf3"
6888 [(set (match_operand:XF 0 "register_operand" "")
6890 (match_operand:XF 1 "register_operand" "")
6891 (match_operand:XF 2 "register_operand" "")))]
6894 (define_expand "<plusminus_insn><mode>3"
6895 [(set (match_operand:MODEF 0 "register_operand" "")
6897 (match_operand:MODEF 1 "register_operand" "")
6898 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6899 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6900 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6902 ;; Multiply instructions
6904 (define_expand "mul<mode>3"
6905 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6907 (match_operand:SWIM248 1 "register_operand" "")
6908 (match_operand:SWIM248 2 "<general_operand>" "")))
6909 (clobber (reg:CC FLAGS_REG))])])
6911 (define_expand "mulqi3"
6912 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6914 (match_operand:QI 1 "register_operand" "")
6915 (match_operand:QI 2 "nonimmediate_operand" "")))
6916 (clobber (reg:CC FLAGS_REG))])]
6917 "TARGET_QIMODE_MATH")
6920 ;; IMUL reg32/64, reg32/64, imm8 Direct
6921 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6922 ;; IMUL reg32/64, reg32/64, imm32 Direct
6923 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6924 ;; IMUL reg32/64, reg32/64 Direct
6925 ;; IMUL reg32/64, mem32/64 Direct
6927 ;; On BDVER1, all above IMULs use DirectPath
6929 (define_insn "*mul<mode>3_1"
6930 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6932 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6933 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6934 (clobber (reg:CC FLAGS_REG))]
6935 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6937 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6938 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6939 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6940 [(set_attr "type" "imul")
6941 (set_attr "prefix_0f" "0,0,1")
6942 (set (attr "athlon_decode")
6943 (cond [(eq_attr "cpu" "athlon")
6944 (const_string "vector")
6945 (eq_attr "alternative" "1")
6946 (const_string "vector")
6947 (and (eq_attr "alternative" "2")
6948 (match_operand 1 "memory_operand" ""))
6949 (const_string "vector")]
6950 (const_string "direct")))
6951 (set (attr "amdfam10_decode")
6952 (cond [(and (eq_attr "alternative" "0,1")
6953 (match_operand 1 "memory_operand" ""))
6954 (const_string "vector")]
6955 (const_string "direct")))
6956 (set_attr "bdver1_decode" "direct")
6957 (set_attr "mode" "<MODE>")])
6959 (define_insn "*mulsi3_1_zext"
6960 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6962 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6963 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6964 (clobber (reg:CC FLAGS_REG))]
6966 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6968 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6969 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6970 imul{l}\t{%2, %k0|%k0, %2}"
6971 [(set_attr "type" "imul")
6972 (set_attr "prefix_0f" "0,0,1")
6973 (set (attr "athlon_decode")
6974 (cond [(eq_attr "cpu" "athlon")
6975 (const_string "vector")
6976 (eq_attr "alternative" "1")
6977 (const_string "vector")
6978 (and (eq_attr "alternative" "2")
6979 (match_operand 1 "memory_operand" ""))
6980 (const_string "vector")]
6981 (const_string "direct")))
6982 (set (attr "amdfam10_decode")
6983 (cond [(and (eq_attr "alternative" "0,1")
6984 (match_operand 1 "memory_operand" ""))
6985 (const_string "vector")]
6986 (const_string "direct")))
6987 (set_attr "bdver1_decode" "direct")
6988 (set_attr "mode" "SI")])
6991 ;; IMUL reg16, reg16, imm8 VectorPath
6992 ;; IMUL reg16, mem16, imm8 VectorPath
6993 ;; IMUL reg16, reg16, imm16 VectorPath
6994 ;; IMUL reg16, mem16, imm16 VectorPath
6995 ;; IMUL reg16, reg16 Direct
6996 ;; IMUL reg16, mem16 Direct
6998 ;; On BDVER1, all HI MULs use DoublePath
7000 (define_insn "*mulhi3_1"
7001 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7002 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7003 (match_operand:HI 2 "general_operand" "K,n,mr")))
7004 (clobber (reg:CC FLAGS_REG))]
7006 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7008 imul{w}\t{%2, %1, %0|%0, %1, %2}
7009 imul{w}\t{%2, %1, %0|%0, %1, %2}
7010 imul{w}\t{%2, %0|%0, %2}"
7011 [(set_attr "type" "imul")
7012 (set_attr "prefix_0f" "0,0,1")
7013 (set (attr "athlon_decode")
7014 (cond [(eq_attr "cpu" "athlon")
7015 (const_string "vector")
7016 (eq_attr "alternative" "1,2")
7017 (const_string "vector")]
7018 (const_string "direct")))
7019 (set (attr "amdfam10_decode")
7020 (cond [(eq_attr "alternative" "0,1")
7021 (const_string "vector")]
7022 (const_string "direct")))
7023 (set_attr "bdver1_decode" "double")
7024 (set_attr "mode" "HI")])
7026 ;;On AMDFAM10 and BDVER1
7030 (define_insn "*mulqi3_1"
7031 [(set (match_operand:QI 0 "register_operand" "=a")
7032 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7033 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7034 (clobber (reg:CC FLAGS_REG))]
7036 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7038 [(set_attr "type" "imul")
7039 (set_attr "length_immediate" "0")
7040 (set (attr "athlon_decode")
7041 (if_then_else (eq_attr "cpu" "athlon")
7042 (const_string "vector")
7043 (const_string "direct")))
7044 (set_attr "amdfam10_decode" "direct")
7045 (set_attr "bdver1_decode" "direct")
7046 (set_attr "mode" "QI")])
7048 (define_expand "<u>mul<mode><dwi>3"
7049 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7052 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7054 (match_operand:DWIH 2 "register_operand" ""))))
7055 (clobber (reg:CC FLAGS_REG))])])
7057 (define_expand "<u>mulqihi3"
7058 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7061 (match_operand:QI 1 "nonimmediate_operand" ""))
7063 (match_operand:QI 2 "register_operand" ""))))
7064 (clobber (reg:CC FLAGS_REG))])]
7065 "TARGET_QIMODE_MATH")
7067 (define_insn "*<u>mul<mode><dwi>3_1"
7068 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7071 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7073 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7074 (clobber (reg:CC FLAGS_REG))]
7075 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7076 "<sgnprefix>mul{<imodesuffix>}\t%2"
7077 [(set_attr "type" "imul")
7078 (set_attr "length_immediate" "0")
7079 (set (attr "athlon_decode")
7080 (if_then_else (eq_attr "cpu" "athlon")
7081 (const_string "vector")
7082 (const_string "double")))
7083 (set_attr "amdfam10_decode" "double")
7084 (set_attr "bdver1_decode" "direct")
7085 (set_attr "mode" "<MODE>")])
7087 (define_insn "*<u>mulqihi3_1"
7088 [(set (match_operand:HI 0 "register_operand" "=a")
7091 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7093 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7094 (clobber (reg:CC FLAGS_REG))]
7096 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7097 "<sgnprefix>mul{b}\t%2"
7098 [(set_attr "type" "imul")
7099 (set_attr "length_immediate" "0")
7100 (set (attr "athlon_decode")
7101 (if_then_else (eq_attr "cpu" "athlon")
7102 (const_string "vector")
7103 (const_string "direct")))
7104 (set_attr "amdfam10_decode" "direct")
7105 (set_attr "bdver1_decode" "direct")
7106 (set_attr "mode" "QI")])
7108 (define_expand "<s>mul<mode>3_highpart"
7109 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7114 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7116 (match_operand:SWI48 2 "register_operand" "")))
7118 (clobber (match_scratch:SWI48 3 ""))
7119 (clobber (reg:CC FLAGS_REG))])]
7121 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7123 (define_insn "*<s>muldi3_highpart_1"
7124 [(set (match_operand:DI 0 "register_operand" "=d")
7129 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7131 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7133 (clobber (match_scratch:DI 3 "=1"))
7134 (clobber (reg:CC FLAGS_REG))]
7136 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7137 "<sgnprefix>mul{q}\t%2"
7138 [(set_attr "type" "imul")
7139 (set_attr "length_immediate" "0")
7140 (set (attr "athlon_decode")
7141 (if_then_else (eq_attr "cpu" "athlon")
7142 (const_string "vector")
7143 (const_string "double")))
7144 (set_attr "amdfam10_decode" "double")
7145 (set_attr "bdver1_decode" "direct")
7146 (set_attr "mode" "DI")])
7148 (define_insn "*<s>mulsi3_highpart_1"
7149 [(set (match_operand:SI 0 "register_operand" "=d")
7154 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7156 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7158 (clobber (match_scratch:SI 3 "=1"))
7159 (clobber (reg:CC FLAGS_REG))]
7160 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7161 "<sgnprefix>mul{l}\t%2"
7162 [(set_attr "type" "imul")
7163 (set_attr "length_immediate" "0")
7164 (set (attr "athlon_decode")
7165 (if_then_else (eq_attr "cpu" "athlon")
7166 (const_string "vector")
7167 (const_string "double")))
7168 (set_attr "amdfam10_decode" "double")
7169 (set_attr "bdver1_decode" "direct")
7170 (set_attr "mode" "SI")])
7172 (define_insn "*<s>mulsi3_highpart_zext"
7173 [(set (match_operand:DI 0 "register_operand" "=d")
7174 (zero_extend:DI (truncate:SI
7176 (mult:DI (any_extend:DI
7177 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7179 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7181 (clobber (match_scratch:SI 3 "=1"))
7182 (clobber (reg:CC FLAGS_REG))]
7184 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7185 "<sgnprefix>mul{l}\t%2"
7186 [(set_attr "type" "imul")
7187 (set_attr "length_immediate" "0")
7188 (set (attr "athlon_decode")
7189 (if_then_else (eq_attr "cpu" "athlon")
7190 (const_string "vector")
7191 (const_string "double")))
7192 (set_attr "amdfam10_decode" "double")
7193 (set_attr "bdver1_decode" "direct")
7194 (set_attr "mode" "SI")])
7196 ;; The patterns that match these are at the end of this file.
7198 (define_expand "mulxf3"
7199 [(set (match_operand:XF 0 "register_operand" "")
7200 (mult:XF (match_operand:XF 1 "register_operand" "")
7201 (match_operand:XF 2 "register_operand" "")))]
7204 (define_expand "mul<mode>3"
7205 [(set (match_operand:MODEF 0 "register_operand" "")
7206 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7207 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7208 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7209 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7211 ;; Divide instructions
7213 ;; The patterns that match these are at the end of this file.
7215 (define_expand "divxf3"
7216 [(set (match_operand:XF 0 "register_operand" "")
7217 (div:XF (match_operand:XF 1 "register_operand" "")
7218 (match_operand:XF 2 "register_operand" "")))]
7221 (define_expand "divdf3"
7222 [(set (match_operand:DF 0 "register_operand" "")
7223 (div:DF (match_operand:DF 1 "register_operand" "")
7224 (match_operand:DF 2 "nonimmediate_operand" "")))]
7225 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7226 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7228 (define_expand "divsf3"
7229 [(set (match_operand:SF 0 "register_operand" "")
7230 (div:SF (match_operand:SF 1 "register_operand" "")
7231 (match_operand:SF 2 "nonimmediate_operand" "")))]
7232 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7235 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7236 && flag_finite_math_only && !flag_trapping_math
7237 && flag_unsafe_math_optimizations)
7239 ix86_emit_swdivsf (operands[0], operands[1],
7240 operands[2], SFmode);
7245 ;; Divmod instructions.
7247 (define_expand "divmod<mode>4"
7248 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7250 (match_operand:SWIM248 1 "register_operand" "")
7251 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7252 (set (match_operand:SWIM248 3 "register_operand" "")
7253 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7254 (clobber (reg:CC FLAGS_REG))])])
7256 ;; Split with 8bit unsigned divide:
7257 ;; if (dividend an divisor are in [0-255])
7258 ;; use 8bit unsigned integer divide
7260 ;; use original integer divide
7262 [(set (match_operand:SWI48 0 "register_operand" "")
7263 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7264 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7265 (set (match_operand:SWI48 1 "register_operand" "")
7266 (mod:SWI48 (match_dup 2) (match_dup 3)))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "TARGET_USE_8BIT_IDIV
7269 && TARGET_QIMODE_MATH
7270 && can_create_pseudo_p ()
7271 && !optimize_insn_for_size_p ()"
7273 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7275 (define_insn_and_split "divmod<mode>4_1"
7276 [(set (match_operand:SWI48 0 "register_operand" "=a")
7277 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7278 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7279 (set (match_operand:SWI48 1 "register_operand" "=&d")
7280 (mod:SWI48 (match_dup 2) (match_dup 3)))
7281 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7282 (clobber (reg:CC FLAGS_REG))]
7286 [(parallel [(set (match_dup 1)
7287 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7288 (clobber (reg:CC FLAGS_REG))])
7289 (parallel [(set (match_dup 0)
7290 (div:SWI48 (match_dup 2) (match_dup 3)))
7292 (mod:SWI48 (match_dup 2) (match_dup 3)))
7294 (clobber (reg:CC FLAGS_REG))])]
7296 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7298 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7299 operands[4] = operands[2];
7302 /* Avoid use of cltd in favor of a mov+shift. */
7303 emit_move_insn (operands[1], operands[2]);
7304 operands[4] = operands[1];
7307 [(set_attr "type" "multi")
7308 (set_attr "mode" "<MODE>")])
7310 (define_insn_and_split "*divmod<mode>4"
7311 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7312 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7313 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7314 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7315 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7316 (clobber (reg:CC FLAGS_REG))]
7320 [(parallel [(set (match_dup 1)
7321 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7322 (clobber (reg:CC FLAGS_REG))])
7323 (parallel [(set (match_dup 0)
7324 (div:SWIM248 (match_dup 2) (match_dup 3)))
7326 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7328 (clobber (reg:CC FLAGS_REG))])]
7330 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7332 if (<MODE>mode != HImode
7333 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7334 operands[4] = operands[2];
7337 /* Avoid use of cltd in favor of a mov+shift. */
7338 emit_move_insn (operands[1], operands[2]);
7339 operands[4] = operands[1];
7342 [(set_attr "type" "multi")
7343 (set_attr "mode" "<MODE>")])
7345 (define_insn "*divmod<mode>4_noext"
7346 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7347 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7348 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7349 (set (match_operand:SWIM248 1 "register_operand" "=d")
7350 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7351 (use (match_operand:SWIM248 4 "register_operand" "1"))
7352 (clobber (reg:CC FLAGS_REG))]
7354 "idiv{<imodesuffix>}\t%3"
7355 [(set_attr "type" "idiv")
7356 (set_attr "mode" "<MODE>")])
7358 (define_expand "divmodqi4"
7359 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7361 (match_operand:QI 1 "register_operand" "")
7362 (match_operand:QI 2 "nonimmediate_operand" "")))
7363 (set (match_operand:QI 3 "register_operand" "")
7364 (mod:QI (match_dup 1) (match_dup 2)))
7365 (clobber (reg:CC FLAGS_REG))])]
7366 "TARGET_QIMODE_MATH"
7371 tmp0 = gen_reg_rtx (HImode);
7372 tmp1 = gen_reg_rtx (HImode);
7374 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7376 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7377 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7379 /* Extract remainder from AH. */
7380 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7381 insn = emit_move_insn (operands[3], tmp1);
7383 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7384 set_unique_reg_note (insn, REG_EQUAL, mod);
7386 /* Extract quotient from AL. */
7387 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7389 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7390 set_unique_reg_note (insn, REG_EQUAL, div);
7395 ;; Divide AX by r/m8, with result stored in
7398 ;; Change div/mod to HImode and extend the second argument to HImode
7399 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7400 ;; combine may fail.
7401 (define_insn "divmodhiqi3"
7402 [(set (match_operand:HI 0 "register_operand" "=a")
7407 (mod:HI (match_operand:HI 1 "register_operand" "0")
7409 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7413 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7414 (clobber (reg:CC FLAGS_REG))]
7415 "TARGET_QIMODE_MATH"
7417 [(set_attr "type" "idiv")
7418 (set_attr "mode" "QI")])
7420 (define_expand "udivmod<mode>4"
7421 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7423 (match_operand:SWIM248 1 "register_operand" "")
7424 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7425 (set (match_operand:SWIM248 3 "register_operand" "")
7426 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7427 (clobber (reg:CC FLAGS_REG))])])
7429 ;; Split with 8bit unsigned divide:
7430 ;; if (dividend an divisor are in [0-255])
7431 ;; use 8bit unsigned integer divide
7433 ;; use original integer divide
7435 [(set (match_operand:SWI48 0 "register_operand" "")
7436 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7437 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7438 (set (match_operand:SWI48 1 "register_operand" "")
7439 (umod:SWI48 (match_dup 2) (match_dup 3)))
7440 (clobber (reg:CC FLAGS_REG))]
7441 "TARGET_USE_8BIT_IDIV
7442 && TARGET_QIMODE_MATH
7443 && can_create_pseudo_p ()
7444 && !optimize_insn_for_size_p ()"
7446 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7448 (define_insn_and_split "udivmod<mode>4_1"
7449 [(set (match_operand:SWI48 0 "register_operand" "=a")
7450 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7451 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7452 (set (match_operand:SWI48 1 "register_operand" "=&d")
7453 (umod:SWI48 (match_dup 2) (match_dup 3)))
7454 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7455 (clobber (reg:CC FLAGS_REG))]
7459 [(set (match_dup 1) (const_int 0))
7460 (parallel [(set (match_dup 0)
7461 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7463 (umod:SWI48 (match_dup 2) (match_dup 3)))
7465 (clobber (reg:CC FLAGS_REG))])]
7467 [(set_attr "type" "multi")
7468 (set_attr "mode" "<MODE>")])
7470 (define_insn_and_split "*udivmod<mode>4"
7471 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7472 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7473 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7474 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7475 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7476 (clobber (reg:CC FLAGS_REG))]
7480 [(set (match_dup 1) (const_int 0))
7481 (parallel [(set (match_dup 0)
7482 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7484 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7486 (clobber (reg:CC FLAGS_REG))])]
7488 [(set_attr "type" "multi")
7489 (set_attr "mode" "<MODE>")])
7491 (define_insn "*udivmod<mode>4_noext"
7492 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7493 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7494 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7495 (set (match_operand:SWIM248 1 "register_operand" "=d")
7496 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7497 (use (match_operand:SWIM248 4 "register_operand" "1"))
7498 (clobber (reg:CC FLAGS_REG))]
7500 "div{<imodesuffix>}\t%3"
7501 [(set_attr "type" "idiv")
7502 (set_attr "mode" "<MODE>")])
7504 (define_expand "udivmodqi4"
7505 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7507 (match_operand:QI 1 "register_operand" "")
7508 (match_operand:QI 2 "nonimmediate_operand" "")))
7509 (set (match_operand:QI 3 "register_operand" "")
7510 (umod:QI (match_dup 1) (match_dup 2)))
7511 (clobber (reg:CC FLAGS_REG))])]
7512 "TARGET_QIMODE_MATH"
7517 tmp0 = gen_reg_rtx (HImode);
7518 tmp1 = gen_reg_rtx (HImode);
7520 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7522 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7523 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7525 /* Extract remainder from AH. */
7526 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7527 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7528 insn = emit_move_insn (operands[3], tmp1);
7530 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7531 set_unique_reg_note (insn, REG_EQUAL, mod);
7533 /* Extract quotient from AL. */
7534 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7536 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7537 set_unique_reg_note (insn, REG_EQUAL, div);
7542 (define_insn "udivmodhiqi3"
7543 [(set (match_operand:HI 0 "register_operand" "=a")
7548 (mod:HI (match_operand:HI 1 "register_operand" "0")
7550 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7554 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7555 (clobber (reg:CC FLAGS_REG))]
7556 "TARGET_QIMODE_MATH"
7558 [(set_attr "type" "idiv")
7559 (set_attr "mode" "QI")])
7561 ;; We cannot use div/idiv for double division, because it causes
7562 ;; "division by zero" on the overflow and that's not what we expect
7563 ;; from truncate. Because true (non truncating) double division is
7564 ;; never generated, we can't create this insn anyway.
7567 ; [(set (match_operand:SI 0 "register_operand" "=a")
7569 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7571 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7572 ; (set (match_operand:SI 3 "register_operand" "=d")
7574 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7575 ; (clobber (reg:CC FLAGS_REG))]
7577 ; "div{l}\t{%2, %0|%0, %2}"
7578 ; [(set_attr "type" "idiv")])
7580 ;;- Logical AND instructions
7582 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7583 ;; Note that this excludes ah.
7585 (define_expand "testsi_ccno_1"
7586 [(set (reg:CCNO FLAGS_REG)
7588 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7589 (match_operand:SI 1 "nonmemory_operand" ""))
7592 (define_expand "testqi_ccz_1"
7593 [(set (reg:CCZ FLAGS_REG)
7594 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7595 (match_operand:QI 1 "nonmemory_operand" ""))
7598 (define_expand "testdi_ccno_1"
7599 [(set (reg:CCNO FLAGS_REG)
7601 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7602 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7604 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7606 (define_insn "*testdi_1"
7607 [(set (reg FLAGS_REG)
7610 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7611 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7613 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7614 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7616 test{l}\t{%k1, %k0|%k0, %k1}
7617 test{l}\t{%k1, %k0|%k0, %k1}
7618 test{q}\t{%1, %0|%0, %1}
7619 test{q}\t{%1, %0|%0, %1}
7620 test{q}\t{%1, %0|%0, %1}"
7621 [(set_attr "type" "test")
7622 (set_attr "modrm" "0,1,0,1,1")
7623 (set_attr "mode" "SI,SI,DI,DI,DI")])
7625 (define_insn "*testqi_1_maybe_si"
7626 [(set (reg FLAGS_REG)
7629 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7630 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7632 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7633 && ix86_match_ccmode (insn,
7634 CONST_INT_P (operands[1])
7635 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7637 if (which_alternative == 3)
7639 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7640 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7641 return "test{l}\t{%1, %k0|%k0, %1}";
7643 return "test{b}\t{%1, %0|%0, %1}";
7645 [(set_attr "type" "test")
7646 (set_attr "modrm" "0,1,1,1")
7647 (set_attr "mode" "QI,QI,QI,SI")
7648 (set_attr "pent_pair" "uv,np,uv,np")])
7650 (define_insn "*test<mode>_1"
7651 [(set (reg FLAGS_REG)
7654 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7655 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7657 "ix86_match_ccmode (insn, CCNOmode)
7658 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7659 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7660 [(set_attr "type" "test")
7661 (set_attr "modrm" "0,1,1")
7662 (set_attr "mode" "<MODE>")
7663 (set_attr "pent_pair" "uv,np,uv")])
7665 (define_expand "testqi_ext_ccno_0"
7666 [(set (reg:CCNO FLAGS_REG)
7670 (match_operand 0 "ext_register_operand" "")
7673 (match_operand 1 "const_int_operand" ""))
7676 (define_insn "*testqi_ext_0"
7677 [(set (reg FLAGS_REG)
7681 (match_operand 0 "ext_register_operand" "Q")
7684 (match_operand 1 "const_int_operand" "n"))
7686 "ix86_match_ccmode (insn, CCNOmode)"
7687 "test{b}\t{%1, %h0|%h0, %1}"
7688 [(set_attr "type" "test")
7689 (set_attr "mode" "QI")
7690 (set_attr "length_immediate" "1")
7691 (set_attr "modrm" "1")
7692 (set_attr "pent_pair" "np")])
7694 (define_insn "*testqi_ext_1_rex64"
7695 [(set (reg FLAGS_REG)
7699 (match_operand 0 "ext_register_operand" "Q")
7703 (match_operand:QI 1 "register_operand" "Q")))
7705 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7706 "test{b}\t{%1, %h0|%h0, %1}"
7707 [(set_attr "type" "test")
7708 (set_attr "mode" "QI")])
7710 (define_insn "*testqi_ext_1"
7711 [(set (reg FLAGS_REG)
7715 (match_operand 0 "ext_register_operand" "Q")
7719 (match_operand:QI 1 "general_operand" "Qm")))
7721 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7722 "test{b}\t{%1, %h0|%h0, %1}"
7723 [(set_attr "type" "test")
7724 (set_attr "mode" "QI")])
7726 (define_insn "*testqi_ext_2"
7727 [(set (reg FLAGS_REG)
7731 (match_operand 0 "ext_register_operand" "Q")
7735 (match_operand 1 "ext_register_operand" "Q")
7739 "ix86_match_ccmode (insn, CCNOmode)"
7740 "test{b}\t{%h1, %h0|%h0, %h1}"
7741 [(set_attr "type" "test")
7742 (set_attr "mode" "QI")])
7744 (define_insn "*testqi_ext_3_rex64"
7745 [(set (reg FLAGS_REG)
7746 (compare (zero_extract:DI
7747 (match_operand 0 "nonimmediate_operand" "rm")
7748 (match_operand:DI 1 "const_int_operand" "")
7749 (match_operand:DI 2 "const_int_operand" ""))
7752 && ix86_match_ccmode (insn, CCNOmode)
7753 && INTVAL (operands[1]) > 0
7754 && INTVAL (operands[2]) >= 0
7755 /* Ensure that resulting mask is zero or sign extended operand. */
7756 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7757 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7758 && INTVAL (operands[1]) > 32))
7759 && (GET_MODE (operands[0]) == SImode
7760 || GET_MODE (operands[0]) == DImode
7761 || GET_MODE (operands[0]) == HImode
7762 || GET_MODE (operands[0]) == QImode)"
7765 ;; Combine likes to form bit extractions for some tests. Humor it.
7766 (define_insn "*testqi_ext_3"
7767 [(set (reg FLAGS_REG)
7768 (compare (zero_extract:SI
7769 (match_operand 0 "nonimmediate_operand" "rm")
7770 (match_operand:SI 1 "const_int_operand" "")
7771 (match_operand:SI 2 "const_int_operand" ""))
7773 "ix86_match_ccmode (insn, CCNOmode)
7774 && INTVAL (operands[1]) > 0
7775 && INTVAL (operands[2]) >= 0
7776 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7777 && (GET_MODE (operands[0]) == SImode
7778 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7779 || GET_MODE (operands[0]) == HImode
7780 || GET_MODE (operands[0]) == QImode)"
7784 [(set (match_operand 0 "flags_reg_operand" "")
7785 (match_operator 1 "compare_operator"
7787 (match_operand 2 "nonimmediate_operand" "")
7788 (match_operand 3 "const_int_operand" "")
7789 (match_operand 4 "const_int_operand" ""))
7791 "ix86_match_ccmode (insn, CCNOmode)"
7792 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7794 rtx val = operands[2];
7795 HOST_WIDE_INT len = INTVAL (operands[3]);
7796 HOST_WIDE_INT pos = INTVAL (operands[4]);
7798 enum machine_mode mode, submode;
7800 mode = GET_MODE (val);
7803 /* ??? Combine likes to put non-volatile mem extractions in QImode
7804 no matter the size of the test. So find a mode that works. */
7805 if (! MEM_VOLATILE_P (val))
7807 mode = smallest_mode_for_size (pos + len, MODE_INT);
7808 val = adjust_address (val, mode, 0);
7811 else if (GET_CODE (val) == SUBREG
7812 && (submode = GET_MODE (SUBREG_REG (val)),
7813 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7814 && pos + len <= GET_MODE_BITSIZE (submode)
7815 && GET_MODE_CLASS (submode) == MODE_INT)
7817 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7819 val = SUBREG_REG (val);
7821 else if (mode == HImode && pos + len <= 8)
7823 /* Small HImode tests can be converted to QImode. */
7825 val = gen_lowpart (QImode, val);
7828 if (len == HOST_BITS_PER_WIDE_INT)
7831 mask = ((HOST_WIDE_INT)1 << len) - 1;
7834 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7837 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7838 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7839 ;; this is relatively important trick.
7840 ;; Do the conversion only post-reload to avoid limiting of the register class
7843 [(set (match_operand 0 "flags_reg_operand" "")
7844 (match_operator 1 "compare_operator"
7845 [(and (match_operand 2 "register_operand" "")
7846 (match_operand 3 "const_int_operand" ""))
7849 && QI_REG_P (operands[2])
7850 && GET_MODE (operands[2]) != QImode
7851 && ((ix86_match_ccmode (insn, CCZmode)
7852 && !(INTVAL (operands[3]) & ~(255 << 8)))
7853 || (ix86_match_ccmode (insn, CCNOmode)
7854 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7857 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7860 "operands[2] = gen_lowpart (SImode, operands[2]);
7861 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7864 [(set (match_operand 0 "flags_reg_operand" "")
7865 (match_operator 1 "compare_operator"
7866 [(and (match_operand 2 "nonimmediate_operand" "")
7867 (match_operand 3 "const_int_operand" ""))
7870 && GET_MODE (operands[2]) != QImode
7871 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7872 && ((ix86_match_ccmode (insn, CCZmode)
7873 && !(INTVAL (operands[3]) & ~255))
7874 || (ix86_match_ccmode (insn, CCNOmode)
7875 && !(INTVAL (operands[3]) & ~127)))"
7877 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7879 "operands[2] = gen_lowpart (QImode, operands[2]);
7880 operands[3] = gen_lowpart (QImode, operands[3]);")
7882 ;; %%% This used to optimize known byte-wide and operations to memory,
7883 ;; and sometimes to QImode registers. If this is considered useful,
7884 ;; it should be done with splitters.
7886 (define_expand "and<mode>3"
7887 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7888 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7889 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7891 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7893 (define_insn "*anddi_1"
7894 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7896 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7897 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7898 (clobber (reg:CC FLAGS_REG))]
7899 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7901 switch (get_attr_type (insn))
7905 enum machine_mode mode;
7907 gcc_assert (CONST_INT_P (operands[2]));
7908 if (INTVAL (operands[2]) == 0xff)
7912 gcc_assert (INTVAL (operands[2]) == 0xffff);
7916 operands[1] = gen_lowpart (mode, operands[1]);
7918 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7920 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7924 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7925 if (get_attr_mode (insn) == MODE_SI)
7926 return "and{l}\t{%k2, %k0|%k0, %k2}";
7928 return "and{q}\t{%2, %0|%0, %2}";
7931 [(set_attr "type" "alu,alu,alu,imovx")
7932 (set_attr "length_immediate" "*,*,*,0")
7933 (set (attr "prefix_rex")
7935 (and (eq_attr "type" "imovx")
7936 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7937 (match_operand 1 "ext_QIreg_operand" "")))
7939 (const_string "*")))
7940 (set_attr "mode" "SI,DI,DI,SI")])
7942 (define_insn "*andsi_1"
7943 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7944 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7945 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7946 (clobber (reg:CC FLAGS_REG))]
7947 "ix86_binary_operator_ok (AND, SImode, operands)"
7949 switch (get_attr_type (insn))
7953 enum machine_mode mode;
7955 gcc_assert (CONST_INT_P (operands[2]));
7956 if (INTVAL (operands[2]) == 0xff)
7960 gcc_assert (INTVAL (operands[2]) == 0xffff);
7964 operands[1] = gen_lowpart (mode, operands[1]);
7966 return "movz{bl|x}\t{%1, %0|%0, %1}";
7968 return "movz{wl|x}\t{%1, %0|%0, %1}";
7972 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7973 return "and{l}\t{%2, %0|%0, %2}";
7976 [(set_attr "type" "alu,alu,imovx")
7977 (set (attr "prefix_rex")
7979 (and (eq_attr "type" "imovx")
7980 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7981 (match_operand 1 "ext_QIreg_operand" "")))
7983 (const_string "*")))
7984 (set_attr "length_immediate" "*,*,0")
7985 (set_attr "mode" "SI")])
7987 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7988 (define_insn "*andsi_1_zext"
7989 [(set (match_operand:DI 0 "register_operand" "=r")
7991 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7992 (match_operand:SI 2 "general_operand" "g"))))
7993 (clobber (reg:CC FLAGS_REG))]
7994 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7995 "and{l}\t{%2, %k0|%k0, %2}"
7996 [(set_attr "type" "alu")
7997 (set_attr "mode" "SI")])
7999 (define_insn "*andhi_1"
8000 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8001 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8002 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8003 (clobber (reg:CC FLAGS_REG))]
8004 "ix86_binary_operator_ok (AND, HImode, operands)"
8006 switch (get_attr_type (insn))
8009 gcc_assert (CONST_INT_P (operands[2]));
8010 gcc_assert (INTVAL (operands[2]) == 0xff);
8011 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8014 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8016 return "and{w}\t{%2, %0|%0, %2}";
8019 [(set_attr "type" "alu,alu,imovx")
8020 (set_attr "length_immediate" "*,*,0")
8021 (set (attr "prefix_rex")
8023 (and (eq_attr "type" "imovx")
8024 (match_operand 1 "ext_QIreg_operand" ""))
8026 (const_string "*")))
8027 (set_attr "mode" "HI,HI,SI")])
8029 ;; %%% Potential partial reg stall on alternative 2. What to do?
8030 (define_insn "*andqi_1"
8031 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8032 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8033 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8034 (clobber (reg:CC FLAGS_REG))]
8035 "ix86_binary_operator_ok (AND, QImode, operands)"
8037 and{b}\t{%2, %0|%0, %2}
8038 and{b}\t{%2, %0|%0, %2}
8039 and{l}\t{%k2, %k0|%k0, %k2}"
8040 [(set_attr "type" "alu")
8041 (set_attr "mode" "QI,QI,SI")])
8043 (define_insn "*andqi_1_slp"
8044 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8045 (and:QI (match_dup 0)
8046 (match_operand:QI 1 "general_operand" "qn,qmn")))
8047 (clobber (reg:CC FLAGS_REG))]
8048 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8049 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8050 "and{b}\t{%1, %0|%0, %1}"
8051 [(set_attr "type" "alu1")
8052 (set_attr "mode" "QI")])
8055 [(set (match_operand 0 "register_operand" "")
8057 (const_int -65536)))
8058 (clobber (reg:CC FLAGS_REG))]
8059 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8060 || optimize_function_for_size_p (cfun)"
8061 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8062 "operands[1] = gen_lowpart (HImode, operands[0]);")
8065 [(set (match_operand 0 "ext_register_operand" "")
8068 (clobber (reg:CC FLAGS_REG))]
8069 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8070 && reload_completed"
8071 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8072 "operands[1] = gen_lowpart (QImode, operands[0]);")
8075 [(set (match_operand 0 "ext_register_operand" "")
8077 (const_int -65281)))
8078 (clobber (reg:CC FLAGS_REG))]
8079 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8080 && reload_completed"
8081 [(parallel [(set (zero_extract:SI (match_dup 0)
8085 (zero_extract:SI (match_dup 0)
8088 (zero_extract:SI (match_dup 0)
8091 (clobber (reg:CC FLAGS_REG))])]
8092 "operands[0] = gen_lowpart (SImode, operands[0]);")
8094 (define_insn "*anddi_2"
8095 [(set (reg FLAGS_REG)
8098 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8099 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8101 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8102 (and:DI (match_dup 1) (match_dup 2)))]
8103 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8104 && ix86_binary_operator_ok (AND, DImode, operands)"
8106 and{l}\t{%k2, %k0|%k0, %k2}
8107 and{q}\t{%2, %0|%0, %2}
8108 and{q}\t{%2, %0|%0, %2}"
8109 [(set_attr "type" "alu")
8110 (set_attr "mode" "SI,DI,DI")])
8112 (define_insn "*andqi_2_maybe_si"
8113 [(set (reg FLAGS_REG)
8115 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8116 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8118 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8119 (and:QI (match_dup 1) (match_dup 2)))]
8120 "ix86_binary_operator_ok (AND, QImode, operands)
8121 && ix86_match_ccmode (insn,
8122 CONST_INT_P (operands[2])
8123 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8125 if (which_alternative == 2)
8127 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8128 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8129 return "and{l}\t{%2, %k0|%k0, %2}";
8131 return "and{b}\t{%2, %0|%0, %2}";
8133 [(set_attr "type" "alu")
8134 (set_attr "mode" "QI,QI,SI")])
8136 (define_insn "*and<mode>_2"
8137 [(set (reg FLAGS_REG)
8138 (compare (and:SWI124
8139 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8140 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8142 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8143 (and:SWI124 (match_dup 1) (match_dup 2)))]
8144 "ix86_match_ccmode (insn, CCNOmode)
8145 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8146 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8147 [(set_attr "type" "alu")
8148 (set_attr "mode" "<MODE>")])
8150 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8151 (define_insn "*andsi_2_zext"
8152 [(set (reg FLAGS_REG)
8154 (match_operand:SI 1 "nonimmediate_operand" "%0")
8155 (match_operand:SI 2 "general_operand" "g"))
8157 (set (match_operand:DI 0 "register_operand" "=r")
8158 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8159 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8160 && ix86_binary_operator_ok (AND, SImode, operands)"
8161 "and{l}\t{%2, %k0|%k0, %2}"
8162 [(set_attr "type" "alu")
8163 (set_attr "mode" "SI")])
8165 (define_insn "*andqi_2_slp"
8166 [(set (reg FLAGS_REG)
8168 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8169 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8171 (set (strict_low_part (match_dup 0))
8172 (and:QI (match_dup 0) (match_dup 1)))]
8173 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8174 && ix86_match_ccmode (insn, CCNOmode)
8175 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8176 "and{b}\t{%1, %0|%0, %1}"
8177 [(set_attr "type" "alu1")
8178 (set_attr "mode" "QI")])
8180 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8181 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8182 ;; for a QImode operand, which of course failed.
8183 (define_insn "andqi_ext_0"
8184 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8189 (match_operand 1 "ext_register_operand" "0")
8192 (match_operand 2 "const_int_operand" "n")))
8193 (clobber (reg:CC FLAGS_REG))]
8195 "and{b}\t{%2, %h0|%h0, %2}"
8196 [(set_attr "type" "alu")
8197 (set_attr "length_immediate" "1")
8198 (set_attr "modrm" "1")
8199 (set_attr "mode" "QI")])
8201 ;; Generated by peephole translating test to and. This shows up
8202 ;; often in fp comparisons.
8203 (define_insn "*andqi_ext_0_cc"
8204 [(set (reg FLAGS_REG)
8208 (match_operand 1 "ext_register_operand" "0")
8211 (match_operand 2 "const_int_operand" "n"))
8213 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8222 "ix86_match_ccmode (insn, CCNOmode)"
8223 "and{b}\t{%2, %h0|%h0, %2}"
8224 [(set_attr "type" "alu")
8225 (set_attr "length_immediate" "1")
8226 (set_attr "modrm" "1")
8227 (set_attr "mode" "QI")])
8229 (define_insn "*andqi_ext_1_rex64"
8230 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8235 (match_operand 1 "ext_register_operand" "0")
8239 (match_operand 2 "ext_register_operand" "Q"))))
8240 (clobber (reg:CC FLAGS_REG))]
8242 "and{b}\t{%2, %h0|%h0, %2}"
8243 [(set_attr "type" "alu")
8244 (set_attr "length_immediate" "0")
8245 (set_attr "mode" "QI")])
8247 (define_insn "*andqi_ext_1"
8248 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8253 (match_operand 1 "ext_register_operand" "0")
8257 (match_operand:QI 2 "general_operand" "Qm"))))
8258 (clobber (reg:CC FLAGS_REG))]
8260 "and{b}\t{%2, %h0|%h0, %2}"
8261 [(set_attr "type" "alu")
8262 (set_attr "length_immediate" "0")
8263 (set_attr "mode" "QI")])
8265 (define_insn "*andqi_ext_2"
8266 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8271 (match_operand 1 "ext_register_operand" "%0")
8275 (match_operand 2 "ext_register_operand" "Q")
8278 (clobber (reg:CC FLAGS_REG))]
8280 "and{b}\t{%h2, %h0|%h0, %h2}"
8281 [(set_attr "type" "alu")
8282 (set_attr "length_immediate" "0")
8283 (set_attr "mode" "QI")])
8285 ;; Convert wide AND instructions with immediate operand to shorter QImode
8286 ;; equivalents when possible.
8287 ;; Don't do the splitting with memory operands, since it introduces risk
8288 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8289 ;; for size, but that can (should?) be handled by generic code instead.
8291 [(set (match_operand 0 "register_operand" "")
8292 (and (match_operand 1 "register_operand" "")
8293 (match_operand 2 "const_int_operand" "")))
8294 (clobber (reg:CC FLAGS_REG))]
8296 && QI_REG_P (operands[0])
8297 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8298 && !(~INTVAL (operands[2]) & ~(255 << 8))
8299 && GET_MODE (operands[0]) != QImode"
8300 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8301 (and:SI (zero_extract:SI (match_dup 1)
8302 (const_int 8) (const_int 8))
8304 (clobber (reg:CC FLAGS_REG))])]
8305 "operands[0] = gen_lowpart (SImode, operands[0]);
8306 operands[1] = gen_lowpart (SImode, operands[1]);
8307 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8309 ;; Since AND can be encoded with sign extended immediate, this is only
8310 ;; profitable when 7th bit is not set.
8312 [(set (match_operand 0 "register_operand" "")
8313 (and (match_operand 1 "general_operand" "")
8314 (match_operand 2 "const_int_operand" "")))
8315 (clobber (reg:CC FLAGS_REG))]
8317 && ANY_QI_REG_P (operands[0])
8318 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8319 && !(~INTVAL (operands[2]) & ~255)
8320 && !(INTVAL (operands[2]) & 128)
8321 && GET_MODE (operands[0]) != QImode"
8322 [(parallel [(set (strict_low_part (match_dup 0))
8323 (and:QI (match_dup 1)
8325 (clobber (reg:CC FLAGS_REG))])]
8326 "operands[0] = gen_lowpart (QImode, operands[0]);
8327 operands[1] = gen_lowpart (QImode, operands[1]);
8328 operands[2] = gen_lowpart (QImode, operands[2]);")
8330 ;; Logical inclusive and exclusive OR instructions
8332 ;; %%% This used to optimize known byte-wide and operations to memory.
8333 ;; If this is considered useful, it should be done with splitters.
8335 (define_expand "<code><mode>3"
8336 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8337 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8338 (match_operand:SWIM 2 "<general_operand>" "")))]
8340 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8342 (define_insn "*<code><mode>_1"
8343 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8345 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8346 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8347 (clobber (reg:CC FLAGS_REG))]
8348 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8349 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8350 [(set_attr "type" "alu")
8351 (set_attr "mode" "<MODE>")])
8353 ;; %%% Potential partial reg stall on alternative 2. What to do?
8354 (define_insn "*<code>qi_1"
8355 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8356 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8357 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8358 (clobber (reg:CC FLAGS_REG))]
8359 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8361 <logic>{b}\t{%2, %0|%0, %2}
8362 <logic>{b}\t{%2, %0|%0, %2}
8363 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "mode" "QI,QI,SI")])
8367 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8368 (define_insn "*<code>si_1_zext"
8369 [(set (match_operand:DI 0 "register_operand" "=r")
8371 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8372 (match_operand:SI 2 "general_operand" "g"))))
8373 (clobber (reg:CC FLAGS_REG))]
8374 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8375 "<logic>{l}\t{%2, %k0|%k0, %2}"
8376 [(set_attr "type" "alu")
8377 (set_attr "mode" "SI")])
8379 (define_insn "*<code>si_1_zext_imm"
8380 [(set (match_operand:DI 0 "register_operand" "=r")
8382 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8383 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8384 (clobber (reg:CC FLAGS_REG))]
8385 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8386 "<logic>{l}\t{%2, %k0|%k0, %2}"
8387 [(set_attr "type" "alu")
8388 (set_attr "mode" "SI")])
8390 (define_insn "*<code>qi_1_slp"
8391 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8392 (any_or:QI (match_dup 0)
8393 (match_operand:QI 1 "general_operand" "qmn,qn")))
8394 (clobber (reg:CC FLAGS_REG))]
8395 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8396 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8397 "<logic>{b}\t{%1, %0|%0, %1}"
8398 [(set_attr "type" "alu1")
8399 (set_attr "mode" "QI")])
8401 (define_insn "*<code><mode>_2"
8402 [(set (reg FLAGS_REG)
8403 (compare (any_or:SWI
8404 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8405 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8407 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8408 (any_or:SWI (match_dup 1) (match_dup 2)))]
8409 "ix86_match_ccmode (insn, CCNOmode)
8410 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8411 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8412 [(set_attr "type" "alu")
8413 (set_attr "mode" "<MODE>")])
8415 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8416 ;; ??? Special case for immediate operand is missing - it is tricky.
8417 (define_insn "*<code>si_2_zext"
8418 [(set (reg FLAGS_REG)
8419 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8420 (match_operand:SI 2 "general_operand" "g"))
8422 (set (match_operand:DI 0 "register_operand" "=r")
8423 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8424 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8425 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8426 "<logic>{l}\t{%2, %k0|%k0, %2}"
8427 [(set_attr "type" "alu")
8428 (set_attr "mode" "SI")])
8430 (define_insn "*<code>si_2_zext_imm"
8431 [(set (reg FLAGS_REG)
8433 (match_operand:SI 1 "nonimmediate_operand" "%0")
8434 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8436 (set (match_operand:DI 0 "register_operand" "=r")
8437 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8438 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8439 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8440 "<logic>{l}\t{%2, %k0|%k0, %2}"
8441 [(set_attr "type" "alu")
8442 (set_attr "mode" "SI")])
8444 (define_insn "*<code>qi_2_slp"
8445 [(set (reg FLAGS_REG)
8446 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8447 (match_operand:QI 1 "general_operand" "qmn,qn"))
8449 (set (strict_low_part (match_dup 0))
8450 (any_or:QI (match_dup 0) (match_dup 1)))]
8451 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8452 && ix86_match_ccmode (insn, CCNOmode)
8453 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8454 "<logic>{b}\t{%1, %0|%0, %1}"
8455 [(set_attr "type" "alu1")
8456 (set_attr "mode" "QI")])
8458 (define_insn "*<code><mode>_3"
8459 [(set (reg FLAGS_REG)
8460 (compare (any_or:SWI
8461 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8462 (match_operand:SWI 2 "<general_operand>" "<g>"))
8464 (clobber (match_scratch:SWI 0 "=<r>"))]
8465 "ix86_match_ccmode (insn, CCNOmode)
8466 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8467 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8468 [(set_attr "type" "alu")
8469 (set_attr "mode" "<MODE>")])
8471 (define_insn "*<code>qi_ext_0"
8472 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8477 (match_operand 1 "ext_register_operand" "0")
8480 (match_operand 2 "const_int_operand" "n")))
8481 (clobber (reg:CC FLAGS_REG))]
8482 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8483 "<logic>{b}\t{%2, %h0|%h0, %2}"
8484 [(set_attr "type" "alu")
8485 (set_attr "length_immediate" "1")
8486 (set_attr "modrm" "1")
8487 (set_attr "mode" "QI")])
8489 (define_insn "*<code>qi_ext_1_rex64"
8490 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8495 (match_operand 1 "ext_register_operand" "0")
8499 (match_operand 2 "ext_register_operand" "Q"))))
8500 (clobber (reg:CC FLAGS_REG))]
8502 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8503 "<logic>{b}\t{%2, %h0|%h0, %2}"
8504 [(set_attr "type" "alu")
8505 (set_attr "length_immediate" "0")
8506 (set_attr "mode" "QI")])
8508 (define_insn "*<code>qi_ext_1"
8509 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8514 (match_operand 1 "ext_register_operand" "0")
8518 (match_operand:QI 2 "general_operand" "Qm"))))
8519 (clobber (reg:CC FLAGS_REG))]
8521 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8522 "<logic>{b}\t{%2, %h0|%h0, %2}"
8523 [(set_attr "type" "alu")
8524 (set_attr "length_immediate" "0")
8525 (set_attr "mode" "QI")])
8527 (define_insn "*<code>qi_ext_2"
8528 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8532 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8535 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8538 (clobber (reg:CC FLAGS_REG))]
8539 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8540 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8541 [(set_attr "type" "alu")
8542 (set_attr "length_immediate" "0")
8543 (set_attr "mode" "QI")])
8546 [(set (match_operand 0 "register_operand" "")
8547 (any_or (match_operand 1 "register_operand" "")
8548 (match_operand 2 "const_int_operand" "")))
8549 (clobber (reg:CC FLAGS_REG))]
8551 && QI_REG_P (operands[0])
8552 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8553 && !(INTVAL (operands[2]) & ~(255 << 8))
8554 && GET_MODE (operands[0]) != QImode"
8555 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8556 (any_or:SI (zero_extract:SI (match_dup 1)
8557 (const_int 8) (const_int 8))
8559 (clobber (reg:CC FLAGS_REG))])]
8560 "operands[0] = gen_lowpart (SImode, operands[0]);
8561 operands[1] = gen_lowpart (SImode, operands[1]);
8562 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8564 ;; Since OR can be encoded with sign extended immediate, this is only
8565 ;; profitable when 7th bit is set.
8567 [(set (match_operand 0 "register_operand" "")
8568 (any_or (match_operand 1 "general_operand" "")
8569 (match_operand 2 "const_int_operand" "")))
8570 (clobber (reg:CC FLAGS_REG))]
8572 && ANY_QI_REG_P (operands[0])
8573 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8574 && !(INTVAL (operands[2]) & ~255)
8575 && (INTVAL (operands[2]) & 128)
8576 && GET_MODE (operands[0]) != QImode"
8577 [(parallel [(set (strict_low_part (match_dup 0))
8578 (any_or:QI (match_dup 1)
8580 (clobber (reg:CC FLAGS_REG))])]
8581 "operands[0] = gen_lowpart (QImode, operands[0]);
8582 operands[1] = gen_lowpart (QImode, operands[1]);
8583 operands[2] = gen_lowpart (QImode, operands[2]);")
8585 (define_expand "xorqi_cc_ext_1"
8587 (set (reg:CCNO FLAGS_REG)
8591 (match_operand 1 "ext_register_operand" "")
8594 (match_operand:QI 2 "general_operand" ""))
8596 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8606 (define_insn "*xorqi_cc_ext_1_rex64"
8607 [(set (reg FLAGS_REG)
8611 (match_operand 1 "ext_register_operand" "0")
8614 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8616 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8625 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8626 "xor{b}\t{%2, %h0|%h0, %2}"
8627 [(set_attr "type" "alu")
8628 (set_attr "modrm" "1")
8629 (set_attr "mode" "QI")])
8631 (define_insn "*xorqi_cc_ext_1"
8632 [(set (reg FLAGS_REG)
8636 (match_operand 1 "ext_register_operand" "0")
8639 (match_operand:QI 2 "general_operand" "qmn"))
8641 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8650 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8651 "xor{b}\t{%2, %h0|%h0, %2}"
8652 [(set_attr "type" "alu")
8653 (set_attr "modrm" "1")
8654 (set_attr "mode" "QI")])
8656 ;; Negation instructions
8658 (define_expand "neg<mode>2"
8659 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8660 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8662 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8664 (define_insn_and_split "*neg<dwi>2_doubleword"
8665 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8666 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8667 (clobber (reg:CC FLAGS_REG))]
8668 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8672 [(set (reg:CCZ FLAGS_REG)
8673 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8674 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8677 (plus:DWIH (match_dup 3)
8678 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8680 (clobber (reg:CC FLAGS_REG))])
8683 (neg:DWIH (match_dup 2)))
8684 (clobber (reg:CC FLAGS_REG))])]
8685 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8687 (define_insn "*neg<mode>2_1"
8688 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8689 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8690 (clobber (reg:CC FLAGS_REG))]
8691 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8692 "neg{<imodesuffix>}\t%0"
8693 [(set_attr "type" "negnot")
8694 (set_attr "mode" "<MODE>")])
8696 ;; Combine is quite creative about this pattern.
8697 (define_insn "*negsi2_1_zext"
8698 [(set (match_operand:DI 0 "register_operand" "=r")
8700 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8703 (clobber (reg:CC FLAGS_REG))]
8704 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8706 [(set_attr "type" "negnot")
8707 (set_attr "mode" "SI")])
8709 ;; The problem with neg is that it does not perform (compare x 0),
8710 ;; it really performs (compare 0 x), which leaves us with the zero
8711 ;; flag being the only useful item.
8713 (define_insn "*neg<mode>2_cmpz"
8714 [(set (reg:CCZ FLAGS_REG)
8716 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8718 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8719 (neg:SWI (match_dup 1)))]
8720 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8721 "neg{<imodesuffix>}\t%0"
8722 [(set_attr "type" "negnot")
8723 (set_attr "mode" "<MODE>")])
8725 (define_insn "*negsi2_cmpz_zext"
8726 [(set (reg:CCZ FLAGS_REG)
8730 (match_operand:DI 1 "register_operand" "0")
8734 (set (match_operand:DI 0 "register_operand" "=r")
8735 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8738 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8740 [(set_attr "type" "negnot")
8741 (set_attr "mode" "SI")])
8743 ;; Changing of sign for FP values is doable using integer unit too.
8745 (define_expand "<code><mode>2"
8746 [(set (match_operand:X87MODEF 0 "register_operand" "")
8747 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8748 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8749 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8751 (define_insn "*absneg<mode>2_mixed"
8752 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8753 (match_operator:MODEF 3 "absneg_operator"
8754 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8755 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8756 (clobber (reg:CC FLAGS_REG))]
8757 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8760 (define_insn "*absneg<mode>2_sse"
8761 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8762 (match_operator:MODEF 3 "absneg_operator"
8763 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8764 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8765 (clobber (reg:CC FLAGS_REG))]
8766 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8769 (define_insn "*absneg<mode>2_i387"
8770 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8771 (match_operator:X87MODEF 3 "absneg_operator"
8772 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8773 (use (match_operand 2 "" ""))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8778 (define_expand "<code>tf2"
8779 [(set (match_operand:TF 0 "register_operand" "")
8780 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8782 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8784 (define_insn "*absnegtf2_sse"
8785 [(set (match_operand:TF 0 "register_operand" "=x,x")
8786 (match_operator:TF 3 "absneg_operator"
8787 [(match_operand:TF 1 "register_operand" "0,x")]))
8788 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8789 (clobber (reg:CC FLAGS_REG))]
8793 ;; Splitters for fp abs and neg.
8796 [(set (match_operand 0 "fp_register_operand" "")
8797 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8798 (use (match_operand 2 "" ""))
8799 (clobber (reg:CC FLAGS_REG))]
8801 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8804 [(set (match_operand 0 "register_operand" "")
8805 (match_operator 3 "absneg_operator"
8806 [(match_operand 1 "register_operand" "")]))
8807 (use (match_operand 2 "nonimmediate_operand" ""))
8808 (clobber (reg:CC FLAGS_REG))]
8809 "reload_completed && SSE_REG_P (operands[0])"
8810 [(set (match_dup 0) (match_dup 3))]
8812 enum machine_mode mode = GET_MODE (operands[0]);
8813 enum machine_mode vmode = GET_MODE (operands[2]);
8816 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8817 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8818 if (operands_match_p (operands[0], operands[2]))
8821 operands[1] = operands[2];
8824 if (GET_CODE (operands[3]) == ABS)
8825 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8827 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8832 [(set (match_operand:SF 0 "register_operand" "")
8833 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8834 (use (match_operand:V4SF 2 "" ""))
8835 (clobber (reg:CC FLAGS_REG))]
8837 [(parallel [(set (match_dup 0) (match_dup 1))
8838 (clobber (reg:CC FLAGS_REG))])]
8841 operands[0] = gen_lowpart (SImode, operands[0]);
8842 if (GET_CODE (operands[1]) == ABS)
8844 tmp = gen_int_mode (0x7fffffff, SImode);
8845 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8849 tmp = gen_int_mode (0x80000000, SImode);
8850 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8856 [(set (match_operand:DF 0 "register_operand" "")
8857 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8858 (use (match_operand 2 "" ""))
8859 (clobber (reg:CC FLAGS_REG))]
8861 [(parallel [(set (match_dup 0) (match_dup 1))
8862 (clobber (reg:CC FLAGS_REG))])]
8867 tmp = gen_lowpart (DImode, operands[0]);
8868 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8871 if (GET_CODE (operands[1]) == ABS)
8874 tmp = gen_rtx_NOT (DImode, tmp);
8878 operands[0] = gen_highpart (SImode, operands[0]);
8879 if (GET_CODE (operands[1]) == ABS)
8881 tmp = gen_int_mode (0x7fffffff, SImode);
8882 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8886 tmp = gen_int_mode (0x80000000, SImode);
8887 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8894 [(set (match_operand:XF 0 "register_operand" "")
8895 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8896 (use (match_operand 2 "" ""))
8897 (clobber (reg:CC FLAGS_REG))]
8899 [(parallel [(set (match_dup 0) (match_dup 1))
8900 (clobber (reg:CC FLAGS_REG))])]
8903 operands[0] = gen_rtx_REG (SImode,
8904 true_regnum (operands[0])
8905 + (TARGET_64BIT ? 1 : 2));
8906 if (GET_CODE (operands[1]) == ABS)
8908 tmp = GEN_INT (0x7fff);
8909 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8913 tmp = GEN_INT (0x8000);
8914 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8919 ;; Conditionalize these after reload. If they match before reload, we
8920 ;; lose the clobber and ability to use integer instructions.
8922 (define_insn "*<code><mode>2_1"
8923 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8924 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8926 && (reload_completed
8927 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8928 "f<absneg_mnemonic>"
8929 [(set_attr "type" "fsgn")
8930 (set_attr "mode" "<MODE>")])
8932 (define_insn "*<code>extendsfdf2"
8933 [(set (match_operand:DF 0 "register_operand" "=f")
8934 (absneg:DF (float_extend:DF
8935 (match_operand:SF 1 "register_operand" "0"))))]
8936 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8937 "f<absneg_mnemonic>"
8938 [(set_attr "type" "fsgn")
8939 (set_attr "mode" "DF")])
8941 (define_insn "*<code>extendsfxf2"
8942 [(set (match_operand:XF 0 "register_operand" "=f")
8943 (absneg:XF (float_extend:XF
8944 (match_operand:SF 1 "register_operand" "0"))))]
8946 "f<absneg_mnemonic>"
8947 [(set_attr "type" "fsgn")
8948 (set_attr "mode" "XF")])
8950 (define_insn "*<code>extenddfxf2"
8951 [(set (match_operand:XF 0 "register_operand" "=f")
8952 (absneg:XF (float_extend:XF
8953 (match_operand:DF 1 "register_operand" "0"))))]
8955 "f<absneg_mnemonic>"
8956 [(set_attr "type" "fsgn")
8957 (set_attr "mode" "XF")])
8959 ;; Copysign instructions
8961 (define_mode_iterator CSGNMODE [SF DF TF])
8962 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8964 (define_expand "copysign<mode>3"
8965 [(match_operand:CSGNMODE 0 "register_operand" "")
8966 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8967 (match_operand:CSGNMODE 2 "register_operand" "")]
8968 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8969 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8970 "ix86_expand_copysign (operands); DONE;")
8972 (define_insn_and_split "copysign<mode>3_const"
8973 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8975 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8976 (match_operand:CSGNMODE 2 "register_operand" "0")
8977 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8979 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8980 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8982 "&& reload_completed"
8984 "ix86_split_copysign_const (operands); DONE;")
8986 (define_insn "copysign<mode>3_var"
8987 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8989 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8990 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8991 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8992 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8994 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8995 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8996 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9000 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9002 [(match_operand:CSGNMODE 2 "register_operand" "")
9003 (match_operand:CSGNMODE 3 "register_operand" "")
9004 (match_operand:<CSGNVMODE> 4 "" "")
9005 (match_operand:<CSGNVMODE> 5 "" "")]
9007 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9008 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9009 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9010 && reload_completed"
9012 "ix86_split_copysign_var (operands); DONE;")
9014 ;; One complement instructions
9016 (define_expand "one_cmpl<mode>2"
9017 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9018 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9020 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9022 (define_insn "*one_cmpl<mode>2_1"
9023 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9024 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9025 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9026 "not{<imodesuffix>}\t%0"
9027 [(set_attr "type" "negnot")
9028 (set_attr "mode" "<MODE>")])
9030 ;; %%% Potential partial reg stall on alternative 1. What to do?
9031 (define_insn "*one_cmplqi2_1"
9032 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9033 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9034 "ix86_unary_operator_ok (NOT, QImode, operands)"
9038 [(set_attr "type" "negnot")
9039 (set_attr "mode" "QI,SI")])
9041 ;; ??? Currently never generated - xor is used instead.
9042 (define_insn "*one_cmplsi2_1_zext"
9043 [(set (match_operand:DI 0 "register_operand" "=r")
9045 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9046 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9048 [(set_attr "type" "negnot")
9049 (set_attr "mode" "SI")])
9051 (define_insn "*one_cmpl<mode>2_2"
9052 [(set (reg FLAGS_REG)
9053 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9055 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9056 (not:SWI (match_dup 1)))]
9057 "ix86_match_ccmode (insn, CCNOmode)
9058 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9060 [(set_attr "type" "alu1")
9061 (set_attr "mode" "<MODE>")])
9064 [(set (match_operand 0 "flags_reg_operand" "")
9065 (match_operator 2 "compare_operator"
9066 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9068 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9069 (not:SWI (match_dup 3)))]
9070 "ix86_match_ccmode (insn, CCNOmode)"
9071 [(parallel [(set (match_dup 0)
9072 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9075 (xor:SWI (match_dup 3) (const_int -1)))])])
9077 ;; ??? Currently never generated - xor is used instead.
9078 (define_insn "*one_cmplsi2_2_zext"
9079 [(set (reg FLAGS_REG)
9080 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9082 (set (match_operand:DI 0 "register_operand" "=r")
9083 (zero_extend:DI (not:SI (match_dup 1))))]
9084 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9085 && ix86_unary_operator_ok (NOT, SImode, operands)"
9087 [(set_attr "type" "alu1")
9088 (set_attr "mode" "SI")])
9091 [(set (match_operand 0 "flags_reg_operand" "")
9092 (match_operator 2 "compare_operator"
9093 [(not:SI (match_operand:SI 3 "register_operand" ""))
9095 (set (match_operand:DI 1 "register_operand" "")
9096 (zero_extend:DI (not:SI (match_dup 3))))]
9097 "ix86_match_ccmode (insn, CCNOmode)"
9098 [(parallel [(set (match_dup 0)
9099 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9102 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9104 ;; Shift instructions
9106 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9107 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9108 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9109 ;; from the assembler input.
9111 ;; This instruction shifts the target reg/mem as usual, but instead of
9112 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9113 ;; is a left shift double, bits are taken from the high order bits of
9114 ;; reg, else if the insn is a shift right double, bits are taken from the
9115 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9116 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9118 ;; Since sh[lr]d does not change the `reg' operand, that is done
9119 ;; separately, making all shifts emit pairs of shift double and normal
9120 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9121 ;; support a 63 bit shift, each shift where the count is in a reg expands
9122 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9124 ;; If the shift count is a constant, we need never emit more than one
9125 ;; shift pair, instead using moves and sign extension for counts greater
9128 (define_expand "ashl<mode>3"
9129 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9130 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9131 (match_operand:QI 2 "nonmemory_operand" "")))]
9133 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9135 (define_insn "*ashl<mode>3_doubleword"
9136 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9137 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9138 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9139 (clobber (reg:CC FLAGS_REG))]
9142 [(set_attr "type" "multi")])
9145 [(set (match_operand:DWI 0 "register_operand" "")
9146 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9147 (match_operand:QI 2 "nonmemory_operand" "")))
9148 (clobber (reg:CC FLAGS_REG))]
9149 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9151 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9153 ;; By default we don't ask for a scratch register, because when DWImode
9154 ;; values are manipulated, registers are already at a premium. But if
9155 ;; we have one handy, we won't turn it away.
9158 [(match_scratch:DWIH 3 "r")
9159 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9161 (match_operand:<DWI> 1 "nonmemory_operand" "")
9162 (match_operand:QI 2 "nonmemory_operand" "")))
9163 (clobber (reg:CC FLAGS_REG))])
9167 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9169 (define_insn "x86_64_shld"
9170 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9171 (ior:DI (ashift:DI (match_dup 0)
9172 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9173 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9174 (minus:QI (const_int 64) (match_dup 2)))))
9175 (clobber (reg:CC FLAGS_REG))]
9177 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9178 [(set_attr "type" "ishift")
9179 (set_attr "prefix_0f" "1")
9180 (set_attr "mode" "DI")
9181 (set_attr "athlon_decode" "vector")
9182 (set_attr "amdfam10_decode" "vector")
9183 (set_attr "bdver1_decode" "vector")])
9185 (define_insn "x86_shld"
9186 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9187 (ior:SI (ashift:SI (match_dup 0)
9188 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9189 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9190 (minus:QI (const_int 32) (match_dup 2)))))
9191 (clobber (reg:CC FLAGS_REG))]
9193 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9194 [(set_attr "type" "ishift")
9195 (set_attr "prefix_0f" "1")
9196 (set_attr "mode" "SI")
9197 (set_attr "pent_pair" "np")
9198 (set_attr "athlon_decode" "vector")
9199 (set_attr "amdfam10_decode" "vector")
9200 (set_attr "bdver1_decode" "vector")])
9202 (define_expand "x86_shift<mode>_adj_1"
9203 [(set (reg:CCZ FLAGS_REG)
9204 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9207 (set (match_operand:SWI48 0 "register_operand" "")
9208 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9209 (match_operand:SWI48 1 "register_operand" "")
9212 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9213 (match_operand:SWI48 3 "register_operand" "r")
9216 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9218 (define_expand "x86_shift<mode>_adj_2"
9219 [(use (match_operand:SWI48 0 "register_operand" ""))
9220 (use (match_operand:SWI48 1 "register_operand" ""))
9221 (use (match_operand:QI 2 "register_operand" ""))]
9224 rtx label = gen_label_rtx ();
9227 emit_insn (gen_testqi_ccz_1 (operands[2],
9228 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9230 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9231 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9232 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9233 gen_rtx_LABEL_REF (VOIDmode, label),
9235 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9236 JUMP_LABEL (tmp) = label;
9238 emit_move_insn (operands[0], operands[1]);
9239 ix86_expand_clear (operands[1]);
9242 LABEL_NUSES (label) = 1;
9247 ;; Avoid useless masking of count operand.
9248 (define_insn_and_split "*ashl<mode>3_mask"
9249 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9251 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9254 (match_operand:SI 2 "nonimmediate_operand" "c")
9255 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9256 (clobber (reg:CC FLAGS_REG))]
9257 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9258 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9259 == GET_MODE_BITSIZE (<MODE>mode)-1"
9262 [(parallel [(set (match_dup 0)
9263 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9264 (clobber (reg:CC FLAGS_REG))])]
9266 if (can_create_pseudo_p ())
9267 operands [2] = force_reg (SImode, operands[2]);
9269 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9271 [(set_attr "type" "ishift")
9272 (set_attr "mode" "<MODE>")])
9274 (define_insn "*ashl<mode>3_1"
9275 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9276 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9277 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9278 (clobber (reg:CC FLAGS_REG))]
9279 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9281 switch (get_attr_type (insn))
9287 gcc_assert (operands[2] == const1_rtx);
9288 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9289 return "add{<imodesuffix>}\t%0, %0";
9292 if (operands[2] == const1_rtx
9293 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9294 return "sal{<imodesuffix>}\t%0";
9296 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9300 (cond [(eq_attr "alternative" "1")
9301 (const_string "lea")
9302 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9304 (match_operand 0 "register_operand" ""))
9305 (match_operand 2 "const1_operand" ""))
9306 (const_string "alu")
9308 (const_string "ishift")))
9309 (set (attr "length_immediate")
9311 (ior (eq_attr "type" "alu")
9312 (and (eq_attr "type" "ishift")
9313 (and (match_operand 2 "const1_operand" "")
9314 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9317 (const_string "*")))
9318 (set_attr "mode" "<MODE>")])
9320 (define_insn "*ashlsi3_1_zext"
9321 [(set (match_operand:DI 0 "register_operand" "=r,r")
9323 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9324 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9325 (clobber (reg:CC FLAGS_REG))]
9326 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9328 switch (get_attr_type (insn))
9334 gcc_assert (operands[2] == const1_rtx);
9335 return "add{l}\t%k0, %k0";
9338 if (operands[2] == const1_rtx
9339 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9340 return "sal{l}\t%k0";
9342 return "sal{l}\t{%2, %k0|%k0, %2}";
9346 (cond [(eq_attr "alternative" "1")
9347 (const_string "lea")
9348 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9350 (match_operand 2 "const1_operand" ""))
9351 (const_string "alu")
9353 (const_string "ishift")))
9354 (set (attr "length_immediate")
9356 (ior (eq_attr "type" "alu")
9357 (and (eq_attr "type" "ishift")
9358 (and (match_operand 2 "const1_operand" "")
9359 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9362 (const_string "*")))
9363 (set_attr "mode" "SI")])
9365 (define_insn "*ashlhi3_1"
9366 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9367 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9368 (match_operand:QI 2 "nonmemory_operand" "cI")))
9369 (clobber (reg:CC FLAGS_REG))]
9370 "TARGET_PARTIAL_REG_STALL
9371 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9373 switch (get_attr_type (insn))
9376 gcc_assert (operands[2] == const1_rtx);
9377 return "add{w}\t%0, %0";
9380 if (operands[2] == const1_rtx
9381 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9382 return "sal{w}\t%0";
9384 return "sal{w}\t{%2, %0|%0, %2}";
9388 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9390 (match_operand 0 "register_operand" ""))
9391 (match_operand 2 "const1_operand" ""))
9392 (const_string "alu")
9394 (const_string "ishift")))
9395 (set (attr "length_immediate")
9397 (ior (eq_attr "type" "alu")
9398 (and (eq_attr "type" "ishift")
9399 (and (match_operand 2 "const1_operand" "")
9400 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9403 (const_string "*")))
9404 (set_attr "mode" "HI")])
9406 (define_insn "*ashlhi3_1_lea"
9407 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9408 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9409 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9410 (clobber (reg:CC FLAGS_REG))]
9411 "!TARGET_PARTIAL_REG_STALL
9412 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9414 switch (get_attr_type (insn))
9420 gcc_assert (operands[2] == const1_rtx);
9421 return "add{w}\t%0, %0";
9424 if (operands[2] == const1_rtx
9425 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9426 return "sal{w}\t%0";
9428 return "sal{w}\t{%2, %0|%0, %2}";
9432 (cond [(eq_attr "alternative" "1")
9433 (const_string "lea")
9434 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9436 (match_operand 0 "register_operand" ""))
9437 (match_operand 2 "const1_operand" ""))
9438 (const_string "alu")
9440 (const_string "ishift")))
9441 (set (attr "length_immediate")
9443 (ior (eq_attr "type" "alu")
9444 (and (eq_attr "type" "ishift")
9445 (and (match_operand 2 "const1_operand" "")
9446 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9449 (const_string "*")))
9450 (set_attr "mode" "HI,SI")])
9452 (define_insn "*ashlqi3_1"
9453 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9454 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9455 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9456 (clobber (reg:CC FLAGS_REG))]
9457 "TARGET_PARTIAL_REG_STALL
9458 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9460 switch (get_attr_type (insn))
9463 gcc_assert (operands[2] == const1_rtx);
9464 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9465 return "add{l}\t%k0, %k0";
9467 return "add{b}\t%0, %0";
9470 if (operands[2] == const1_rtx
9471 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9473 if (get_attr_mode (insn) == MODE_SI)
9474 return "sal{l}\t%k0";
9476 return "sal{b}\t%0";
9480 if (get_attr_mode (insn) == MODE_SI)
9481 return "sal{l}\t{%2, %k0|%k0, %2}";
9483 return "sal{b}\t{%2, %0|%0, %2}";
9488 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9490 (match_operand 0 "register_operand" ""))
9491 (match_operand 2 "const1_operand" ""))
9492 (const_string "alu")
9494 (const_string "ishift")))
9495 (set (attr "length_immediate")
9497 (ior (eq_attr "type" "alu")
9498 (and (eq_attr "type" "ishift")
9499 (and (match_operand 2 "const1_operand" "")
9500 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9503 (const_string "*")))
9504 (set_attr "mode" "QI,SI")])
9506 ;; %%% Potential partial reg stall on alternative 2. What to do?
9507 (define_insn "*ashlqi3_1_lea"
9508 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9509 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9510 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9511 (clobber (reg:CC FLAGS_REG))]
9512 "!TARGET_PARTIAL_REG_STALL
9513 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9515 switch (get_attr_type (insn))
9521 gcc_assert (operands[2] == const1_rtx);
9522 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9523 return "add{l}\t%k0, %k0";
9525 return "add{b}\t%0, %0";
9528 if (operands[2] == const1_rtx
9529 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9531 if (get_attr_mode (insn) == MODE_SI)
9532 return "sal{l}\t%k0";
9534 return "sal{b}\t%0";
9538 if (get_attr_mode (insn) == MODE_SI)
9539 return "sal{l}\t{%2, %k0|%k0, %2}";
9541 return "sal{b}\t{%2, %0|%0, %2}";
9546 (cond [(eq_attr "alternative" "2")
9547 (const_string "lea")
9548 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9550 (match_operand 0 "register_operand" ""))
9551 (match_operand 2 "const1_operand" ""))
9552 (const_string "alu")
9554 (const_string "ishift")))
9555 (set (attr "length_immediate")
9557 (ior (eq_attr "type" "alu")
9558 (and (eq_attr "type" "ishift")
9559 (and (match_operand 2 "const1_operand" "")
9560 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9563 (const_string "*")))
9564 (set_attr "mode" "QI,SI,SI")])
9566 (define_insn "*ashlqi3_1_slp"
9567 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9568 (ashift:QI (match_dup 0)
9569 (match_operand:QI 1 "nonmemory_operand" "cI")))
9570 (clobber (reg:CC FLAGS_REG))]
9571 "(optimize_function_for_size_p (cfun)
9572 || !TARGET_PARTIAL_FLAG_REG_STALL
9573 || (operands[1] == const1_rtx
9575 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9577 switch (get_attr_type (insn))
9580 gcc_assert (operands[1] == const1_rtx);
9581 return "add{b}\t%0, %0";
9584 if (operands[1] == const1_rtx
9585 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9586 return "sal{b}\t%0";
9588 return "sal{b}\t{%1, %0|%0, %1}";
9592 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9594 (match_operand 0 "register_operand" ""))
9595 (match_operand 1 "const1_operand" ""))
9596 (const_string "alu")
9598 (const_string "ishift1")))
9599 (set (attr "length_immediate")
9601 (ior (eq_attr "type" "alu")
9602 (and (eq_attr "type" "ishift1")
9603 (and (match_operand 1 "const1_operand" "")
9604 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9607 (const_string "*")))
9608 (set_attr "mode" "QI")])
9610 ;; Convert lea to the lea pattern to avoid flags dependency.
9612 [(set (match_operand 0 "register_operand" "")
9613 (ashift (match_operand 1 "index_register_operand" "")
9614 (match_operand:QI 2 "const_int_operand" "")))
9615 (clobber (reg:CC FLAGS_REG))]
9617 && true_regnum (operands[0]) != true_regnum (operands[1])"
9621 enum machine_mode mode = GET_MODE (operands[0]);
9624 operands[1] = gen_lowpart (Pmode, operands[1]);
9625 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9627 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9629 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9630 operands[0] = gen_lowpart (SImode, operands[0]);
9632 if (TARGET_64BIT && mode != Pmode)
9633 pat = gen_rtx_SUBREG (SImode, pat, 0);
9635 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9639 ;; Convert lea to the lea pattern to avoid flags dependency.
9641 [(set (match_operand:DI 0 "register_operand" "")
9643 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9644 (match_operand:QI 2 "const_int_operand" ""))))
9645 (clobber (reg:CC FLAGS_REG))]
9646 "TARGET_64BIT && reload_completed
9647 && true_regnum (operands[0]) != true_regnum (operands[1])"
9649 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9651 operands[1] = gen_lowpart (DImode, operands[1]);
9652 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9655 ;; This pattern can't accept a variable shift count, since shifts by
9656 ;; zero don't affect the flags. We assume that shifts by constant
9657 ;; zero are optimized away.
9658 (define_insn "*ashl<mode>3_cmp"
9659 [(set (reg FLAGS_REG)
9661 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9662 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9664 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9665 (ashift:SWI (match_dup 1) (match_dup 2)))]
9666 "(optimize_function_for_size_p (cfun)
9667 || !TARGET_PARTIAL_FLAG_REG_STALL
9668 || (operands[2] == const1_rtx
9670 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9671 && ix86_match_ccmode (insn, CCGOCmode)
9672 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9674 switch (get_attr_type (insn))
9677 gcc_assert (operands[2] == const1_rtx);
9678 return "add{<imodesuffix>}\t%0, %0";
9681 if (operands[2] == const1_rtx
9682 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9683 return "sal{<imodesuffix>}\t%0";
9685 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9689 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9691 (match_operand 0 "register_operand" ""))
9692 (match_operand 2 "const1_operand" ""))
9693 (const_string "alu")
9695 (const_string "ishift")))
9696 (set (attr "length_immediate")
9698 (ior (eq_attr "type" "alu")
9699 (and (eq_attr "type" "ishift")
9700 (and (match_operand 2 "const1_operand" "")
9701 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9704 (const_string "*")))
9705 (set_attr "mode" "<MODE>")])
9707 (define_insn "*ashlsi3_cmp_zext"
9708 [(set (reg FLAGS_REG)
9710 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9711 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9713 (set (match_operand:DI 0 "register_operand" "=r")
9714 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9716 && (optimize_function_for_size_p (cfun)
9717 || !TARGET_PARTIAL_FLAG_REG_STALL
9718 || (operands[2] == const1_rtx
9720 || TARGET_DOUBLE_WITH_ADD)))
9721 && ix86_match_ccmode (insn, CCGOCmode)
9722 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9724 switch (get_attr_type (insn))
9727 gcc_assert (operands[2] == const1_rtx);
9728 return "add{l}\t%k0, %k0";
9731 if (operands[2] == const1_rtx
9732 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9733 return "sal{l}\t%k0";
9735 return "sal{l}\t{%2, %k0|%k0, %2}";
9739 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9741 (match_operand 2 "const1_operand" ""))
9742 (const_string "alu")
9744 (const_string "ishift")))
9745 (set (attr "length_immediate")
9747 (ior (eq_attr "type" "alu")
9748 (and (eq_attr "type" "ishift")
9749 (and (match_operand 2 "const1_operand" "")
9750 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9753 (const_string "*")))
9754 (set_attr "mode" "SI")])
9756 (define_insn "*ashl<mode>3_cconly"
9757 [(set (reg FLAGS_REG)
9759 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9760 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9762 (clobber (match_scratch:SWI 0 "=<r>"))]
9763 "(optimize_function_for_size_p (cfun)
9764 || !TARGET_PARTIAL_FLAG_REG_STALL
9765 || (operands[2] == const1_rtx
9767 || TARGET_DOUBLE_WITH_ADD)))
9768 && ix86_match_ccmode (insn, CCGOCmode)"
9770 switch (get_attr_type (insn))
9773 gcc_assert (operands[2] == const1_rtx);
9774 return "add{<imodesuffix>}\t%0, %0";
9777 if (operands[2] == const1_rtx
9778 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9779 return "sal{<imodesuffix>}\t%0";
9781 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9785 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9787 (match_operand 0 "register_operand" ""))
9788 (match_operand 2 "const1_operand" ""))
9789 (const_string "alu")
9791 (const_string "ishift")))
9792 (set (attr "length_immediate")
9794 (ior (eq_attr "type" "alu")
9795 (and (eq_attr "type" "ishift")
9796 (and (match_operand 2 "const1_operand" "")
9797 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9800 (const_string "*")))
9801 (set_attr "mode" "<MODE>")])
9803 ;; See comment above `ashl<mode>3' about how this works.
9805 (define_expand "<shiftrt_insn><mode>3"
9806 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9807 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9808 (match_operand:QI 2 "nonmemory_operand" "")))]
9810 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9812 ;; Avoid useless masking of count operand.
9813 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9814 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9816 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9819 (match_operand:SI 2 "nonimmediate_operand" "c")
9820 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9821 (clobber (reg:CC FLAGS_REG))]
9822 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9823 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9824 == GET_MODE_BITSIZE (<MODE>mode)-1"
9827 [(parallel [(set (match_dup 0)
9828 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9829 (clobber (reg:CC FLAGS_REG))])]
9831 if (can_create_pseudo_p ())
9832 operands [2] = force_reg (SImode, operands[2]);
9834 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9836 [(set_attr "type" "ishift")
9837 (set_attr "mode" "<MODE>")])
9839 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9840 [(set (match_operand:DWI 0 "register_operand" "=r")
9841 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9842 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9843 (clobber (reg:CC FLAGS_REG))]
9846 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9848 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9849 [(set_attr "type" "multi")])
9851 ;; By default we don't ask for a scratch register, because when DWImode
9852 ;; values are manipulated, registers are already at a premium. But if
9853 ;; we have one handy, we won't turn it away.
9856 [(match_scratch:DWIH 3 "r")
9857 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9859 (match_operand:<DWI> 1 "register_operand" "")
9860 (match_operand:QI 2 "nonmemory_operand" "")))
9861 (clobber (reg:CC FLAGS_REG))])
9865 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9867 (define_insn "x86_64_shrd"
9868 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9869 (ior:DI (ashiftrt:DI (match_dup 0)
9870 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9871 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9872 (minus:QI (const_int 64) (match_dup 2)))))
9873 (clobber (reg:CC FLAGS_REG))]
9875 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9876 [(set_attr "type" "ishift")
9877 (set_attr "prefix_0f" "1")
9878 (set_attr "mode" "DI")
9879 (set_attr "athlon_decode" "vector")
9880 (set_attr "amdfam10_decode" "vector")
9881 (set_attr "bdver1_decode" "vector")])
9883 (define_insn "x86_shrd"
9884 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9885 (ior:SI (ashiftrt:SI (match_dup 0)
9886 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9887 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9888 (minus:QI (const_int 32) (match_dup 2)))))
9889 (clobber (reg:CC FLAGS_REG))]
9891 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9892 [(set_attr "type" "ishift")
9893 (set_attr "prefix_0f" "1")
9894 (set_attr "mode" "SI")
9895 (set_attr "pent_pair" "np")
9896 (set_attr "athlon_decode" "vector")
9897 (set_attr "amdfam10_decode" "vector")
9898 (set_attr "bdver1_decode" "vector")])
9900 (define_insn "ashrdi3_cvt"
9901 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9902 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9903 (match_operand:QI 2 "const_int_operand" "")))
9904 (clobber (reg:CC FLAGS_REG))]
9905 "TARGET_64BIT && INTVAL (operands[2]) == 63
9906 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9907 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9910 sar{q}\t{%2, %0|%0, %2}"
9911 [(set_attr "type" "imovx,ishift")
9912 (set_attr "prefix_0f" "0,*")
9913 (set_attr "length_immediate" "0,*")
9914 (set_attr "modrm" "0,1")
9915 (set_attr "mode" "DI")])
9917 (define_insn "ashrsi3_cvt"
9918 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9919 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9920 (match_operand:QI 2 "const_int_operand" "")))
9921 (clobber (reg:CC FLAGS_REG))]
9922 "INTVAL (operands[2]) == 31
9923 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9924 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9927 sar{l}\t{%2, %0|%0, %2}"
9928 [(set_attr "type" "imovx,ishift")
9929 (set_attr "prefix_0f" "0,*")
9930 (set_attr "length_immediate" "0,*")
9931 (set_attr "modrm" "0,1")
9932 (set_attr "mode" "SI")])
9934 (define_insn "*ashrsi3_cvt_zext"
9935 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9937 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9938 (match_operand:QI 2 "const_int_operand" ""))))
9939 (clobber (reg:CC FLAGS_REG))]
9940 "TARGET_64BIT && INTVAL (operands[2]) == 31
9941 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9942 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9945 sar{l}\t{%2, %k0|%k0, %2}"
9946 [(set_attr "type" "imovx,ishift")
9947 (set_attr "prefix_0f" "0,*")
9948 (set_attr "length_immediate" "0,*")
9949 (set_attr "modrm" "0,1")
9950 (set_attr "mode" "SI")])
9952 (define_expand "x86_shift<mode>_adj_3"
9953 [(use (match_operand:SWI48 0 "register_operand" ""))
9954 (use (match_operand:SWI48 1 "register_operand" ""))
9955 (use (match_operand:QI 2 "register_operand" ""))]
9958 rtx label = gen_label_rtx ();
9961 emit_insn (gen_testqi_ccz_1 (operands[2],
9962 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9964 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9965 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9966 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9967 gen_rtx_LABEL_REF (VOIDmode, label),
9969 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9970 JUMP_LABEL (tmp) = label;
9972 emit_move_insn (operands[0], operands[1]);
9973 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9974 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9976 LABEL_NUSES (label) = 1;
9981 (define_insn "*<shiftrt_insn><mode>3_1"
9982 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9983 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9984 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9985 (clobber (reg:CC FLAGS_REG))]
9986 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9988 if (operands[2] == const1_rtx
9989 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9990 return "<shiftrt>{<imodesuffix>}\t%0";
9992 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9994 [(set_attr "type" "ishift")
9995 (set (attr "length_immediate")
9997 (and (match_operand 2 "const1_operand" "")
9998 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10001 (const_string "*")))
10002 (set_attr "mode" "<MODE>")])
10004 (define_insn "*<shiftrt_insn>si3_1_zext"
10005 [(set (match_operand:DI 0 "register_operand" "=r")
10007 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10008 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10009 (clobber (reg:CC FLAGS_REG))]
10010 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10012 if (operands[2] == const1_rtx
10013 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10014 return "<shiftrt>{l}\t%k0";
10016 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10018 [(set_attr "type" "ishift")
10019 (set (attr "length_immediate")
10021 (and (match_operand 2 "const1_operand" "")
10022 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10025 (const_string "*")))
10026 (set_attr "mode" "SI")])
10028 (define_insn "*<shiftrt_insn>qi3_1_slp"
10029 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10030 (any_shiftrt:QI (match_dup 0)
10031 (match_operand:QI 1 "nonmemory_operand" "cI")))
10032 (clobber (reg:CC FLAGS_REG))]
10033 "(optimize_function_for_size_p (cfun)
10034 || !TARGET_PARTIAL_REG_STALL
10035 || (operands[1] == const1_rtx
10036 && TARGET_SHIFT1))"
10038 if (operands[1] == const1_rtx
10039 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10040 return "<shiftrt>{b}\t%0";
10042 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10044 [(set_attr "type" "ishift1")
10045 (set (attr "length_immediate")
10047 (and (match_operand 1 "const1_operand" "")
10048 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10051 (const_string "*")))
10052 (set_attr "mode" "QI")])
10054 ;; This pattern can't accept a variable shift count, since shifts by
10055 ;; zero don't affect the flags. We assume that shifts by constant
10056 ;; zero are optimized away.
10057 (define_insn "*<shiftrt_insn><mode>3_cmp"
10058 [(set (reg FLAGS_REG)
10061 (match_operand:SWI 1 "nonimmediate_operand" "0")
10062 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10064 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10065 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10066 "(optimize_function_for_size_p (cfun)
10067 || !TARGET_PARTIAL_FLAG_REG_STALL
10068 || (operands[2] == const1_rtx
10070 && ix86_match_ccmode (insn, CCGOCmode)
10071 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10073 if (operands[2] == const1_rtx
10074 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10075 return "<shiftrt>{<imodesuffix>}\t%0";
10077 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10079 [(set_attr "type" "ishift")
10080 (set (attr "length_immediate")
10082 (and (match_operand 2 "const1_operand" "")
10083 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10086 (const_string "*")))
10087 (set_attr "mode" "<MODE>")])
10089 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10090 [(set (reg FLAGS_REG)
10092 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10093 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10095 (set (match_operand:DI 0 "register_operand" "=r")
10096 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10098 && (optimize_function_for_size_p (cfun)
10099 || !TARGET_PARTIAL_FLAG_REG_STALL
10100 || (operands[2] == const1_rtx
10102 && ix86_match_ccmode (insn, CCGOCmode)
10103 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10105 if (operands[2] == const1_rtx
10106 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10107 return "<shiftrt>{l}\t%k0";
10109 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10111 [(set_attr "type" "ishift")
10112 (set (attr "length_immediate")
10114 (and (match_operand 2 "const1_operand" "")
10115 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10118 (const_string "*")))
10119 (set_attr "mode" "SI")])
10121 (define_insn "*<shiftrt_insn><mode>3_cconly"
10122 [(set (reg FLAGS_REG)
10125 (match_operand:SWI 1 "register_operand" "0")
10126 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10128 (clobber (match_scratch:SWI 0 "=<r>"))]
10129 "(optimize_function_for_size_p (cfun)
10130 || !TARGET_PARTIAL_FLAG_REG_STALL
10131 || (operands[2] == const1_rtx
10133 && ix86_match_ccmode (insn, CCGOCmode)"
10135 if (operands[2] == const1_rtx
10136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10137 return "<shiftrt>{<imodesuffix>}\t%0";
10139 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10141 [(set_attr "type" "ishift")
10142 (set (attr "length_immediate")
10144 (and (match_operand 2 "const1_operand" "")
10145 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10148 (const_string "*")))
10149 (set_attr "mode" "<MODE>")])
10151 ;; Rotate instructions
10153 (define_expand "<rotate_insn>ti3"
10154 [(set (match_operand:TI 0 "register_operand" "")
10155 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10156 (match_operand:QI 2 "nonmemory_operand" "")))]
10159 if (const_1_to_63_operand (operands[2], VOIDmode))
10160 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10161 (operands[0], operands[1], operands[2]));
10168 (define_expand "<rotate_insn>di3"
10169 [(set (match_operand:DI 0 "shiftdi_operand" "")
10170 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10171 (match_operand:QI 2 "nonmemory_operand" "")))]
10175 ix86_expand_binary_operator (<CODE>, DImode, operands);
10176 else if (const_1_to_31_operand (operands[2], VOIDmode))
10177 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10178 (operands[0], operands[1], operands[2]));
10185 (define_expand "<rotate_insn><mode>3"
10186 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10187 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10188 (match_operand:QI 2 "nonmemory_operand" "")))]
10190 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10192 ;; Avoid useless masking of count operand.
10193 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10194 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10196 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10199 (match_operand:SI 2 "nonimmediate_operand" "c")
10200 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10201 (clobber (reg:CC FLAGS_REG))]
10202 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10203 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10204 == GET_MODE_BITSIZE (<MODE>mode)-1"
10207 [(parallel [(set (match_dup 0)
10208 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10209 (clobber (reg:CC FLAGS_REG))])]
10211 if (can_create_pseudo_p ())
10212 operands [2] = force_reg (SImode, operands[2]);
10214 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10216 [(set_attr "type" "rotate")
10217 (set_attr "mode" "<MODE>")])
10219 ;; Implement rotation using two double-precision
10220 ;; shift instructions and a scratch register.
10222 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10223 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10224 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10225 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10226 (clobber (reg:CC FLAGS_REG))
10227 (clobber (match_scratch:DWIH 3 "=&r"))]
10231 [(set (match_dup 3) (match_dup 4))
10233 [(set (match_dup 4)
10234 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10235 (lshiftrt:DWIH (match_dup 5)
10236 (minus:QI (match_dup 6) (match_dup 2)))))
10237 (clobber (reg:CC FLAGS_REG))])
10239 [(set (match_dup 5)
10240 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10241 (lshiftrt:DWIH (match_dup 3)
10242 (minus:QI (match_dup 6) (match_dup 2)))))
10243 (clobber (reg:CC FLAGS_REG))])]
10245 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10247 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10250 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10251 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10252 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10253 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10254 (clobber (reg:CC FLAGS_REG))
10255 (clobber (match_scratch:DWIH 3 "=&r"))]
10259 [(set (match_dup 3) (match_dup 4))
10261 [(set (match_dup 4)
10262 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10263 (ashift:DWIH (match_dup 5)
10264 (minus:QI (match_dup 6) (match_dup 2)))))
10265 (clobber (reg:CC FLAGS_REG))])
10267 [(set (match_dup 5)
10268 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10269 (ashift:DWIH (match_dup 3)
10270 (minus:QI (match_dup 6) (match_dup 2)))))
10271 (clobber (reg:CC FLAGS_REG))])]
10273 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10275 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10278 (define_insn "*<rotate_insn><mode>3_1"
10279 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10280 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10281 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10282 (clobber (reg:CC FLAGS_REG))]
10283 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10285 if (operands[2] == const1_rtx
10286 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10287 return "<rotate>{<imodesuffix>}\t%0";
10289 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10291 [(set_attr "type" "rotate")
10292 (set (attr "length_immediate")
10294 (and (match_operand 2 "const1_operand" "")
10295 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10298 (const_string "*")))
10299 (set_attr "mode" "<MODE>")])
10301 (define_insn "*<rotate_insn>si3_1_zext"
10302 [(set (match_operand:DI 0 "register_operand" "=r")
10304 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10305 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10306 (clobber (reg:CC FLAGS_REG))]
10307 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10309 if (operands[2] == const1_rtx
10310 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10311 return "<rotate>{l}\t%k0";
10313 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10315 [(set_attr "type" "rotate")
10316 (set (attr "length_immediate")
10318 (and (match_operand 2 "const1_operand" "")
10319 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10322 (const_string "*")))
10323 (set_attr "mode" "SI")])
10325 (define_insn "*<rotate_insn>qi3_1_slp"
10326 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10327 (any_rotate:QI (match_dup 0)
10328 (match_operand:QI 1 "nonmemory_operand" "cI")))
10329 (clobber (reg:CC FLAGS_REG))]
10330 "(optimize_function_for_size_p (cfun)
10331 || !TARGET_PARTIAL_REG_STALL
10332 || (operands[1] == const1_rtx
10333 && TARGET_SHIFT1))"
10335 if (operands[1] == const1_rtx
10336 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10337 return "<rotate>{b}\t%0";
10339 return "<rotate>{b}\t{%1, %0|%0, %1}";
10341 [(set_attr "type" "rotate1")
10342 (set (attr "length_immediate")
10344 (and (match_operand 1 "const1_operand" "")
10345 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10348 (const_string "*")))
10349 (set_attr "mode" "QI")])
10352 [(set (match_operand:HI 0 "register_operand" "")
10353 (any_rotate:HI (match_dup 0) (const_int 8)))
10354 (clobber (reg:CC FLAGS_REG))]
10356 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10357 [(parallel [(set (strict_low_part (match_dup 0))
10358 (bswap:HI (match_dup 0)))
10359 (clobber (reg:CC FLAGS_REG))])])
10361 ;; Bit set / bit test instructions
10363 (define_expand "extv"
10364 [(set (match_operand:SI 0 "register_operand" "")
10365 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10366 (match_operand:SI 2 "const8_operand" "")
10367 (match_operand:SI 3 "const8_operand" "")))]
10370 /* Handle extractions from %ah et al. */
10371 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10374 /* From mips.md: extract_bit_field doesn't verify that our source
10375 matches the predicate, so check it again here. */
10376 if (! ext_register_operand (operands[1], VOIDmode))
10380 (define_expand "extzv"
10381 [(set (match_operand:SI 0 "register_operand" "")
10382 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10383 (match_operand:SI 2 "const8_operand" "")
10384 (match_operand:SI 3 "const8_operand" "")))]
10387 /* Handle extractions from %ah et al. */
10388 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10391 /* From mips.md: extract_bit_field doesn't verify that our source
10392 matches the predicate, so check it again here. */
10393 if (! ext_register_operand (operands[1], VOIDmode))
10397 (define_expand "insv"
10398 [(set (zero_extract (match_operand 0 "register_operand" "")
10399 (match_operand 1 "const_int_operand" "")
10400 (match_operand 2 "const_int_operand" ""))
10401 (match_operand 3 "register_operand" ""))]
10404 rtx (*gen_mov_insv_1) (rtx, rtx);
10406 if (ix86_expand_pinsr (operands))
10409 /* Handle insertions to %ah et al. */
10410 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10413 /* From mips.md: insert_bit_field doesn't verify that our source
10414 matches the predicate, so check it again here. */
10415 if (! ext_register_operand (operands[0], VOIDmode))
10418 gen_mov_insv_1 = (TARGET_64BIT
10419 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10421 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10425 ;; %%% bts, btr, btc, bt.
10426 ;; In general these instructions are *slow* when applied to memory,
10427 ;; since they enforce atomic operation. When applied to registers,
10428 ;; it depends on the cpu implementation. They're never faster than
10429 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10430 ;; no point. But in 64-bit, we can't hold the relevant immediates
10431 ;; within the instruction itself, so operating on bits in the high
10432 ;; 32-bits of a register becomes easier.
10434 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10435 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10436 ;; negdf respectively, so they can never be disabled entirely.
10438 (define_insn "*btsq"
10439 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10441 (match_operand:DI 1 "const_0_to_63_operand" ""))
10443 (clobber (reg:CC FLAGS_REG))]
10444 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10445 "bts{q}\t{%1, %0|%0, %1}"
10446 [(set_attr "type" "alu1")
10447 (set_attr "prefix_0f" "1")
10448 (set_attr "mode" "DI")])
10450 (define_insn "*btrq"
10451 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10453 (match_operand:DI 1 "const_0_to_63_operand" ""))
10455 (clobber (reg:CC FLAGS_REG))]
10456 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10457 "btr{q}\t{%1, %0|%0, %1}"
10458 [(set_attr "type" "alu1")
10459 (set_attr "prefix_0f" "1")
10460 (set_attr "mode" "DI")])
10462 (define_insn "*btcq"
10463 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10465 (match_operand:DI 1 "const_0_to_63_operand" ""))
10466 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10467 (clobber (reg:CC FLAGS_REG))]
10468 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10469 "btc{q}\t{%1, %0|%0, %1}"
10470 [(set_attr "type" "alu1")
10471 (set_attr "prefix_0f" "1")
10472 (set_attr "mode" "DI")])
10474 ;; Allow Nocona to avoid these instructions if a register is available.
10477 [(match_scratch:DI 2 "r")
10478 (parallel [(set (zero_extract:DI
10479 (match_operand:DI 0 "register_operand" "")
10481 (match_operand:DI 1 "const_0_to_63_operand" ""))
10483 (clobber (reg:CC FLAGS_REG))])]
10484 "TARGET_64BIT && !TARGET_USE_BT"
10487 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10490 if (HOST_BITS_PER_WIDE_INT >= 64)
10491 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10492 else if (i < HOST_BITS_PER_WIDE_INT)
10493 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10495 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10497 op1 = immed_double_const (lo, hi, DImode);
10500 emit_move_insn (operands[2], op1);
10504 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10509 [(match_scratch:DI 2 "r")
10510 (parallel [(set (zero_extract:DI
10511 (match_operand:DI 0 "register_operand" "")
10513 (match_operand:DI 1 "const_0_to_63_operand" ""))
10515 (clobber (reg:CC FLAGS_REG))])]
10516 "TARGET_64BIT && !TARGET_USE_BT"
10519 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10522 if (HOST_BITS_PER_WIDE_INT >= 64)
10523 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10524 else if (i < HOST_BITS_PER_WIDE_INT)
10525 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10527 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10529 op1 = immed_double_const (~lo, ~hi, DImode);
10532 emit_move_insn (operands[2], op1);
10536 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10541 [(match_scratch:DI 2 "r")
10542 (parallel [(set (zero_extract:DI
10543 (match_operand:DI 0 "register_operand" "")
10545 (match_operand:DI 1 "const_0_to_63_operand" ""))
10546 (not:DI (zero_extract:DI
10547 (match_dup 0) (const_int 1) (match_dup 1))))
10548 (clobber (reg:CC FLAGS_REG))])]
10549 "TARGET_64BIT && !TARGET_USE_BT"
10552 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10555 if (HOST_BITS_PER_WIDE_INT >= 64)
10556 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10557 else if (i < HOST_BITS_PER_WIDE_INT)
10558 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10560 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10562 op1 = immed_double_const (lo, hi, DImode);
10565 emit_move_insn (operands[2], op1);
10569 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10573 (define_insn "*bt<mode>"
10574 [(set (reg:CCC FLAGS_REG)
10576 (zero_extract:SWI48
10577 (match_operand:SWI48 0 "register_operand" "r")
10579 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10581 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10582 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10583 [(set_attr "type" "alu1")
10584 (set_attr "prefix_0f" "1")
10585 (set_attr "mode" "<MODE>")])
10587 ;; Store-flag instructions.
10589 ;; For all sCOND expanders, also expand the compare or test insn that
10590 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10592 (define_insn_and_split "*setcc_di_1"
10593 [(set (match_operand:DI 0 "register_operand" "=q")
10594 (match_operator:DI 1 "ix86_comparison_operator"
10595 [(reg FLAGS_REG) (const_int 0)]))]
10596 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10598 "&& reload_completed"
10599 [(set (match_dup 2) (match_dup 1))
10600 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10602 PUT_MODE (operands[1], QImode);
10603 operands[2] = gen_lowpart (QImode, operands[0]);
10606 (define_insn_and_split "*setcc_si_1_and"
10607 [(set (match_operand:SI 0 "register_operand" "=q")
10608 (match_operator:SI 1 "ix86_comparison_operator"
10609 [(reg FLAGS_REG) (const_int 0)]))
10610 (clobber (reg:CC FLAGS_REG))]
10611 "!TARGET_PARTIAL_REG_STALL
10612 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10614 "&& reload_completed"
10615 [(set (match_dup 2) (match_dup 1))
10616 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10617 (clobber (reg:CC FLAGS_REG))])]
10619 PUT_MODE (operands[1], QImode);
10620 operands[2] = gen_lowpart (QImode, operands[0]);
10623 (define_insn_and_split "*setcc_si_1_movzbl"
10624 [(set (match_operand:SI 0 "register_operand" "=q")
10625 (match_operator:SI 1 "ix86_comparison_operator"
10626 [(reg FLAGS_REG) (const_int 0)]))]
10627 "!TARGET_PARTIAL_REG_STALL
10628 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10630 "&& reload_completed"
10631 [(set (match_dup 2) (match_dup 1))
10632 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10634 PUT_MODE (operands[1], QImode);
10635 operands[2] = gen_lowpart (QImode, operands[0]);
10638 (define_insn "*setcc_qi"
10639 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10640 (match_operator:QI 1 "ix86_comparison_operator"
10641 [(reg FLAGS_REG) (const_int 0)]))]
10644 [(set_attr "type" "setcc")
10645 (set_attr "mode" "QI")])
10647 (define_insn "*setcc_qi_slp"
10648 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10649 (match_operator:QI 1 "ix86_comparison_operator"
10650 [(reg FLAGS_REG) (const_int 0)]))]
10653 [(set_attr "type" "setcc")
10654 (set_attr "mode" "QI")])
10656 ;; In general it is not safe to assume too much about CCmode registers,
10657 ;; so simplify-rtx stops when it sees a second one. Under certain
10658 ;; conditions this is safe on x86, so help combine not create
10665 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10666 (ne:QI (match_operator 1 "ix86_comparison_operator"
10667 [(reg FLAGS_REG) (const_int 0)])
10670 [(set (match_dup 0) (match_dup 1))]
10671 "PUT_MODE (operands[1], QImode);")
10674 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10675 (ne:QI (match_operator 1 "ix86_comparison_operator"
10676 [(reg FLAGS_REG) (const_int 0)])
10679 [(set (match_dup 0) (match_dup 1))]
10680 "PUT_MODE (operands[1], QImode);")
10683 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10684 (eq:QI (match_operator 1 "ix86_comparison_operator"
10685 [(reg FLAGS_REG) (const_int 0)])
10688 [(set (match_dup 0) (match_dup 1))]
10690 rtx new_op1 = copy_rtx (operands[1]);
10691 operands[1] = new_op1;
10692 PUT_MODE (new_op1, QImode);
10693 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10694 GET_MODE (XEXP (new_op1, 0))));
10696 /* Make sure that (a) the CCmode we have for the flags is strong
10697 enough for the reversed compare or (b) we have a valid FP compare. */
10698 if (! ix86_comparison_operator (new_op1, VOIDmode))
10703 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10704 (eq:QI (match_operator 1 "ix86_comparison_operator"
10705 [(reg FLAGS_REG) (const_int 0)])
10708 [(set (match_dup 0) (match_dup 1))]
10710 rtx new_op1 = copy_rtx (operands[1]);
10711 operands[1] = new_op1;
10712 PUT_MODE (new_op1, QImode);
10713 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10714 GET_MODE (XEXP (new_op1, 0))));
10716 /* Make sure that (a) the CCmode we have for the flags is strong
10717 enough for the reversed compare or (b) we have a valid FP compare. */
10718 if (! ix86_comparison_operator (new_op1, VOIDmode))
10722 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10723 ;; subsequent logical operations are used to imitate conditional moves.
10724 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10727 (define_insn "setcc_<mode>_sse"
10728 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10729 (match_operator:MODEF 3 "sse_comparison_operator"
10730 [(match_operand:MODEF 1 "register_operand" "0,x")
10731 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10732 "SSE_FLOAT_MODE_P (<MODE>mode)"
10734 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10735 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10736 [(set_attr "isa" "noavx,avx")
10737 (set_attr "type" "ssecmp")
10738 (set_attr "length_immediate" "1")
10739 (set_attr "prefix" "orig,vex")
10740 (set_attr "mode" "<MODE>")])
10742 ;; Basic conditional jump instructions.
10743 ;; We ignore the overflow flag for signed branch instructions.
10745 (define_insn "*jcc_1"
10747 (if_then_else (match_operator 1 "ix86_comparison_operator"
10748 [(reg FLAGS_REG) (const_int 0)])
10749 (label_ref (match_operand 0 "" ""))
10753 [(set_attr "type" "ibr")
10754 (set_attr "modrm" "0")
10755 (set (attr "length")
10756 (if_then_else (and (ge (minus (match_dup 0) (pc))
10758 (lt (minus (match_dup 0) (pc))
10763 (define_insn "*jcc_2"
10765 (if_then_else (match_operator 1 "ix86_comparison_operator"
10766 [(reg FLAGS_REG) (const_int 0)])
10768 (label_ref (match_operand 0 "" ""))))]
10771 [(set_attr "type" "ibr")
10772 (set_attr "modrm" "0")
10773 (set (attr "length")
10774 (if_then_else (and (ge (minus (match_dup 0) (pc))
10776 (lt (minus (match_dup 0) (pc))
10781 ;; In general it is not safe to assume too much about CCmode registers,
10782 ;; so simplify-rtx stops when it sees a second one. Under certain
10783 ;; conditions this is safe on x86, so help combine not create
10791 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10792 [(reg FLAGS_REG) (const_int 0)])
10794 (label_ref (match_operand 1 "" ""))
10798 (if_then_else (match_dup 0)
10799 (label_ref (match_dup 1))
10801 "PUT_MODE (operands[0], VOIDmode);")
10805 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10806 [(reg FLAGS_REG) (const_int 0)])
10808 (label_ref (match_operand 1 "" ""))
10812 (if_then_else (match_dup 0)
10813 (label_ref (match_dup 1))
10816 rtx new_op0 = copy_rtx (operands[0]);
10817 operands[0] = new_op0;
10818 PUT_MODE (new_op0, VOIDmode);
10819 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10820 GET_MODE (XEXP (new_op0, 0))));
10822 /* Make sure that (a) the CCmode we have for the flags is strong
10823 enough for the reversed compare or (b) we have a valid FP compare. */
10824 if (! ix86_comparison_operator (new_op0, VOIDmode))
10828 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10829 ;; pass generates from shift insn with QImode operand. Actually, the mode
10830 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10831 ;; appropriate modulo of the bit offset value.
10833 (define_insn_and_split "*jcc_bt<mode>"
10835 (if_then_else (match_operator 0 "bt_comparison_operator"
10836 [(zero_extract:SWI48
10837 (match_operand:SWI48 1 "register_operand" "r")
10840 (match_operand:QI 2 "register_operand" "r")))
10842 (label_ref (match_operand 3 "" ""))
10844 (clobber (reg:CC FLAGS_REG))]
10845 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10848 [(set (reg:CCC FLAGS_REG)
10850 (zero_extract:SWI48
10856 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10857 (label_ref (match_dup 3))
10860 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10862 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10865 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10866 ;; also for DImode, this is what combine produces.
10867 (define_insn_and_split "*jcc_bt<mode>_mask"
10869 (if_then_else (match_operator 0 "bt_comparison_operator"
10870 [(zero_extract:SWI48
10871 (match_operand:SWI48 1 "register_operand" "r")
10874 (match_operand:SI 2 "register_operand" "r")
10875 (match_operand:SI 3 "const_int_operand" "n")))])
10876 (label_ref (match_operand 4 "" ""))
10878 (clobber (reg:CC FLAGS_REG))]
10879 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10880 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10881 == GET_MODE_BITSIZE (<MODE>mode)-1"
10884 [(set (reg:CCC FLAGS_REG)
10886 (zero_extract:SWI48
10892 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10893 (label_ref (match_dup 4))
10896 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10898 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10901 (define_insn_and_split "*jcc_btsi_1"
10903 (if_then_else (match_operator 0 "bt_comparison_operator"
10906 (match_operand:SI 1 "register_operand" "r")
10907 (match_operand:QI 2 "register_operand" "r"))
10910 (label_ref (match_operand 3 "" ""))
10912 (clobber (reg:CC FLAGS_REG))]
10913 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10916 [(set (reg:CCC FLAGS_REG)
10924 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10925 (label_ref (match_dup 3))
10928 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10930 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10933 ;; avoid useless masking of bit offset operand
10934 (define_insn_and_split "*jcc_btsi_mask_1"
10937 (match_operator 0 "bt_comparison_operator"
10940 (match_operand:SI 1 "register_operand" "r")
10943 (match_operand:SI 2 "register_operand" "r")
10944 (match_operand:SI 3 "const_int_operand" "n")) 0))
10947 (label_ref (match_operand 4 "" ""))
10949 (clobber (reg:CC FLAGS_REG))]
10950 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10951 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10954 [(set (reg:CCC FLAGS_REG)
10962 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10963 (label_ref (match_dup 4))
10965 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10967 ;; Define combination compare-and-branch fp compare instructions to help
10970 (define_insn "*fp_jcc_1_387"
10972 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10973 [(match_operand 1 "register_operand" "f")
10974 (match_operand 2 "nonimmediate_operand" "fm")])
10975 (label_ref (match_operand 3 "" ""))
10977 (clobber (reg:CCFP FPSR_REG))
10978 (clobber (reg:CCFP FLAGS_REG))
10979 (clobber (match_scratch:HI 4 "=a"))]
10981 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10982 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10983 && SELECT_CC_MODE (GET_CODE (operands[0]),
10984 operands[1], operands[2]) == CCFPmode
10988 (define_insn "*fp_jcc_1r_387"
10990 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10991 [(match_operand 1 "register_operand" "f")
10992 (match_operand 2 "nonimmediate_operand" "fm")])
10994 (label_ref (match_operand 3 "" ""))))
10995 (clobber (reg:CCFP FPSR_REG))
10996 (clobber (reg:CCFP FLAGS_REG))
10997 (clobber (match_scratch:HI 4 "=a"))]
10999 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11000 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11001 && SELECT_CC_MODE (GET_CODE (operands[0]),
11002 operands[1], operands[2]) == CCFPmode
11006 (define_insn "*fp_jcc_2_387"
11008 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11009 [(match_operand 1 "register_operand" "f")
11010 (match_operand 2 "register_operand" "f")])
11011 (label_ref (match_operand 3 "" ""))
11013 (clobber (reg:CCFP FPSR_REG))
11014 (clobber (reg:CCFP FLAGS_REG))
11015 (clobber (match_scratch:HI 4 "=a"))]
11016 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11017 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11021 (define_insn "*fp_jcc_2r_387"
11023 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11024 [(match_operand 1 "register_operand" "f")
11025 (match_operand 2 "register_operand" "f")])
11027 (label_ref (match_operand 3 "" ""))))
11028 (clobber (reg:CCFP FPSR_REG))
11029 (clobber (reg:CCFP FLAGS_REG))
11030 (clobber (match_scratch:HI 4 "=a"))]
11031 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11032 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11036 (define_insn "*fp_jcc_3_387"
11038 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11039 [(match_operand 1 "register_operand" "f")
11040 (match_operand 2 "const0_operand" "")])
11041 (label_ref (match_operand 3 "" ""))
11043 (clobber (reg:CCFP FPSR_REG))
11044 (clobber (reg:CCFP FLAGS_REG))
11045 (clobber (match_scratch:HI 4 "=a"))]
11046 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11047 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11048 && SELECT_CC_MODE (GET_CODE (operands[0]),
11049 operands[1], operands[2]) == CCFPmode
11055 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11056 [(match_operand 1 "register_operand" "")
11057 (match_operand 2 "nonimmediate_operand" "")])
11058 (match_operand 3 "" "")
11059 (match_operand 4 "" "")))
11060 (clobber (reg:CCFP FPSR_REG))
11061 (clobber (reg:CCFP FLAGS_REG))]
11065 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11066 operands[3], operands[4], NULL_RTX, NULL_RTX);
11072 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11073 [(match_operand 1 "register_operand" "")
11074 (match_operand 2 "general_operand" "")])
11075 (match_operand 3 "" "")
11076 (match_operand 4 "" "")))
11077 (clobber (reg:CCFP FPSR_REG))
11078 (clobber (reg:CCFP FLAGS_REG))
11079 (clobber (match_scratch:HI 5 "=a"))]
11083 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11084 operands[3], operands[4], operands[5], NULL_RTX);
11088 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11089 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11090 ;; with a precedence over other operators and is always put in the first
11091 ;; place. Swap condition and operands to match ficom instruction.
11093 (define_insn "*fp_jcc_4_<mode>_387"
11096 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11097 [(match_operator 1 "float_operator"
11098 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11099 (match_operand 3 "register_operand" "f,f")])
11100 (label_ref (match_operand 4 "" ""))
11102 (clobber (reg:CCFP FPSR_REG))
11103 (clobber (reg:CCFP FLAGS_REG))
11104 (clobber (match_scratch:HI 5 "=a,a"))]
11105 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11106 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11107 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11108 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11115 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11116 [(match_operator 1 "float_operator"
11117 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11118 (match_operand 3 "register_operand" "")])
11119 (match_operand 4 "" "")
11120 (match_operand 5 "" "")))
11121 (clobber (reg:CCFP FPSR_REG))
11122 (clobber (reg:CCFP FLAGS_REG))
11123 (clobber (match_scratch:HI 6 "=a"))]
11127 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11129 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11130 operands[3], operands[7],
11131 operands[4], operands[5], operands[6], NULL_RTX);
11135 ;; %%% Kill this when reload knows how to do it.
11139 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11140 [(match_operator 1 "float_operator"
11141 [(match_operand:X87MODEI12 2 "register_operand" "")])
11142 (match_operand 3 "register_operand" "")])
11143 (match_operand 4 "" "")
11144 (match_operand 5 "" "")))
11145 (clobber (reg:CCFP FPSR_REG))
11146 (clobber (reg:CCFP FLAGS_REG))
11147 (clobber (match_scratch:HI 6 "=a"))]
11151 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11152 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11154 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11155 operands[3], operands[7],
11156 operands[4], operands[5], operands[6], operands[2]);
11160 ;; Unconditional and other jump instructions
11162 (define_insn "jump"
11164 (label_ref (match_operand 0 "" "")))]
11167 [(set_attr "type" "ibr")
11168 (set (attr "length")
11169 (if_then_else (and (ge (minus (match_dup 0) (pc))
11171 (lt (minus (match_dup 0) (pc))
11175 (set_attr "modrm" "0")])
11177 (define_expand "indirect_jump"
11178 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11182 (define_insn "*indirect_jump"
11183 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11186 [(set_attr "type" "ibr")
11187 (set_attr "length_immediate" "0")])
11189 (define_expand "tablejump"
11190 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11191 (use (label_ref (match_operand 1 "" "")))])]
11194 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11195 relative. Convert the relative address to an absolute address. */
11199 enum rtx_code code;
11201 /* We can't use @GOTOFF for text labels on VxWorks;
11202 see gotoff_operand. */
11203 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11207 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11209 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11213 op1 = pic_offset_table_rtx;
11218 op0 = pic_offset_table_rtx;
11222 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11227 (define_insn "*tablejump_1"
11228 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11229 (use (label_ref (match_operand 1 "" "")))]
11232 [(set_attr "type" "ibr")
11233 (set_attr "length_immediate" "0")])
11235 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11238 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11239 (set (match_operand:QI 1 "register_operand" "")
11240 (match_operator:QI 2 "ix86_comparison_operator"
11241 [(reg FLAGS_REG) (const_int 0)]))
11242 (set (match_operand 3 "q_regs_operand" "")
11243 (zero_extend (match_dup 1)))]
11244 "(peep2_reg_dead_p (3, operands[1])
11245 || operands_match_p (operands[1], operands[3]))
11246 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11247 [(set (match_dup 4) (match_dup 0))
11248 (set (strict_low_part (match_dup 5))
11251 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11252 operands[5] = gen_lowpart (QImode, operands[3]);
11253 ix86_expand_clear (operands[3]);
11256 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11259 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11260 (set (match_operand:QI 1 "register_operand" "")
11261 (match_operator:QI 2 "ix86_comparison_operator"
11262 [(reg FLAGS_REG) (const_int 0)]))
11263 (parallel [(set (match_operand 3 "q_regs_operand" "")
11264 (zero_extend (match_dup 1)))
11265 (clobber (reg:CC FLAGS_REG))])]
11266 "(peep2_reg_dead_p (3, operands[1])
11267 || operands_match_p (operands[1], operands[3]))
11268 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11269 [(set (match_dup 4) (match_dup 0))
11270 (set (strict_low_part (match_dup 5))
11273 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11274 operands[5] = gen_lowpart (QImode, operands[3]);
11275 ix86_expand_clear (operands[3]);
11278 ;; Call instructions.
11280 ;; The predicates normally associated with named expanders are not properly
11281 ;; checked for calls. This is a bug in the generic code, but it isn't that
11282 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11284 ;; P6 processors will jump to the address after the decrement when %esp
11285 ;; is used as a call operand, so they will execute return address as a code.
11286 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11288 ;; Call subroutine returning no value.
11290 (define_expand "call_pop"
11291 [(parallel [(call (match_operand:QI 0 "" "")
11292 (match_operand:SI 1 "" ""))
11293 (set (reg:SI SP_REG)
11294 (plus:SI (reg:SI SP_REG)
11295 (match_operand:SI 3 "" "")))])]
11298 ix86_expand_call (NULL, operands[0], operands[1],
11299 operands[2], operands[3], 0);
11303 (define_insn_and_split "*call_pop_0_vzeroupper"
11305 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11306 (match_operand:SI 1 "" ""))
11307 (set (reg:SI SP_REG)
11308 (plus:SI (reg:SI SP_REG)
11309 (match_operand:SI 2 "immediate_operand" "")))])
11310 (unspec [(match_operand 3 "const_int_operand" "")]
11311 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11312 "TARGET_VZEROUPPER && !TARGET_64BIT"
11314 "&& reload_completed"
11316 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11317 [(set_attr "type" "call")])
11319 (define_insn "*call_pop_0"
11320 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11321 (match_operand:SI 1 "" ""))
11322 (set (reg:SI SP_REG)
11323 (plus:SI (reg:SI SP_REG)
11324 (match_operand:SI 2 "immediate_operand" "")))]
11327 if (SIBLING_CALL_P (insn))
11330 return "call\t%P0";
11332 [(set_attr "type" "call")])
11334 (define_insn_and_split "*call_pop_1_vzeroupper"
11336 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11337 (match_operand:SI 1 "" ""))
11338 (set (reg:SI SP_REG)
11339 (plus:SI (reg:SI SP_REG)
11340 (match_operand:SI 2 "immediate_operand" "i")))])
11341 (unspec [(match_operand 3 "const_int_operand" "")]
11342 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11343 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11345 "&& reload_completed"
11347 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11348 [(set_attr "type" "call")])
11350 (define_insn "*call_pop_1"
11351 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11352 (match_operand:SI 1 "" ""))
11353 (set (reg:SI SP_REG)
11354 (plus:SI (reg:SI SP_REG)
11355 (match_operand:SI 2 "immediate_operand" "i")))]
11356 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11358 if (constant_call_address_operand (operands[0], Pmode))
11359 return "call\t%P0";
11360 return "call\t%A0";
11362 [(set_attr "type" "call")])
11364 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11366 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11367 (match_operand:SI 1 "" ""))
11368 (set (reg:SI SP_REG)
11369 (plus:SI (reg:SI SP_REG)
11370 (match_operand:SI 2 "immediate_operand" "i,i")))])
11371 (unspec [(match_operand 3 "const_int_operand" "")]
11372 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11373 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11375 "&& reload_completed"
11377 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11378 [(set_attr "type" "call")])
11380 (define_insn "*sibcall_pop_1"
11381 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11382 (match_operand:SI 1 "" ""))
11383 (set (reg:SI SP_REG)
11384 (plus:SI (reg:SI SP_REG)
11385 (match_operand:SI 2 "immediate_operand" "i,i")))]
11386 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11390 [(set_attr "type" "call")])
11392 (define_expand "call"
11393 [(call (match_operand:QI 0 "" "")
11394 (match_operand 1 "" ""))
11395 (use (match_operand 2 "" ""))]
11398 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11402 (define_expand "sibcall"
11403 [(call (match_operand:QI 0 "" "")
11404 (match_operand 1 "" ""))
11405 (use (match_operand 2 "" ""))]
11408 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11412 (define_insn_and_split "*call_0_vzeroupper"
11413 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11414 (match_operand 1 "" ""))
11415 (unspec [(match_operand 2 "const_int_operand" "")]
11416 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11417 "TARGET_VZEROUPPER"
11419 "&& reload_completed"
11421 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11422 [(set_attr "type" "call")])
11424 (define_insn "*call_0"
11425 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11426 (match_operand 1 "" ""))]
11428 { return ix86_output_call_insn (insn, operands[0], 0); }
11429 [(set_attr "type" "call")])
11431 (define_insn_and_split "*call_1_vzeroupper"
11432 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11433 (match_operand 1 "" ""))
11434 (unspec [(match_operand 2 "const_int_operand" "")]
11435 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11436 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11438 "&& reload_completed"
11440 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11441 [(set_attr "type" "call")])
11443 (define_insn "*call_1"
11444 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11445 (match_operand 1 "" ""))]
11446 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11447 { return ix86_output_call_insn (insn, operands[0], 0); }
11448 [(set_attr "type" "call")])
11450 (define_insn_and_split "*sibcall_1_vzeroupper"
11451 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11452 (match_operand 1 "" ""))
11453 (unspec [(match_operand 2 "const_int_operand" "")]
11454 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11455 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11457 "&& reload_completed"
11459 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11460 [(set_attr "type" "call")])
11462 (define_insn "*sibcall_1"
11463 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11464 (match_operand 1 "" ""))]
11465 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11466 { return ix86_output_call_insn (insn, operands[0], 0); }
11467 [(set_attr "type" "call")])
11469 (define_insn_and_split "*call_1_rex64_vzeroupper"
11470 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11471 (match_operand 1 "" ""))
11472 (unspec [(match_operand 2 "const_int_operand" "")]
11473 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11474 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11475 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11477 "&& reload_completed"
11479 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11480 [(set_attr "type" "call")])
11482 (define_insn "*call_1_rex64"
11483 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11484 (match_operand 1 "" ""))]
11485 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11486 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11487 { return ix86_output_call_insn (insn, operands[0], 0); }
11488 [(set_attr "type" "call")])
11490 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11492 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11493 (match_operand 1 "" ""))
11494 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11495 (clobber (reg:TI XMM6_REG))
11496 (clobber (reg:TI XMM7_REG))
11497 (clobber (reg:TI XMM8_REG))
11498 (clobber (reg:TI XMM9_REG))
11499 (clobber (reg:TI XMM10_REG))
11500 (clobber (reg:TI XMM11_REG))
11501 (clobber (reg:TI XMM12_REG))
11502 (clobber (reg:TI XMM13_REG))
11503 (clobber (reg:TI XMM14_REG))
11504 (clobber (reg:TI XMM15_REG))
11505 (clobber (reg:DI SI_REG))
11506 (clobber (reg:DI DI_REG))])
11507 (unspec [(match_operand 2 "const_int_operand" "")]
11508 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11509 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11511 "&& reload_completed"
11513 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11514 [(set_attr "type" "call")])
11516 (define_insn "*call_1_rex64_ms_sysv"
11517 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11518 (match_operand 1 "" ""))
11519 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11520 (clobber (reg:TI XMM6_REG))
11521 (clobber (reg:TI XMM7_REG))
11522 (clobber (reg:TI XMM8_REG))
11523 (clobber (reg:TI XMM9_REG))
11524 (clobber (reg:TI XMM10_REG))
11525 (clobber (reg:TI XMM11_REG))
11526 (clobber (reg:TI XMM12_REG))
11527 (clobber (reg:TI XMM13_REG))
11528 (clobber (reg:TI XMM14_REG))
11529 (clobber (reg:TI XMM15_REG))
11530 (clobber (reg:DI SI_REG))
11531 (clobber (reg:DI DI_REG))]
11532 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11533 { return ix86_output_call_insn (insn, operands[0], 0); }
11534 [(set_attr "type" "call")])
11536 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11537 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11538 (match_operand 1 "" ""))
11539 (unspec [(match_operand 2 "const_int_operand" "")]
11540 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11541 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11543 "&& reload_completed"
11545 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11546 [(set_attr "type" "call")])
11548 (define_insn "*call_1_rex64_large"
11549 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11550 (match_operand 1 "" ""))]
11551 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11552 { return ix86_output_call_insn (insn, operands[0], 0); }
11553 [(set_attr "type" "call")])
11555 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11556 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11557 (match_operand 1 "" ""))
11558 (unspec [(match_operand 2 "const_int_operand" "")]
11559 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11560 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11562 "&& reload_completed"
11564 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11565 [(set_attr "type" "call")])
11567 (define_insn "*sibcall_1_rex64"
11568 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11569 (match_operand 1 "" ""))]
11570 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11571 { return ix86_output_call_insn (insn, operands[0], 0); }
11572 [(set_attr "type" "call")])
11574 ;; Call subroutine, returning value in operand 0
11575 (define_expand "call_value_pop"
11576 [(parallel [(set (match_operand 0 "" "")
11577 (call (match_operand:QI 1 "" "")
11578 (match_operand:SI 2 "" "")))
11579 (set (reg:SI SP_REG)
11580 (plus:SI (reg:SI SP_REG)
11581 (match_operand:SI 4 "" "")))])]
11584 ix86_expand_call (operands[0], operands[1], operands[2],
11585 operands[3], operands[4], 0);
11589 (define_expand "call_value"
11590 [(set (match_operand 0 "" "")
11591 (call (match_operand:QI 1 "" "")
11592 (match_operand:SI 2 "" "")))
11593 (use (match_operand:SI 3 "" ""))]
11594 ;; Operand 3 is not used on the i386.
11597 ix86_expand_call (operands[0], operands[1], operands[2],
11598 operands[3], NULL, 0);
11602 (define_expand "sibcall_value"
11603 [(set (match_operand 0 "" "")
11604 (call (match_operand:QI 1 "" "")
11605 (match_operand:SI 2 "" "")))
11606 (use (match_operand:SI 3 "" ""))]
11607 ;; Operand 3 is not used on the i386.
11610 ix86_expand_call (operands[0], operands[1], operands[2],
11611 operands[3], NULL, 1);
11615 ;; Call subroutine returning any type.
11617 (define_expand "untyped_call"
11618 [(parallel [(call (match_operand 0 "" "")
11620 (match_operand 1 "" "")
11621 (match_operand 2 "" "")])]
11626 /* In order to give reg-stack an easier job in validating two
11627 coprocessor registers as containing a possible return value,
11628 simply pretend the untyped call returns a complex long double
11631 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11632 and should have the default ABI. */
11634 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11635 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11636 operands[0], const0_rtx,
11637 GEN_INT ((TARGET_64BIT
11638 ? (ix86_abi == SYSV_ABI
11639 ? X86_64_SSE_REGPARM_MAX
11640 : X86_64_MS_SSE_REGPARM_MAX)
11641 : X86_32_SSE_REGPARM_MAX)
11645 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11647 rtx set = XVECEXP (operands[2], 0, i);
11648 emit_move_insn (SET_DEST (set), SET_SRC (set));
11651 /* The optimizer does not know that the call sets the function value
11652 registers we stored in the result block. We avoid problems by
11653 claiming that all hard registers are used and clobbered at this
11655 emit_insn (gen_blockage ());
11660 ;; Prologue and epilogue instructions
11662 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11663 ;; all of memory. This blocks insns from being moved across this point.
11665 (define_insn "blockage"
11666 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11669 [(set_attr "length" "0")])
11671 ;; Do not schedule instructions accessing memory across this point.
11673 (define_expand "memory_blockage"
11674 [(set (match_dup 0)
11675 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11678 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11679 MEM_VOLATILE_P (operands[0]) = 1;
11682 (define_insn "*memory_blockage"
11683 [(set (match_operand:BLK 0 "" "")
11684 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11687 [(set_attr "length" "0")])
11689 ;; As USE insns aren't meaningful after reload, this is used instead
11690 ;; to prevent deleting instructions setting registers for PIC code
11691 (define_insn "prologue_use"
11692 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11695 [(set_attr "length" "0")])
11697 ;; Insn emitted into the body of a function to return from a function.
11698 ;; This is only done if the function's epilogue is known to be simple.
11699 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11701 (define_expand "return"
11703 "ix86_can_use_return_insn_p ()"
11705 if (crtl->args.pops_args)
11707 rtx popc = GEN_INT (crtl->args.pops_args);
11708 emit_jump_insn (gen_return_pop_internal (popc));
11713 (define_insn "return_internal"
11717 [(set_attr "length" "1")
11718 (set_attr "atom_unit" "jeu")
11719 (set_attr "length_immediate" "0")
11720 (set_attr "modrm" "0")])
11722 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11723 ;; instruction Athlon and K8 have.
11725 (define_insn "return_internal_long"
11727 (unspec [(const_int 0)] UNSPEC_REP)]
11730 [(set_attr "length" "2")
11731 (set_attr "atom_unit" "jeu")
11732 (set_attr "length_immediate" "0")
11733 (set_attr "prefix_rep" "1")
11734 (set_attr "modrm" "0")])
11736 (define_insn "return_pop_internal"
11738 (use (match_operand:SI 0 "const_int_operand" ""))]
11741 [(set_attr "length" "3")
11742 (set_attr "atom_unit" "jeu")
11743 (set_attr "length_immediate" "2")
11744 (set_attr "modrm" "0")])
11746 (define_insn "return_indirect_internal"
11748 (use (match_operand:SI 0 "register_operand" "r"))]
11751 [(set_attr "type" "ibr")
11752 (set_attr "length_immediate" "0")])
11758 [(set_attr "length" "1")
11759 (set_attr "length_immediate" "0")
11760 (set_attr "modrm" "0")])
11762 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11763 (define_insn "nops"
11764 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11768 int num = INTVAL (operands[0]);
11770 gcc_assert (num >= 1 && num <= 8);
11773 fputs ("\tnop\n", asm_out_file);
11777 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11778 (set_attr "length_immediate" "0")
11779 (set_attr "modrm" "0")])
11781 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11782 ;; branch prediction penalty for the third jump in a 16-byte
11786 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11789 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11790 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11792 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11793 The align insn is used to avoid 3 jump instructions in the row to improve
11794 branch prediction and the benefits hardly outweigh the cost of extra 8
11795 nops on the average inserted by full alignment pseudo operation. */
11799 [(set_attr "length" "16")])
11801 (define_expand "prologue"
11804 "ix86_expand_prologue (); DONE;")
11806 (define_insn "set_got"
11807 [(set (match_operand:SI 0 "register_operand" "=r")
11808 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11809 (clobber (reg:CC FLAGS_REG))]
11811 "* return output_set_got (operands[0], NULL_RTX);"
11812 [(set_attr "type" "multi")
11813 (set_attr "length" "12")])
11815 (define_insn "set_got_labelled"
11816 [(set (match_operand:SI 0 "register_operand" "=r")
11817 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11819 (clobber (reg:CC FLAGS_REG))]
11821 "* return output_set_got (operands[0], operands[1]);"
11822 [(set_attr "type" "multi")
11823 (set_attr "length" "12")])
11825 (define_insn "set_got_rex64"
11826 [(set (match_operand:DI 0 "register_operand" "=r")
11827 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11829 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11830 [(set_attr "type" "lea")
11831 (set_attr "length_address" "4")
11832 (set_attr "mode" "DI")])
11834 (define_insn "set_rip_rex64"
11835 [(set (match_operand:DI 0 "register_operand" "=r")
11836 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11838 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11839 [(set_attr "type" "lea")
11840 (set_attr "length_address" "4")
11841 (set_attr "mode" "DI")])
11843 (define_insn "set_got_offset_rex64"
11844 [(set (match_operand:DI 0 "register_operand" "=r")
11846 [(label_ref (match_operand 1 "" ""))]
11847 UNSPEC_SET_GOT_OFFSET))]
11849 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11850 [(set_attr "type" "imov")
11851 (set_attr "length_immediate" "0")
11852 (set_attr "length_address" "8")
11853 (set_attr "mode" "DI")])
11855 (define_expand "epilogue"
11858 "ix86_expand_epilogue (1); DONE;")
11860 (define_expand "sibcall_epilogue"
11863 "ix86_expand_epilogue (0); DONE;")
11865 (define_expand "eh_return"
11866 [(use (match_operand 0 "register_operand" ""))]
11869 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11871 /* Tricky bit: we write the address of the handler to which we will
11872 be returning into someone else's stack frame, one word below the
11873 stack address we wish to restore. */
11874 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11875 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11876 tmp = gen_rtx_MEM (Pmode, tmp);
11877 emit_move_insn (tmp, ra);
11879 emit_jump_insn (gen_eh_return_internal ());
11884 (define_insn_and_split "eh_return_internal"
11888 "epilogue_completed"
11890 "ix86_expand_epilogue (2); DONE;")
11892 (define_insn "leave"
11893 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11894 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11895 (clobber (mem:BLK (scratch)))]
11898 [(set_attr "type" "leave")])
11900 (define_insn "leave_rex64"
11901 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11902 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11903 (clobber (mem:BLK (scratch)))]
11906 [(set_attr "type" "leave")])
11908 ;; Handle -fsplit-stack.
11910 (define_expand "split_stack_prologue"
11914 ix86_expand_split_stack_prologue ();
11918 ;; In order to support the call/return predictor, we use a return
11919 ;; instruction which the middle-end doesn't see.
11920 (define_insn "split_stack_return"
11921 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11922 UNSPECV_SPLIT_STACK_RETURN)]
11925 if (operands[0] == const0_rtx)
11930 [(set_attr "atom_unit" "jeu")
11931 (set_attr "modrm" "0")
11932 (set (attr "length")
11933 (if_then_else (match_operand:SI 0 "const0_operand" "")
11936 (set (attr "length_immediate")
11937 (if_then_else (match_operand:SI 0 "const0_operand" "")
11941 ;; If there are operand 0 bytes available on the stack, jump to
11944 (define_expand "split_stack_space_check"
11945 [(set (pc) (if_then_else
11946 (ltu (minus (reg SP_REG)
11947 (match_operand 0 "register_operand" ""))
11948 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11949 (label_ref (match_operand 1 "" ""))
11953 rtx reg, size, limit;
11955 reg = gen_reg_rtx (Pmode);
11956 size = force_reg (Pmode, operands[0]);
11957 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11958 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11959 UNSPEC_STACK_CHECK);
11960 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11961 ix86_expand_branch (GEU, reg, limit, operands[1]);
11966 ;; Bit manipulation instructions.
11968 (define_expand "ffs<mode>2"
11969 [(set (match_dup 2) (const_int -1))
11970 (parallel [(set (reg:CCZ FLAGS_REG)
11972 (match_operand:SWI48 1 "nonimmediate_operand" "")
11974 (set (match_operand:SWI48 0 "register_operand" "")
11975 (ctz:SWI48 (match_dup 1)))])
11976 (set (match_dup 0) (if_then_else:SWI48
11977 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11980 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11981 (clobber (reg:CC FLAGS_REG))])]
11984 if (<MODE>mode == SImode && !TARGET_CMOVE)
11986 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11989 operands[2] = gen_reg_rtx (<MODE>mode);
11992 (define_insn_and_split "ffssi2_no_cmove"
11993 [(set (match_operand:SI 0 "register_operand" "=r")
11994 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11995 (clobber (match_scratch:SI 2 "=&q"))
11996 (clobber (reg:CC FLAGS_REG))]
11999 "&& reload_completed"
12000 [(parallel [(set (reg:CCZ FLAGS_REG)
12001 (compare:CCZ (match_dup 1) (const_int 0)))
12002 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12003 (set (strict_low_part (match_dup 3))
12004 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12005 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12006 (clobber (reg:CC FLAGS_REG))])
12007 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12008 (clobber (reg:CC FLAGS_REG))])
12009 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12010 (clobber (reg:CC FLAGS_REG))])]
12012 operands[3] = gen_lowpart (QImode, operands[2]);
12013 ix86_expand_clear (operands[2]);
12016 (define_insn "*ffs<mode>_1"
12017 [(set (reg:CCZ FLAGS_REG)
12018 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12020 (set (match_operand:SWI48 0 "register_operand" "=r")
12021 (ctz:SWI48 (match_dup 1)))]
12023 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12024 [(set_attr "type" "alu1")
12025 (set_attr "prefix_0f" "1")
12026 (set_attr "mode" "<MODE>")])
12028 (define_insn "ctz<mode>2"
12029 [(set (match_operand:SWI248 0 "register_operand" "=r")
12030 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12031 (clobber (reg:CC FLAGS_REG))]
12035 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12037 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12039 [(set_attr "type" "alu1")
12040 (set_attr "prefix_0f" "1")
12041 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12042 (set_attr "mode" "<MODE>")])
12044 (define_expand "clz<mode>2"
12046 [(set (match_operand:SWI248 0 "register_operand" "")
12049 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12050 (clobber (reg:CC FLAGS_REG))])
12052 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12053 (clobber (reg:CC FLAGS_REG))])]
12058 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12061 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12064 (define_insn "clz<mode>2_abm"
12065 [(set (match_operand:SWI248 0 "register_operand" "=r")
12066 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12067 (clobber (reg:CC FLAGS_REG))]
12068 "TARGET_ABM || TARGET_BMI"
12069 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12070 [(set_attr "prefix_rep" "1")
12071 (set_attr "type" "bitmanip")
12072 (set_attr "mode" "<MODE>")])
12074 ;; BMI instructions.
12075 (define_insn "*bmi_andn_<mode>"
12076 [(set (match_operand:SWI48 0 "register_operand" "=r")
12079 (match_operand:SWI48 1 "register_operand" "r"))
12080 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12081 (clobber (reg:CC FLAGS_REG))]
12083 "andn\t{%2, %1, %0|%0, %1, %2}"
12084 [(set_attr "type" "bitmanip")
12085 (set_attr "mode" "<MODE>")])
12087 (define_insn "bmi_bextr_<mode>"
12088 [(set (match_operand:SWI48 0 "register_operand" "=r")
12089 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12090 (match_operand:SWI48 2 "register_operand" "r")]
12092 (clobber (reg:CC FLAGS_REG))]
12094 "bextr\t{%2, %1, %0|%0, %1, %2}"
12095 [(set_attr "type" "bitmanip")
12096 (set_attr "mode" "<MODE>")])
12098 (define_insn "*bmi_blsi_<mode>"
12099 [(set (match_operand:SWI48 0 "register_operand" "=r")
12102 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12104 (clobber (reg:CC FLAGS_REG))]
12106 "blsi\t{%1, %0|%0, %1}"
12107 [(set_attr "type" "bitmanip")
12108 (set_attr "mode" "<MODE>")])
12110 (define_insn "*bmi_blsmsk_<mode>"
12111 [(set (match_operand:SWI48 0 "register_operand" "=r")
12114 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12117 (clobber (reg:CC FLAGS_REG))]
12119 "blsmsk\t{%1, %0|%0, %1}"
12120 [(set_attr "type" "bitmanip")
12121 (set_attr "mode" "<MODE>")])
12123 (define_insn "*bmi_blsr_<mode>"
12124 [(set (match_operand:SWI48 0 "register_operand" "=r")
12127 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12130 (clobber (reg:CC FLAGS_REG))]
12132 "blsr\t{%1, %0|%0, %1}"
12133 [(set_attr "type" "bitmanip")
12134 (set_attr "mode" "<MODE>")])
12136 ;; TBM instructions.
12137 (define_insn "tbm_bextri_<mode>"
12138 [(set (match_operand:SWI48 0 "register_operand" "=r")
12139 (zero_extract:SWI48
12140 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12141 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12142 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12143 (clobber (reg:CC FLAGS_REG))]
12146 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12147 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12149 [(set_attr "type" "bitmanip")
12150 (set_attr "mode" "<MODE>")])
12152 (define_insn "*tbm_blcfill_<mode>"
12153 [(set (match_operand:SWI48 0 "register_operand" "=r")
12156 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12159 (clobber (reg:CC FLAGS_REG))]
12161 "blcfill\t{%1, %0|%0, %1}"
12162 [(set_attr "type" "bitmanip")
12163 (set_attr "mode" "<MODE>")])
12165 (define_insn "*tbm_blci_<mode>"
12166 [(set (match_operand:SWI48 0 "register_operand" "=r")
12170 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12173 (clobber (reg:CC FLAGS_REG))]
12175 "blci\t{%1, %0|%0, %1}"
12176 [(set_attr "type" "bitmanip")
12177 (set_attr "mode" "<MODE>")])
12179 (define_insn "*tbm_blcic_<mode>"
12180 [(set (match_operand:SWI48 0 "register_operand" "=r")
12183 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12187 (clobber (reg:CC FLAGS_REG))]
12189 "blcic\t{%1, %0|%0, %1}"
12190 [(set_attr "type" "bitmanip")
12191 (set_attr "mode" "<MODE>")])
12193 (define_insn "*tbm_blcmsk_<mode>"
12194 [(set (match_operand:SWI48 0 "register_operand" "=r")
12197 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12200 (clobber (reg:CC FLAGS_REG))]
12202 "blcmsk\t{%1, %0|%0, %1}"
12203 [(set_attr "type" "bitmanip")
12204 (set_attr "mode" "<MODE>")])
12206 (define_insn "*tbm_blcs_<mode>"
12207 [(set (match_operand:SWI48 0 "register_operand" "=r")
12210 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12213 (clobber (reg:CC FLAGS_REG))]
12215 "blcs\t{%1, %0|%0, %1}"
12216 [(set_attr "type" "bitmanip")
12217 (set_attr "mode" "<MODE>")])
12219 (define_insn "*tbm_blsfill_<mode>"
12220 [(set (match_operand:SWI48 0 "register_operand" "=r")
12223 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12226 (clobber (reg:CC FLAGS_REG))]
12228 "blsfill\t{%1, %0|%0, %1}"
12229 [(set_attr "type" "bitmanip")
12230 (set_attr "mode" "<MODE>")])
12232 (define_insn "*tbm_blsic_<mode>"
12233 [(set (match_operand:SWI48 0 "register_operand" "=r")
12236 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12240 (clobber (reg:CC FLAGS_REG))]
12242 "blsic\t{%1, %0|%0, %1}"
12243 [(set_attr "type" "bitmanip")
12244 (set_attr "mode" "<MODE>")])
12246 (define_insn "*tbm_t1mskc_<mode>"
12247 [(set (match_operand:SWI48 0 "register_operand" "=r")
12250 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12254 (clobber (reg:CC FLAGS_REG))]
12256 "t1mskc\t{%1, %0|%0, %1}"
12257 [(set_attr "type" "bitmanip")
12258 (set_attr "mode" "<MODE>")])
12260 (define_insn "*tbm_tzmsk_<mode>"
12261 [(set (match_operand:SWI48 0 "register_operand" "=r")
12264 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12268 (clobber (reg:CC FLAGS_REG))]
12270 "tzmsk\t{%1, %0|%0, %1}"
12271 [(set_attr "type" "bitmanip")
12272 (set_attr "mode" "<MODE>")])
12274 (define_insn "bsr_rex64"
12275 [(set (match_operand:DI 0 "register_operand" "=r")
12276 (minus:DI (const_int 63)
12277 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12278 (clobber (reg:CC FLAGS_REG))]
12280 "bsr{q}\t{%1, %0|%0, %1}"
12281 [(set_attr "type" "alu1")
12282 (set_attr "prefix_0f" "1")
12283 (set_attr "mode" "DI")])
12286 [(set (match_operand:SI 0 "register_operand" "=r")
12287 (minus:SI (const_int 31)
12288 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12289 (clobber (reg:CC FLAGS_REG))]
12291 "bsr{l}\t{%1, %0|%0, %1}"
12292 [(set_attr "type" "alu1")
12293 (set_attr "prefix_0f" "1")
12294 (set_attr "mode" "SI")])
12296 (define_insn "*bsrhi"
12297 [(set (match_operand:HI 0 "register_operand" "=r")
12298 (minus:HI (const_int 15)
12299 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12300 (clobber (reg:CC FLAGS_REG))]
12302 "bsr{w}\t{%1, %0|%0, %1}"
12303 [(set_attr "type" "alu1")
12304 (set_attr "prefix_0f" "1")
12305 (set_attr "mode" "HI")])
12307 (define_insn "popcount<mode>2"
12308 [(set (match_operand:SWI248 0 "register_operand" "=r")
12310 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12311 (clobber (reg:CC FLAGS_REG))]
12315 return "popcnt\t{%1, %0|%0, %1}";
12317 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12320 [(set_attr "prefix_rep" "1")
12321 (set_attr "type" "bitmanip")
12322 (set_attr "mode" "<MODE>")])
12324 (define_insn "*popcount<mode>2_cmp"
12325 [(set (reg FLAGS_REG)
12328 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12330 (set (match_operand:SWI248 0 "register_operand" "=r")
12331 (popcount:SWI248 (match_dup 1)))]
12332 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12335 return "popcnt\t{%1, %0|%0, %1}";
12337 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12340 [(set_attr "prefix_rep" "1")
12341 (set_attr "type" "bitmanip")
12342 (set_attr "mode" "<MODE>")])
12344 (define_insn "*popcountsi2_cmp_zext"
12345 [(set (reg FLAGS_REG)
12347 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12349 (set (match_operand:DI 0 "register_operand" "=r")
12350 (zero_extend:DI(popcount:SI (match_dup 1))))]
12351 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12354 return "popcnt\t{%1, %0|%0, %1}";
12356 return "popcnt{l}\t{%1, %0|%0, %1}";
12359 [(set_attr "prefix_rep" "1")
12360 (set_attr "type" "bitmanip")
12361 (set_attr "mode" "SI")])
12363 (define_expand "bswap<mode>2"
12364 [(set (match_operand:SWI48 0 "register_operand" "")
12365 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12368 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12370 rtx x = operands[0];
12372 emit_move_insn (x, operands[1]);
12373 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12374 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12375 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12380 (define_insn "*bswap<mode>2_movbe"
12381 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12382 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12384 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12387 movbe\t{%1, %0|%0, %1}
12388 movbe\t{%1, %0|%0, %1}"
12389 [(set_attr "type" "bitmanip,imov,imov")
12390 (set_attr "modrm" "0,1,1")
12391 (set_attr "prefix_0f" "*,1,1")
12392 (set_attr "prefix_extra" "*,1,1")
12393 (set_attr "mode" "<MODE>")])
12395 (define_insn "*bswap<mode>2_1"
12396 [(set (match_operand:SWI48 0 "register_operand" "=r")
12397 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12400 [(set_attr "type" "bitmanip")
12401 (set_attr "modrm" "0")
12402 (set_attr "mode" "<MODE>")])
12404 (define_insn "*bswaphi_lowpart_1"
12405 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12406 (bswap:HI (match_dup 0)))
12407 (clobber (reg:CC FLAGS_REG))]
12408 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12410 xchg{b}\t{%h0, %b0|%b0, %h0}
12411 rol{w}\t{$8, %0|%0, 8}"
12412 [(set_attr "length" "2,4")
12413 (set_attr "mode" "QI,HI")])
12415 (define_insn "bswaphi_lowpart"
12416 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12417 (bswap:HI (match_dup 0)))
12418 (clobber (reg:CC FLAGS_REG))]
12420 "rol{w}\t{$8, %0|%0, 8}"
12421 [(set_attr "length" "4")
12422 (set_attr "mode" "HI")])
12424 (define_expand "paritydi2"
12425 [(set (match_operand:DI 0 "register_operand" "")
12426 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12429 rtx scratch = gen_reg_rtx (QImode);
12432 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12433 NULL_RTX, operands[1]));
12435 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12436 gen_rtx_REG (CCmode, FLAGS_REG),
12438 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12441 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12444 rtx tmp = gen_reg_rtx (SImode);
12446 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12447 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12452 (define_expand "paritysi2"
12453 [(set (match_operand:SI 0 "register_operand" "")
12454 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12457 rtx scratch = gen_reg_rtx (QImode);
12460 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12462 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12463 gen_rtx_REG (CCmode, FLAGS_REG),
12465 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12467 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12471 (define_insn_and_split "paritydi2_cmp"
12472 [(set (reg:CC FLAGS_REG)
12473 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12475 (clobber (match_scratch:DI 0 "=r"))
12476 (clobber (match_scratch:SI 1 "=&r"))
12477 (clobber (match_scratch:HI 2 "=Q"))]
12480 "&& reload_completed"
12482 [(set (match_dup 1)
12483 (xor:SI (match_dup 1) (match_dup 4)))
12484 (clobber (reg:CC FLAGS_REG))])
12486 [(set (reg:CC FLAGS_REG)
12487 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12488 (clobber (match_dup 1))
12489 (clobber (match_dup 2))])]
12491 operands[4] = gen_lowpart (SImode, operands[3]);
12495 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12496 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12499 operands[1] = gen_highpart (SImode, operands[3]);
12502 (define_insn_and_split "paritysi2_cmp"
12503 [(set (reg:CC FLAGS_REG)
12504 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12506 (clobber (match_scratch:SI 0 "=r"))
12507 (clobber (match_scratch:HI 1 "=&Q"))]
12510 "&& reload_completed"
12512 [(set (match_dup 1)
12513 (xor:HI (match_dup 1) (match_dup 3)))
12514 (clobber (reg:CC FLAGS_REG))])
12516 [(set (reg:CC FLAGS_REG)
12517 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12518 (clobber (match_dup 1))])]
12520 operands[3] = gen_lowpart (HImode, operands[2]);
12522 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12523 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12526 (define_insn "*parityhi2_cmp"
12527 [(set (reg:CC FLAGS_REG)
12528 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12530 (clobber (match_scratch:HI 0 "=Q"))]
12532 "xor{b}\t{%h0, %b0|%b0, %h0}"
12533 [(set_attr "length" "2")
12534 (set_attr "mode" "HI")])
12536 ;; Thread-local storage patterns for ELF.
12538 ;; Note that these code sequences must appear exactly as shown
12539 ;; in order to allow linker relaxation.
12541 (define_insn "*tls_global_dynamic_32_gnu"
12542 [(set (match_operand:SI 0 "register_operand" "=a")
12543 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12544 (match_operand:SI 2 "tls_symbolic_operand" "")
12545 (match_operand:SI 3 "call_insn_operand" "")]
12547 (clobber (match_scratch:SI 4 "=d"))
12548 (clobber (match_scratch:SI 5 "=c"))
12549 (clobber (reg:CC FLAGS_REG))]
12550 "!TARGET_64BIT && TARGET_GNU_TLS"
12551 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12552 [(set_attr "type" "multi")
12553 (set_attr "length" "12")])
12555 (define_expand "tls_global_dynamic_32"
12556 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12558 [(match_operand:SI 2 "register_operand" "")
12559 (match_operand:SI 1 "tls_symbolic_operand" "")
12560 (match_operand:SI 3 "call_insn_operand" "")]
12562 (clobber (match_scratch:SI 4 ""))
12563 (clobber (match_scratch:SI 5 ""))
12564 (clobber (reg:CC FLAGS_REG))])])
12566 (define_insn "*tls_global_dynamic_64"
12567 [(set (match_operand:DI 0 "register_operand" "=a")
12568 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12569 (match_operand:DI 3 "" "")))
12570 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12573 { 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"; }
12574 [(set_attr "type" "multi")
12575 (set_attr "length" "16")])
12577 (define_expand "tls_global_dynamic_64"
12578 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12580 (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12582 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12585 (define_insn "*tls_local_dynamic_base_32_gnu"
12586 [(set (match_operand:SI 0 "register_operand" "=a")
12587 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12588 (match_operand:SI 2 "call_insn_operand" "")]
12589 UNSPEC_TLS_LD_BASE))
12590 (clobber (match_scratch:SI 3 "=d"))
12591 (clobber (match_scratch:SI 4 "=c"))
12592 (clobber (reg:CC FLAGS_REG))]
12593 "!TARGET_64BIT && TARGET_GNU_TLS"
12594 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12595 [(set_attr "type" "multi")
12596 (set_attr "length" "11")])
12598 (define_expand "tls_local_dynamic_base_32"
12599 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12600 (unspec:SI [(match_operand:SI 1 "register_operand" "")
12601 (match_operand:SI 2 "call_insn_operand" "")]
12602 UNSPEC_TLS_LD_BASE))
12603 (clobber (match_scratch:SI 3 ""))
12604 (clobber (match_scratch:SI 4 ""))
12605 (clobber (reg:CC FLAGS_REG))])])
12607 (define_insn "*tls_local_dynamic_base_64"
12608 [(set (match_operand:DI 0 "register_operand" "=a")
12609 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12610 (match_operand:DI 2 "" "")))
12611 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12613 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12614 [(set_attr "type" "multi")
12615 (set_attr "length" "12")])
12617 (define_expand "tls_local_dynamic_base_64"
12618 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12620 (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12622 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12624 ;; Local dynamic of a single variable is a lose. Show combine how
12625 ;; to convert that back to global dynamic.
12627 (define_insn_and_split "*tls_local_dynamic_32_once"
12628 [(set (match_operand:SI 0 "register_operand" "=a")
12629 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12630 (match_operand:SI 2 "call_insn_operand" "")]
12631 UNSPEC_TLS_LD_BASE)
12632 (const:SI (unspec:SI
12633 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12635 (clobber (match_scratch:SI 4 "=d"))
12636 (clobber (match_scratch:SI 5 "=c"))
12637 (clobber (reg:CC FLAGS_REG))]
12641 [(parallel [(set (match_dup 0)
12642 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12644 (clobber (match_dup 4))
12645 (clobber (match_dup 5))
12646 (clobber (reg:CC FLAGS_REG))])])
12648 ;; Segment register for the thread base ptr load
12649 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12651 ;; Load and add the thread base pointer from %gs:0.
12652 (define_insn "*load_tp_<mode>"
12653 [(set (match_operand:P 0 "register_operand" "=r")
12654 (unspec:P [(const_int 0)] UNSPEC_TP))]
12656 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12657 [(set_attr "type" "imov")
12658 (set_attr "modrm" "0")
12659 (set_attr "length" "7")
12660 (set_attr "memory" "load")
12661 (set_attr "imm_disp" "false")])
12663 (define_insn "*add_tp_<mode>"
12664 [(set (match_operand:P 0 "register_operand" "=r")
12665 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12666 (match_operand:P 1 "register_operand" "0")))
12667 (clobber (reg:CC FLAGS_REG))]
12669 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12670 [(set_attr "type" "alu")
12671 (set_attr "modrm" "0")
12672 (set_attr "length" "7")
12673 (set_attr "memory" "load")
12674 (set_attr "imm_disp" "false")])
12676 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12677 ;; %rax as destination of the initial executable code sequence.
12678 (define_insn "tls_initial_exec_64_sun"
12679 [(set (match_operand:DI 0 "register_operand" "=a")
12681 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12682 UNSPEC_TLS_IE_SUN))
12683 (clobber (reg:CC FLAGS_REG))]
12684 "TARGET_64BIT && TARGET_SUN_TLS"
12685 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12686 [(set_attr "type" "multi")])
12688 ;; GNU2 TLS patterns can be split.
12690 (define_expand "tls_dynamic_gnu2_32"
12691 [(set (match_dup 3)
12692 (plus:SI (match_operand:SI 2 "register_operand" "")
12694 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12697 [(set (match_operand:SI 0 "register_operand" "")
12698 (unspec:SI [(match_dup 1) (match_dup 3)
12699 (match_dup 2) (reg:SI SP_REG)]
12701 (clobber (reg:CC FLAGS_REG))])]
12702 "!TARGET_64BIT && TARGET_GNU2_TLS"
12704 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12705 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12708 (define_insn "*tls_dynamic_lea_32"
12709 [(set (match_operand:SI 0 "register_operand" "=r")
12710 (plus:SI (match_operand:SI 1 "register_operand" "b")
12712 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12713 UNSPEC_TLSDESC))))]
12714 "!TARGET_64BIT && TARGET_GNU2_TLS"
12715 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12716 [(set_attr "type" "lea")
12717 (set_attr "mode" "SI")
12718 (set_attr "length" "6")
12719 (set_attr "length_address" "4")])
12721 (define_insn "*tls_dynamic_call_32"
12722 [(set (match_operand:SI 0 "register_operand" "=a")
12723 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12724 (match_operand:SI 2 "register_operand" "0")
12725 ;; we have to make sure %ebx still points to the GOT
12726 (match_operand:SI 3 "register_operand" "b")
12729 (clobber (reg:CC FLAGS_REG))]
12730 "!TARGET_64BIT && TARGET_GNU2_TLS"
12731 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12732 [(set_attr "type" "call")
12733 (set_attr "length" "2")
12734 (set_attr "length_address" "0")])
12736 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12737 [(set (match_operand:SI 0 "register_operand" "=&a")
12739 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12740 (match_operand:SI 4 "" "")
12741 (match_operand:SI 2 "register_operand" "b")
12744 (const:SI (unspec:SI
12745 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12747 (clobber (reg:CC FLAGS_REG))]
12748 "!TARGET_64BIT && TARGET_GNU2_TLS"
12751 [(set (match_dup 0) (match_dup 5))]
12753 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12754 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12757 (define_expand "tls_dynamic_gnu2_64"
12758 [(set (match_dup 2)
12759 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12762 [(set (match_operand:DI 0 "register_operand" "")
12763 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12765 (clobber (reg:CC FLAGS_REG))])]
12766 "TARGET_64BIT && TARGET_GNU2_TLS"
12768 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12769 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12772 (define_insn "*tls_dynamic_lea_64"
12773 [(set (match_operand:DI 0 "register_operand" "=r")
12774 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12776 "TARGET_64BIT && TARGET_GNU2_TLS"
12777 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12778 [(set_attr "type" "lea")
12779 (set_attr "mode" "DI")
12780 (set_attr "length" "7")
12781 (set_attr "length_address" "4")])
12783 (define_insn "*tls_dynamic_call_64"
12784 [(set (match_operand:DI 0 "register_operand" "=a")
12785 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12786 (match_operand:DI 2 "register_operand" "0")
12789 (clobber (reg:CC FLAGS_REG))]
12790 "TARGET_64BIT && TARGET_GNU2_TLS"
12791 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12792 [(set_attr "type" "call")
12793 (set_attr "length" "2")
12794 (set_attr "length_address" "0")])
12796 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12797 [(set (match_operand:DI 0 "register_operand" "=&a")
12799 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12800 (match_operand:DI 3 "" "")
12803 (const:DI (unspec:DI
12804 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12806 (clobber (reg:CC FLAGS_REG))]
12807 "TARGET_64BIT && TARGET_GNU2_TLS"
12810 [(set (match_dup 0) (match_dup 4))]
12812 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12813 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12816 ;; These patterns match the binary 387 instructions for addM3, subM3,
12817 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12818 ;; SFmode. The first is the normal insn, the second the same insn but
12819 ;; with one operand a conversion, and the third the same insn but with
12820 ;; the other operand a conversion. The conversion may be SFmode or
12821 ;; SImode if the target mode DFmode, but only SImode if the target mode
12824 ;; Gcc is slightly more smart about handling normal two address instructions
12825 ;; so use special patterns for add and mull.
12827 (define_insn "*fop_<mode>_comm_mixed"
12828 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12829 (match_operator:MODEF 3 "binary_fp_operator"
12830 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12831 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12832 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12833 && COMMUTATIVE_ARITH_P (operands[3])
12834 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12835 "* return output_387_binary_op (insn, operands);"
12836 [(set (attr "type")
12837 (if_then_else (eq_attr "alternative" "1,2")
12838 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12839 (const_string "ssemul")
12840 (const_string "sseadd"))
12841 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12842 (const_string "fmul")
12843 (const_string "fop"))))
12844 (set_attr "isa" "base,noavx,avx")
12845 (set_attr "prefix" "orig,orig,vex")
12846 (set_attr "mode" "<MODE>")])
12848 (define_insn "*fop_<mode>_comm_sse"
12849 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12850 (match_operator:MODEF 3 "binary_fp_operator"
12851 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12852 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12853 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12854 && COMMUTATIVE_ARITH_P (operands[3])
12855 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12856 "* return output_387_binary_op (insn, operands);"
12857 [(set (attr "type")
12858 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12859 (const_string "ssemul")
12860 (const_string "sseadd")))
12861 (set_attr "isa" "noavx,avx")
12862 (set_attr "prefix" "orig,vex")
12863 (set_attr "mode" "<MODE>")])
12865 (define_insn "*fop_<mode>_comm_i387"
12866 [(set (match_operand:MODEF 0 "register_operand" "=f")
12867 (match_operator:MODEF 3 "binary_fp_operator"
12868 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12869 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12870 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12871 && COMMUTATIVE_ARITH_P (operands[3])
12872 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12873 "* return output_387_binary_op (insn, operands);"
12874 [(set (attr "type")
12875 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12876 (const_string "fmul")
12877 (const_string "fop")))
12878 (set_attr "mode" "<MODE>")])
12880 (define_insn "*fop_<mode>_1_mixed"
12881 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12882 (match_operator:MODEF 3 "binary_fp_operator"
12883 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12884 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12885 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12886 && !COMMUTATIVE_ARITH_P (operands[3])
12887 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12888 "* return output_387_binary_op (insn, operands);"
12889 [(set (attr "type")
12890 (cond [(and (eq_attr "alternative" "2,3")
12891 (match_operand:MODEF 3 "mult_operator" ""))
12892 (const_string "ssemul")
12893 (and (eq_attr "alternative" "2,3")
12894 (match_operand:MODEF 3 "div_operator" ""))
12895 (const_string "ssediv")
12896 (eq_attr "alternative" "2,3")
12897 (const_string "sseadd")
12898 (match_operand:MODEF 3 "mult_operator" "")
12899 (const_string "fmul")
12900 (match_operand:MODEF 3 "div_operator" "")
12901 (const_string "fdiv")
12903 (const_string "fop")))
12904 (set_attr "isa" "base,base,noavx,avx")
12905 (set_attr "prefix" "orig,orig,orig,vex")
12906 (set_attr "mode" "<MODE>")])
12908 (define_insn "*rcpsf2_sse"
12909 [(set (match_operand:SF 0 "register_operand" "=x")
12910 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12913 "%vrcpss\t{%1, %d0|%d0, %1}"
12914 [(set_attr "type" "sse")
12915 (set_attr "atom_sse_attr" "rcp")
12916 (set_attr "prefix" "maybe_vex")
12917 (set_attr "mode" "SF")])
12919 (define_insn "*fop_<mode>_1_sse"
12920 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12921 (match_operator:MODEF 3 "binary_fp_operator"
12922 [(match_operand:MODEF 1 "register_operand" "0,x")
12923 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12924 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12925 && !COMMUTATIVE_ARITH_P (operands[3])"
12926 "* return output_387_binary_op (insn, operands);"
12927 [(set (attr "type")
12928 (cond [(match_operand:MODEF 3 "mult_operator" "")
12929 (const_string "ssemul")
12930 (match_operand:MODEF 3 "div_operator" "")
12931 (const_string "ssediv")
12933 (const_string "sseadd")))
12934 (set_attr "isa" "noavx,avx")
12935 (set_attr "prefix" "orig,vex")
12936 (set_attr "mode" "<MODE>")])
12938 ;; This pattern is not fully shadowed by the pattern above.
12939 (define_insn "*fop_<mode>_1_i387"
12940 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12941 (match_operator:MODEF 3 "binary_fp_operator"
12942 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12943 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12944 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12945 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12946 && !COMMUTATIVE_ARITH_P (operands[3])
12947 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12948 "* return output_387_binary_op (insn, operands);"
12949 [(set (attr "type")
12950 (cond [(match_operand:MODEF 3 "mult_operator" "")
12951 (const_string "fmul")
12952 (match_operand:MODEF 3 "div_operator" "")
12953 (const_string "fdiv")
12955 (const_string "fop")))
12956 (set_attr "mode" "<MODE>")])
12958 ;; ??? Add SSE splitters for these!
12959 (define_insn "*fop_<MODEF:mode>_2_i387"
12960 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12961 (match_operator:MODEF 3 "binary_fp_operator"
12963 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12964 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12965 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12966 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12967 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12968 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12969 [(set (attr "type")
12970 (cond [(match_operand:MODEF 3 "mult_operator" "")
12971 (const_string "fmul")
12972 (match_operand:MODEF 3 "div_operator" "")
12973 (const_string "fdiv")
12975 (const_string "fop")))
12976 (set_attr "fp_int_src" "true")
12977 (set_attr "mode" "<X87MODEI12:MODE>")])
12979 (define_insn "*fop_<MODEF:mode>_3_i387"
12980 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12981 (match_operator:MODEF 3 "binary_fp_operator"
12982 [(match_operand:MODEF 1 "register_operand" "0,0")
12984 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12985 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12986 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12987 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12988 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12989 [(set (attr "type")
12990 (cond [(match_operand:MODEF 3 "mult_operator" "")
12991 (const_string "fmul")
12992 (match_operand:MODEF 3 "div_operator" "")
12993 (const_string "fdiv")
12995 (const_string "fop")))
12996 (set_attr "fp_int_src" "true")
12997 (set_attr "mode" "<MODE>")])
12999 (define_insn "*fop_df_4_i387"
13000 [(set (match_operand:DF 0 "register_operand" "=f,f")
13001 (match_operator:DF 3 "binary_fp_operator"
13003 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13004 (match_operand:DF 2 "register_operand" "0,f")]))]
13005 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13006 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13007 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13008 "* return output_387_binary_op (insn, operands);"
13009 [(set (attr "type")
13010 (cond [(match_operand:DF 3 "mult_operator" "")
13011 (const_string "fmul")
13012 (match_operand:DF 3 "div_operator" "")
13013 (const_string "fdiv")
13015 (const_string "fop")))
13016 (set_attr "mode" "SF")])
13018 (define_insn "*fop_df_5_i387"
13019 [(set (match_operand:DF 0 "register_operand" "=f,f")
13020 (match_operator:DF 3 "binary_fp_operator"
13021 [(match_operand:DF 1 "register_operand" "0,f")
13023 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13024 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13025 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13026 "* return output_387_binary_op (insn, operands);"
13027 [(set (attr "type")
13028 (cond [(match_operand:DF 3 "mult_operator" "")
13029 (const_string "fmul")
13030 (match_operand:DF 3 "div_operator" "")
13031 (const_string "fdiv")
13033 (const_string "fop")))
13034 (set_attr "mode" "SF")])
13036 (define_insn "*fop_df_6_i387"
13037 [(set (match_operand:DF 0 "register_operand" "=f,f")
13038 (match_operator:DF 3 "binary_fp_operator"
13040 (match_operand:SF 1 "register_operand" "0,f"))
13042 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13043 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13044 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13045 "* return output_387_binary_op (insn, operands);"
13046 [(set (attr "type")
13047 (cond [(match_operand:DF 3 "mult_operator" "")
13048 (const_string "fmul")
13049 (match_operand:DF 3 "div_operator" "")
13050 (const_string "fdiv")
13052 (const_string "fop")))
13053 (set_attr "mode" "SF")])
13055 (define_insn "*fop_xf_comm_i387"
13056 [(set (match_operand:XF 0 "register_operand" "=f")
13057 (match_operator:XF 3 "binary_fp_operator"
13058 [(match_operand:XF 1 "register_operand" "%0")
13059 (match_operand:XF 2 "register_operand" "f")]))]
13061 && COMMUTATIVE_ARITH_P (operands[3])"
13062 "* return output_387_binary_op (insn, operands);"
13063 [(set (attr "type")
13064 (if_then_else (match_operand:XF 3 "mult_operator" "")
13065 (const_string "fmul")
13066 (const_string "fop")))
13067 (set_attr "mode" "XF")])
13069 (define_insn "*fop_xf_1_i387"
13070 [(set (match_operand:XF 0 "register_operand" "=f,f")
13071 (match_operator:XF 3 "binary_fp_operator"
13072 [(match_operand:XF 1 "register_operand" "0,f")
13073 (match_operand:XF 2 "register_operand" "f,0")]))]
13075 && !COMMUTATIVE_ARITH_P (operands[3])"
13076 "* return output_387_binary_op (insn, operands);"
13077 [(set (attr "type")
13078 (cond [(match_operand:XF 3 "mult_operator" "")
13079 (const_string "fmul")
13080 (match_operand:XF 3 "div_operator" "")
13081 (const_string "fdiv")
13083 (const_string "fop")))
13084 (set_attr "mode" "XF")])
13086 (define_insn "*fop_xf_2_i387"
13087 [(set (match_operand:XF 0 "register_operand" "=f,f")
13088 (match_operator:XF 3 "binary_fp_operator"
13090 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13091 (match_operand:XF 2 "register_operand" "0,0")]))]
13092 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13093 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13094 [(set (attr "type")
13095 (cond [(match_operand:XF 3 "mult_operator" "")
13096 (const_string "fmul")
13097 (match_operand:XF 3 "div_operator" "")
13098 (const_string "fdiv")
13100 (const_string "fop")))
13101 (set_attr "fp_int_src" "true")
13102 (set_attr "mode" "<MODE>")])
13104 (define_insn "*fop_xf_3_i387"
13105 [(set (match_operand:XF 0 "register_operand" "=f,f")
13106 (match_operator:XF 3 "binary_fp_operator"
13107 [(match_operand:XF 1 "register_operand" "0,0")
13109 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13110 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13111 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13112 [(set (attr "type")
13113 (cond [(match_operand:XF 3 "mult_operator" "")
13114 (const_string "fmul")
13115 (match_operand:XF 3 "div_operator" "")
13116 (const_string "fdiv")
13118 (const_string "fop")))
13119 (set_attr "fp_int_src" "true")
13120 (set_attr "mode" "<MODE>")])
13122 (define_insn "*fop_xf_4_i387"
13123 [(set (match_operand:XF 0 "register_operand" "=f,f")
13124 (match_operator:XF 3 "binary_fp_operator"
13126 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13127 (match_operand:XF 2 "register_operand" "0,f")]))]
13129 "* return output_387_binary_op (insn, operands);"
13130 [(set (attr "type")
13131 (cond [(match_operand:XF 3 "mult_operator" "")
13132 (const_string "fmul")
13133 (match_operand:XF 3 "div_operator" "")
13134 (const_string "fdiv")
13136 (const_string "fop")))
13137 (set_attr "mode" "<MODE>")])
13139 (define_insn "*fop_xf_5_i387"
13140 [(set (match_operand:XF 0 "register_operand" "=f,f")
13141 (match_operator:XF 3 "binary_fp_operator"
13142 [(match_operand:XF 1 "register_operand" "0,f")
13144 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13146 "* return output_387_binary_op (insn, operands);"
13147 [(set (attr "type")
13148 (cond [(match_operand:XF 3 "mult_operator" "")
13149 (const_string "fmul")
13150 (match_operand:XF 3 "div_operator" "")
13151 (const_string "fdiv")
13153 (const_string "fop")))
13154 (set_attr "mode" "<MODE>")])
13156 (define_insn "*fop_xf_6_i387"
13157 [(set (match_operand:XF 0 "register_operand" "=f,f")
13158 (match_operator:XF 3 "binary_fp_operator"
13160 (match_operand:MODEF 1 "register_operand" "0,f"))
13162 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13164 "* return output_387_binary_op (insn, operands);"
13165 [(set (attr "type")
13166 (cond [(match_operand:XF 3 "mult_operator" "")
13167 (const_string "fmul")
13168 (match_operand:XF 3 "div_operator" "")
13169 (const_string "fdiv")
13171 (const_string "fop")))
13172 (set_attr "mode" "<MODE>")])
13175 [(set (match_operand 0 "register_operand" "")
13176 (match_operator 3 "binary_fp_operator"
13177 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13178 (match_operand 2 "register_operand" "")]))]
13180 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13181 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13184 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13185 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13186 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13187 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13188 GET_MODE (operands[3]),
13191 ix86_free_from_memory (GET_MODE (operands[1]));
13196 [(set (match_operand 0 "register_operand" "")
13197 (match_operator 3 "binary_fp_operator"
13198 [(match_operand 1 "register_operand" "")
13199 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13201 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13202 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13205 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13206 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13207 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13208 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13209 GET_MODE (operands[3]),
13212 ix86_free_from_memory (GET_MODE (operands[2]));
13216 ;; FPU special functions.
13218 ;; This pattern implements a no-op XFmode truncation for
13219 ;; all fancy i386 XFmode math functions.
13221 (define_insn "truncxf<mode>2_i387_noop_unspec"
13222 [(set (match_operand:MODEF 0 "register_operand" "=f")
13223 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13224 UNSPEC_TRUNC_NOOP))]
13225 "TARGET_USE_FANCY_MATH_387"
13226 "* return output_387_reg_move (insn, operands);"
13227 [(set_attr "type" "fmov")
13228 (set_attr "mode" "<MODE>")])
13230 (define_insn "sqrtxf2"
13231 [(set (match_operand:XF 0 "register_operand" "=f")
13232 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13233 "TARGET_USE_FANCY_MATH_387"
13235 [(set_attr "type" "fpspc")
13236 (set_attr "mode" "XF")
13237 (set_attr "athlon_decode" "direct")
13238 (set_attr "amdfam10_decode" "direct")
13239 (set_attr "bdver1_decode" "direct")])
13241 (define_insn "sqrt_extend<mode>xf2_i387"
13242 [(set (match_operand:XF 0 "register_operand" "=f")
13245 (match_operand:MODEF 1 "register_operand" "0"))))]
13246 "TARGET_USE_FANCY_MATH_387"
13248 [(set_attr "type" "fpspc")
13249 (set_attr "mode" "XF")
13250 (set_attr "athlon_decode" "direct")
13251 (set_attr "amdfam10_decode" "direct")
13252 (set_attr "bdver1_decode" "direct")])
13254 (define_insn "*rsqrtsf2_sse"
13255 [(set (match_operand:SF 0 "register_operand" "=x")
13256 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13259 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13260 [(set_attr "type" "sse")
13261 (set_attr "atom_sse_attr" "rcp")
13262 (set_attr "prefix" "maybe_vex")
13263 (set_attr "mode" "SF")])
13265 (define_expand "rsqrtsf2"
13266 [(set (match_operand:SF 0 "register_operand" "")
13267 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13271 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13275 (define_insn "*sqrt<mode>2_sse"
13276 [(set (match_operand:MODEF 0 "register_operand" "=x")
13278 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13279 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13280 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13281 [(set_attr "type" "sse")
13282 (set_attr "atom_sse_attr" "sqrt")
13283 (set_attr "prefix" "maybe_vex")
13284 (set_attr "mode" "<MODE>")
13285 (set_attr "athlon_decode" "*")
13286 (set_attr "amdfam10_decode" "*")
13287 (set_attr "bdver1_decode" "*")])
13289 (define_expand "sqrt<mode>2"
13290 [(set (match_operand:MODEF 0 "register_operand" "")
13292 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13293 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13294 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13296 if (<MODE>mode == SFmode
13297 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13298 && flag_finite_math_only && !flag_trapping_math
13299 && flag_unsafe_math_optimizations)
13301 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13305 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13307 rtx op0 = gen_reg_rtx (XFmode);
13308 rtx op1 = force_reg (<MODE>mode, operands[1]);
13310 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13311 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13316 (define_insn "fpremxf4_i387"
13317 [(set (match_operand:XF 0 "register_operand" "=f")
13318 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13319 (match_operand:XF 3 "register_operand" "1")]
13321 (set (match_operand:XF 1 "register_operand" "=u")
13322 (unspec:XF [(match_dup 2) (match_dup 3)]
13324 (set (reg:CCFP FPSR_REG)
13325 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13327 "TARGET_USE_FANCY_MATH_387"
13329 [(set_attr "type" "fpspc")
13330 (set_attr "mode" "XF")])
13332 (define_expand "fmodxf3"
13333 [(use (match_operand:XF 0 "register_operand" ""))
13334 (use (match_operand:XF 1 "general_operand" ""))
13335 (use (match_operand:XF 2 "general_operand" ""))]
13336 "TARGET_USE_FANCY_MATH_387"
13338 rtx label = gen_label_rtx ();
13340 rtx op1 = gen_reg_rtx (XFmode);
13341 rtx op2 = gen_reg_rtx (XFmode);
13343 emit_move_insn (op2, operands[2]);
13344 emit_move_insn (op1, operands[1]);
13346 emit_label (label);
13347 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13348 ix86_emit_fp_unordered_jump (label);
13349 LABEL_NUSES (label) = 1;
13351 emit_move_insn (operands[0], op1);
13355 (define_expand "fmod<mode>3"
13356 [(use (match_operand:MODEF 0 "register_operand" ""))
13357 (use (match_operand:MODEF 1 "general_operand" ""))
13358 (use (match_operand:MODEF 2 "general_operand" ""))]
13359 "TARGET_USE_FANCY_MATH_387"
13361 rtx (*gen_truncxf) (rtx, rtx);
13363 rtx label = gen_label_rtx ();
13365 rtx op1 = gen_reg_rtx (XFmode);
13366 rtx op2 = gen_reg_rtx (XFmode);
13368 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13369 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13371 emit_label (label);
13372 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13373 ix86_emit_fp_unordered_jump (label);
13374 LABEL_NUSES (label) = 1;
13376 /* Truncate the result properly for strict SSE math. */
13377 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13378 && !TARGET_MIX_SSE_I387)
13379 gen_truncxf = gen_truncxf<mode>2;
13381 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13383 emit_insn (gen_truncxf (operands[0], op1));
13387 (define_insn "fprem1xf4_i387"
13388 [(set (match_operand:XF 0 "register_operand" "=f")
13389 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13390 (match_operand:XF 3 "register_operand" "1")]
13392 (set (match_operand:XF 1 "register_operand" "=u")
13393 (unspec:XF [(match_dup 2) (match_dup 3)]
13395 (set (reg:CCFP FPSR_REG)
13396 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13398 "TARGET_USE_FANCY_MATH_387"
13400 [(set_attr "type" "fpspc")
13401 (set_attr "mode" "XF")])
13403 (define_expand "remainderxf3"
13404 [(use (match_operand:XF 0 "register_operand" ""))
13405 (use (match_operand:XF 1 "general_operand" ""))
13406 (use (match_operand:XF 2 "general_operand" ""))]
13407 "TARGET_USE_FANCY_MATH_387"
13409 rtx label = gen_label_rtx ();
13411 rtx op1 = gen_reg_rtx (XFmode);
13412 rtx op2 = gen_reg_rtx (XFmode);
13414 emit_move_insn (op2, operands[2]);
13415 emit_move_insn (op1, operands[1]);
13417 emit_label (label);
13418 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13419 ix86_emit_fp_unordered_jump (label);
13420 LABEL_NUSES (label) = 1;
13422 emit_move_insn (operands[0], op1);
13426 (define_expand "remainder<mode>3"
13427 [(use (match_operand:MODEF 0 "register_operand" ""))
13428 (use (match_operand:MODEF 1 "general_operand" ""))
13429 (use (match_operand:MODEF 2 "general_operand" ""))]
13430 "TARGET_USE_FANCY_MATH_387"
13432 rtx (*gen_truncxf) (rtx, rtx);
13434 rtx label = gen_label_rtx ();
13436 rtx op1 = gen_reg_rtx (XFmode);
13437 rtx op2 = gen_reg_rtx (XFmode);
13439 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13440 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13442 emit_label (label);
13444 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13445 ix86_emit_fp_unordered_jump (label);
13446 LABEL_NUSES (label) = 1;
13448 /* Truncate the result properly for strict SSE math. */
13449 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13450 && !TARGET_MIX_SSE_I387)
13451 gen_truncxf = gen_truncxf<mode>2;
13453 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13455 emit_insn (gen_truncxf (operands[0], op1));
13459 (define_insn "*sinxf2_i387"
13460 [(set (match_operand:XF 0 "register_operand" "=f")
13461 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13462 "TARGET_USE_FANCY_MATH_387
13463 && flag_unsafe_math_optimizations"
13465 [(set_attr "type" "fpspc")
13466 (set_attr "mode" "XF")])
13468 (define_insn "*sin_extend<mode>xf2_i387"
13469 [(set (match_operand:XF 0 "register_operand" "=f")
13470 (unspec:XF [(float_extend:XF
13471 (match_operand:MODEF 1 "register_operand" "0"))]
13473 "TARGET_USE_FANCY_MATH_387
13474 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13475 || TARGET_MIX_SSE_I387)
13476 && flag_unsafe_math_optimizations"
13478 [(set_attr "type" "fpspc")
13479 (set_attr "mode" "XF")])
13481 (define_insn "*cosxf2_i387"
13482 [(set (match_operand:XF 0 "register_operand" "=f")
13483 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13484 "TARGET_USE_FANCY_MATH_387
13485 && flag_unsafe_math_optimizations"
13487 [(set_attr "type" "fpspc")
13488 (set_attr "mode" "XF")])
13490 (define_insn "*cos_extend<mode>xf2_i387"
13491 [(set (match_operand:XF 0 "register_operand" "=f")
13492 (unspec:XF [(float_extend:XF
13493 (match_operand:MODEF 1 "register_operand" "0"))]
13495 "TARGET_USE_FANCY_MATH_387
13496 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13497 || TARGET_MIX_SSE_I387)
13498 && flag_unsafe_math_optimizations"
13500 [(set_attr "type" "fpspc")
13501 (set_attr "mode" "XF")])
13503 ;; When sincos pattern is defined, sin and cos builtin functions will be
13504 ;; expanded to sincos pattern with one of its outputs left unused.
13505 ;; CSE pass will figure out if two sincos patterns can be combined,
13506 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13507 ;; depending on the unused output.
13509 (define_insn "sincosxf3"
13510 [(set (match_operand:XF 0 "register_operand" "=f")
13511 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13512 UNSPEC_SINCOS_COS))
13513 (set (match_operand:XF 1 "register_operand" "=u")
13514 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13515 "TARGET_USE_FANCY_MATH_387
13516 && flag_unsafe_math_optimizations"
13518 [(set_attr "type" "fpspc")
13519 (set_attr "mode" "XF")])
13522 [(set (match_operand:XF 0 "register_operand" "")
13523 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13524 UNSPEC_SINCOS_COS))
13525 (set (match_operand:XF 1 "register_operand" "")
13526 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13527 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13528 && !(reload_completed || reload_in_progress)"
13529 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13532 [(set (match_operand:XF 0 "register_operand" "")
13533 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13534 UNSPEC_SINCOS_COS))
13535 (set (match_operand:XF 1 "register_operand" "")
13536 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13537 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13538 && !(reload_completed || reload_in_progress)"
13539 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13541 (define_insn "sincos_extend<mode>xf3_i387"
13542 [(set (match_operand:XF 0 "register_operand" "=f")
13543 (unspec:XF [(float_extend:XF
13544 (match_operand:MODEF 2 "register_operand" "0"))]
13545 UNSPEC_SINCOS_COS))
13546 (set (match_operand:XF 1 "register_operand" "=u")
13547 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13548 "TARGET_USE_FANCY_MATH_387
13549 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13550 || TARGET_MIX_SSE_I387)
13551 && flag_unsafe_math_optimizations"
13553 [(set_attr "type" "fpspc")
13554 (set_attr "mode" "XF")])
13557 [(set (match_operand:XF 0 "register_operand" "")
13558 (unspec:XF [(float_extend:XF
13559 (match_operand:MODEF 2 "register_operand" ""))]
13560 UNSPEC_SINCOS_COS))
13561 (set (match_operand:XF 1 "register_operand" "")
13562 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13563 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13564 && !(reload_completed || reload_in_progress)"
13565 [(set (match_dup 1)
13566 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13569 [(set (match_operand:XF 0 "register_operand" "")
13570 (unspec:XF [(float_extend:XF
13571 (match_operand:MODEF 2 "register_operand" ""))]
13572 UNSPEC_SINCOS_COS))
13573 (set (match_operand:XF 1 "register_operand" "")
13574 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13575 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13576 && !(reload_completed || reload_in_progress)"
13577 [(set (match_dup 0)
13578 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13580 (define_expand "sincos<mode>3"
13581 [(use (match_operand:MODEF 0 "register_operand" ""))
13582 (use (match_operand:MODEF 1 "register_operand" ""))
13583 (use (match_operand:MODEF 2 "register_operand" ""))]
13584 "TARGET_USE_FANCY_MATH_387
13585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13586 || TARGET_MIX_SSE_I387)
13587 && flag_unsafe_math_optimizations"
13589 rtx op0 = gen_reg_rtx (XFmode);
13590 rtx op1 = gen_reg_rtx (XFmode);
13592 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13593 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13594 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13598 (define_insn "fptanxf4_i387"
13599 [(set (match_operand:XF 0 "register_operand" "=f")
13600 (match_operand:XF 3 "const_double_operand" "F"))
13601 (set (match_operand:XF 1 "register_operand" "=u")
13602 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13604 "TARGET_USE_FANCY_MATH_387
13605 && flag_unsafe_math_optimizations
13606 && standard_80387_constant_p (operands[3]) == 2"
13608 [(set_attr "type" "fpspc")
13609 (set_attr "mode" "XF")])
13611 (define_insn "fptan_extend<mode>xf4_i387"
13612 [(set (match_operand:MODEF 0 "register_operand" "=f")
13613 (match_operand:MODEF 3 "const_double_operand" "F"))
13614 (set (match_operand:XF 1 "register_operand" "=u")
13615 (unspec:XF [(float_extend:XF
13616 (match_operand:MODEF 2 "register_operand" "0"))]
13618 "TARGET_USE_FANCY_MATH_387
13619 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13620 || TARGET_MIX_SSE_I387)
13621 && flag_unsafe_math_optimizations
13622 && standard_80387_constant_p (operands[3]) == 2"
13624 [(set_attr "type" "fpspc")
13625 (set_attr "mode" "XF")])
13627 (define_expand "tanxf2"
13628 [(use (match_operand:XF 0 "register_operand" ""))
13629 (use (match_operand:XF 1 "register_operand" ""))]
13630 "TARGET_USE_FANCY_MATH_387
13631 && flag_unsafe_math_optimizations"
13633 rtx one = gen_reg_rtx (XFmode);
13634 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13636 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13640 (define_expand "tan<mode>2"
13641 [(use (match_operand:MODEF 0 "register_operand" ""))
13642 (use (match_operand:MODEF 1 "register_operand" ""))]
13643 "TARGET_USE_FANCY_MATH_387
13644 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13645 || TARGET_MIX_SSE_I387)
13646 && flag_unsafe_math_optimizations"
13648 rtx op0 = gen_reg_rtx (XFmode);
13650 rtx one = gen_reg_rtx (<MODE>mode);
13651 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13653 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13654 operands[1], op2));
13655 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13659 (define_insn "*fpatanxf3_i387"
13660 [(set (match_operand:XF 0 "register_operand" "=f")
13661 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13662 (match_operand:XF 2 "register_operand" "u")]
13664 (clobber (match_scratch:XF 3 "=2"))]
13665 "TARGET_USE_FANCY_MATH_387
13666 && flag_unsafe_math_optimizations"
13668 [(set_attr "type" "fpspc")
13669 (set_attr "mode" "XF")])
13671 (define_insn "fpatan_extend<mode>xf3_i387"
13672 [(set (match_operand:XF 0 "register_operand" "=f")
13673 (unspec:XF [(float_extend:XF
13674 (match_operand:MODEF 1 "register_operand" "0"))
13676 (match_operand:MODEF 2 "register_operand" "u"))]
13678 (clobber (match_scratch:XF 3 "=2"))]
13679 "TARGET_USE_FANCY_MATH_387
13680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13681 || TARGET_MIX_SSE_I387)
13682 && flag_unsafe_math_optimizations"
13684 [(set_attr "type" "fpspc")
13685 (set_attr "mode" "XF")])
13687 (define_expand "atan2xf3"
13688 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13689 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13690 (match_operand:XF 1 "register_operand" "")]
13692 (clobber (match_scratch:XF 3 ""))])]
13693 "TARGET_USE_FANCY_MATH_387
13694 && flag_unsafe_math_optimizations")
13696 (define_expand "atan2<mode>3"
13697 [(use (match_operand:MODEF 0 "register_operand" ""))
13698 (use (match_operand:MODEF 1 "register_operand" ""))
13699 (use (match_operand:MODEF 2 "register_operand" ""))]
13700 "TARGET_USE_FANCY_MATH_387
13701 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13702 || TARGET_MIX_SSE_I387)
13703 && flag_unsafe_math_optimizations"
13705 rtx op0 = gen_reg_rtx (XFmode);
13707 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13708 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13712 (define_expand "atanxf2"
13713 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13714 (unspec:XF [(match_dup 2)
13715 (match_operand:XF 1 "register_operand" "")]
13717 (clobber (match_scratch:XF 3 ""))])]
13718 "TARGET_USE_FANCY_MATH_387
13719 && flag_unsafe_math_optimizations"
13721 operands[2] = gen_reg_rtx (XFmode);
13722 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13725 (define_expand "atan<mode>2"
13726 [(use (match_operand:MODEF 0 "register_operand" ""))
13727 (use (match_operand:MODEF 1 "register_operand" ""))]
13728 "TARGET_USE_FANCY_MATH_387
13729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13730 || TARGET_MIX_SSE_I387)
13731 && flag_unsafe_math_optimizations"
13733 rtx op0 = gen_reg_rtx (XFmode);
13735 rtx op2 = gen_reg_rtx (<MODE>mode);
13736 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13738 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13739 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13743 (define_expand "asinxf2"
13744 [(set (match_dup 2)
13745 (mult:XF (match_operand:XF 1 "register_operand" "")
13747 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13748 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13749 (parallel [(set (match_operand:XF 0 "register_operand" "")
13750 (unspec:XF [(match_dup 5) (match_dup 1)]
13752 (clobber (match_scratch:XF 6 ""))])]
13753 "TARGET_USE_FANCY_MATH_387
13754 && flag_unsafe_math_optimizations"
13758 if (optimize_insn_for_size_p ())
13761 for (i = 2; i < 6; i++)
13762 operands[i] = gen_reg_rtx (XFmode);
13764 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13767 (define_expand "asin<mode>2"
13768 [(use (match_operand:MODEF 0 "register_operand" ""))
13769 (use (match_operand:MODEF 1 "general_operand" ""))]
13770 "TARGET_USE_FANCY_MATH_387
13771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13772 || TARGET_MIX_SSE_I387)
13773 && flag_unsafe_math_optimizations"
13775 rtx op0 = gen_reg_rtx (XFmode);
13776 rtx op1 = gen_reg_rtx (XFmode);
13778 if (optimize_insn_for_size_p ())
13781 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13782 emit_insn (gen_asinxf2 (op0, op1));
13783 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13787 (define_expand "acosxf2"
13788 [(set (match_dup 2)
13789 (mult:XF (match_operand:XF 1 "register_operand" "")
13791 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13792 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13793 (parallel [(set (match_operand:XF 0 "register_operand" "")
13794 (unspec:XF [(match_dup 1) (match_dup 5)]
13796 (clobber (match_scratch:XF 6 ""))])]
13797 "TARGET_USE_FANCY_MATH_387
13798 && flag_unsafe_math_optimizations"
13802 if (optimize_insn_for_size_p ())
13805 for (i = 2; i < 6; i++)
13806 operands[i] = gen_reg_rtx (XFmode);
13808 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13811 (define_expand "acos<mode>2"
13812 [(use (match_operand:MODEF 0 "register_operand" ""))
13813 (use (match_operand:MODEF 1 "general_operand" ""))]
13814 "TARGET_USE_FANCY_MATH_387
13815 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13816 || TARGET_MIX_SSE_I387)
13817 && flag_unsafe_math_optimizations"
13819 rtx op0 = gen_reg_rtx (XFmode);
13820 rtx op1 = gen_reg_rtx (XFmode);
13822 if (optimize_insn_for_size_p ())
13825 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13826 emit_insn (gen_acosxf2 (op0, op1));
13827 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13831 (define_insn "fyl2xxf3_i387"
13832 [(set (match_operand:XF 0 "register_operand" "=f")
13833 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13834 (match_operand:XF 2 "register_operand" "u")]
13836 (clobber (match_scratch:XF 3 "=2"))]
13837 "TARGET_USE_FANCY_MATH_387
13838 && flag_unsafe_math_optimizations"
13840 [(set_attr "type" "fpspc")
13841 (set_attr "mode" "XF")])
13843 (define_insn "fyl2x_extend<mode>xf3_i387"
13844 [(set (match_operand:XF 0 "register_operand" "=f")
13845 (unspec:XF [(float_extend:XF
13846 (match_operand:MODEF 1 "register_operand" "0"))
13847 (match_operand:XF 2 "register_operand" "u")]
13849 (clobber (match_scratch:XF 3 "=2"))]
13850 "TARGET_USE_FANCY_MATH_387
13851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13852 || TARGET_MIX_SSE_I387)
13853 && flag_unsafe_math_optimizations"
13855 [(set_attr "type" "fpspc")
13856 (set_attr "mode" "XF")])
13858 (define_expand "logxf2"
13859 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13860 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13861 (match_dup 2)] UNSPEC_FYL2X))
13862 (clobber (match_scratch:XF 3 ""))])]
13863 "TARGET_USE_FANCY_MATH_387
13864 && flag_unsafe_math_optimizations"
13866 operands[2] = gen_reg_rtx (XFmode);
13867 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13870 (define_expand "log<mode>2"
13871 [(use (match_operand:MODEF 0 "register_operand" ""))
13872 (use (match_operand:MODEF 1 "register_operand" ""))]
13873 "TARGET_USE_FANCY_MATH_387
13874 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13875 || TARGET_MIX_SSE_I387)
13876 && flag_unsafe_math_optimizations"
13878 rtx op0 = gen_reg_rtx (XFmode);
13880 rtx op2 = gen_reg_rtx (XFmode);
13881 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13883 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13884 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13888 (define_expand "log10xf2"
13889 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13890 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13891 (match_dup 2)] UNSPEC_FYL2X))
13892 (clobber (match_scratch:XF 3 ""))])]
13893 "TARGET_USE_FANCY_MATH_387
13894 && flag_unsafe_math_optimizations"
13896 operands[2] = gen_reg_rtx (XFmode);
13897 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13900 (define_expand "log10<mode>2"
13901 [(use (match_operand:MODEF 0 "register_operand" ""))
13902 (use (match_operand:MODEF 1 "register_operand" ""))]
13903 "TARGET_USE_FANCY_MATH_387
13904 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13905 || TARGET_MIX_SSE_I387)
13906 && flag_unsafe_math_optimizations"
13908 rtx op0 = gen_reg_rtx (XFmode);
13910 rtx op2 = gen_reg_rtx (XFmode);
13911 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13913 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13914 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13918 (define_expand "log2xf2"
13919 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13920 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13921 (match_dup 2)] UNSPEC_FYL2X))
13922 (clobber (match_scratch:XF 3 ""))])]
13923 "TARGET_USE_FANCY_MATH_387
13924 && flag_unsafe_math_optimizations"
13926 operands[2] = gen_reg_rtx (XFmode);
13927 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13930 (define_expand "log2<mode>2"
13931 [(use (match_operand:MODEF 0 "register_operand" ""))
13932 (use (match_operand:MODEF 1 "register_operand" ""))]
13933 "TARGET_USE_FANCY_MATH_387
13934 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13935 || TARGET_MIX_SSE_I387)
13936 && flag_unsafe_math_optimizations"
13938 rtx op0 = gen_reg_rtx (XFmode);
13940 rtx op2 = gen_reg_rtx (XFmode);
13941 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13943 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13944 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13948 (define_insn "fyl2xp1xf3_i387"
13949 [(set (match_operand:XF 0 "register_operand" "=f")
13950 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13951 (match_operand:XF 2 "register_operand" "u")]
13953 (clobber (match_scratch:XF 3 "=2"))]
13954 "TARGET_USE_FANCY_MATH_387
13955 && flag_unsafe_math_optimizations"
13957 [(set_attr "type" "fpspc")
13958 (set_attr "mode" "XF")])
13960 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13961 [(set (match_operand:XF 0 "register_operand" "=f")
13962 (unspec:XF [(float_extend:XF
13963 (match_operand:MODEF 1 "register_operand" "0"))
13964 (match_operand:XF 2 "register_operand" "u")]
13966 (clobber (match_scratch:XF 3 "=2"))]
13967 "TARGET_USE_FANCY_MATH_387
13968 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13969 || TARGET_MIX_SSE_I387)
13970 && flag_unsafe_math_optimizations"
13972 [(set_attr "type" "fpspc")
13973 (set_attr "mode" "XF")])
13975 (define_expand "log1pxf2"
13976 [(use (match_operand:XF 0 "register_operand" ""))
13977 (use (match_operand:XF 1 "register_operand" ""))]
13978 "TARGET_USE_FANCY_MATH_387
13979 && flag_unsafe_math_optimizations"
13981 if (optimize_insn_for_size_p ())
13984 ix86_emit_i387_log1p (operands[0], operands[1]);
13988 (define_expand "log1p<mode>2"
13989 [(use (match_operand:MODEF 0 "register_operand" ""))
13990 (use (match_operand:MODEF 1 "register_operand" ""))]
13991 "TARGET_USE_FANCY_MATH_387
13992 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13993 || TARGET_MIX_SSE_I387)
13994 && flag_unsafe_math_optimizations"
13998 if (optimize_insn_for_size_p ())
14001 op0 = gen_reg_rtx (XFmode);
14003 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14005 ix86_emit_i387_log1p (op0, operands[1]);
14006 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14010 (define_insn "fxtractxf3_i387"
14011 [(set (match_operand:XF 0 "register_operand" "=f")
14012 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14013 UNSPEC_XTRACT_FRACT))
14014 (set (match_operand:XF 1 "register_operand" "=u")
14015 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14016 "TARGET_USE_FANCY_MATH_387
14017 && flag_unsafe_math_optimizations"
14019 [(set_attr "type" "fpspc")
14020 (set_attr "mode" "XF")])
14022 (define_insn "fxtract_extend<mode>xf3_i387"
14023 [(set (match_operand:XF 0 "register_operand" "=f")
14024 (unspec:XF [(float_extend:XF
14025 (match_operand:MODEF 2 "register_operand" "0"))]
14026 UNSPEC_XTRACT_FRACT))
14027 (set (match_operand:XF 1 "register_operand" "=u")
14028 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14029 "TARGET_USE_FANCY_MATH_387
14030 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14031 || TARGET_MIX_SSE_I387)
14032 && flag_unsafe_math_optimizations"
14034 [(set_attr "type" "fpspc")
14035 (set_attr "mode" "XF")])
14037 (define_expand "logbxf2"
14038 [(parallel [(set (match_dup 2)
14039 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14040 UNSPEC_XTRACT_FRACT))
14041 (set (match_operand:XF 0 "register_operand" "")
14042 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14043 "TARGET_USE_FANCY_MATH_387
14044 && flag_unsafe_math_optimizations"
14045 "operands[2] = gen_reg_rtx (XFmode);")
14047 (define_expand "logb<mode>2"
14048 [(use (match_operand:MODEF 0 "register_operand" ""))
14049 (use (match_operand:MODEF 1 "register_operand" ""))]
14050 "TARGET_USE_FANCY_MATH_387
14051 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14052 || TARGET_MIX_SSE_I387)
14053 && flag_unsafe_math_optimizations"
14055 rtx op0 = gen_reg_rtx (XFmode);
14056 rtx op1 = gen_reg_rtx (XFmode);
14058 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14059 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14063 (define_expand "ilogbxf2"
14064 [(use (match_operand:SI 0 "register_operand" ""))
14065 (use (match_operand:XF 1 "register_operand" ""))]
14066 "TARGET_USE_FANCY_MATH_387
14067 && flag_unsafe_math_optimizations"
14071 if (optimize_insn_for_size_p ())
14074 op0 = gen_reg_rtx (XFmode);
14075 op1 = gen_reg_rtx (XFmode);
14077 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14078 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14082 (define_expand "ilogb<mode>2"
14083 [(use (match_operand:SI 0 "register_operand" ""))
14084 (use (match_operand:MODEF 1 "register_operand" ""))]
14085 "TARGET_USE_FANCY_MATH_387
14086 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14087 || TARGET_MIX_SSE_I387)
14088 && flag_unsafe_math_optimizations"
14092 if (optimize_insn_for_size_p ())
14095 op0 = gen_reg_rtx (XFmode);
14096 op1 = gen_reg_rtx (XFmode);
14098 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14099 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14103 (define_insn "*f2xm1xf2_i387"
14104 [(set (match_operand:XF 0 "register_operand" "=f")
14105 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14107 "TARGET_USE_FANCY_MATH_387
14108 && flag_unsafe_math_optimizations"
14110 [(set_attr "type" "fpspc")
14111 (set_attr "mode" "XF")])
14113 (define_insn "*fscalexf4_i387"
14114 [(set (match_operand:XF 0 "register_operand" "=f")
14115 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14116 (match_operand:XF 3 "register_operand" "1")]
14117 UNSPEC_FSCALE_FRACT))
14118 (set (match_operand:XF 1 "register_operand" "=u")
14119 (unspec:XF [(match_dup 2) (match_dup 3)]
14120 UNSPEC_FSCALE_EXP))]
14121 "TARGET_USE_FANCY_MATH_387
14122 && flag_unsafe_math_optimizations"
14124 [(set_attr "type" "fpspc")
14125 (set_attr "mode" "XF")])
14127 (define_expand "expNcorexf3"
14128 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14129 (match_operand:XF 2 "register_operand" "")))
14130 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14131 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14132 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14133 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14134 (parallel [(set (match_operand:XF 0 "register_operand" "")
14135 (unspec:XF [(match_dup 8) (match_dup 4)]
14136 UNSPEC_FSCALE_FRACT))
14138 (unspec:XF [(match_dup 8) (match_dup 4)]
14139 UNSPEC_FSCALE_EXP))])]
14140 "TARGET_USE_FANCY_MATH_387
14141 && flag_unsafe_math_optimizations"
14145 if (optimize_insn_for_size_p ())
14148 for (i = 3; i < 10; i++)
14149 operands[i] = gen_reg_rtx (XFmode);
14151 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14154 (define_expand "expxf2"
14155 [(use (match_operand:XF 0 "register_operand" ""))
14156 (use (match_operand:XF 1 "register_operand" ""))]
14157 "TARGET_USE_FANCY_MATH_387
14158 && flag_unsafe_math_optimizations"
14162 if (optimize_insn_for_size_p ())
14165 op2 = gen_reg_rtx (XFmode);
14166 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14168 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14172 (define_expand "exp<mode>2"
14173 [(use (match_operand:MODEF 0 "register_operand" ""))
14174 (use (match_operand:MODEF 1 "general_operand" ""))]
14175 "TARGET_USE_FANCY_MATH_387
14176 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14177 || TARGET_MIX_SSE_I387)
14178 && flag_unsafe_math_optimizations"
14182 if (optimize_insn_for_size_p ())
14185 op0 = gen_reg_rtx (XFmode);
14186 op1 = gen_reg_rtx (XFmode);
14188 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14189 emit_insn (gen_expxf2 (op0, op1));
14190 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14194 (define_expand "exp10xf2"
14195 [(use (match_operand:XF 0 "register_operand" ""))
14196 (use (match_operand:XF 1 "register_operand" ""))]
14197 "TARGET_USE_FANCY_MATH_387
14198 && flag_unsafe_math_optimizations"
14202 if (optimize_insn_for_size_p ())
14205 op2 = gen_reg_rtx (XFmode);
14206 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14208 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14212 (define_expand "exp10<mode>2"
14213 [(use (match_operand:MODEF 0 "register_operand" ""))
14214 (use (match_operand:MODEF 1 "general_operand" ""))]
14215 "TARGET_USE_FANCY_MATH_387
14216 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14217 || TARGET_MIX_SSE_I387)
14218 && flag_unsafe_math_optimizations"
14222 if (optimize_insn_for_size_p ())
14225 op0 = gen_reg_rtx (XFmode);
14226 op1 = gen_reg_rtx (XFmode);
14228 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14229 emit_insn (gen_exp10xf2 (op0, op1));
14230 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14234 (define_expand "exp2xf2"
14235 [(use (match_operand:XF 0 "register_operand" ""))
14236 (use (match_operand:XF 1 "register_operand" ""))]
14237 "TARGET_USE_FANCY_MATH_387
14238 && flag_unsafe_math_optimizations"
14242 if (optimize_insn_for_size_p ())
14245 op2 = gen_reg_rtx (XFmode);
14246 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14248 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14252 (define_expand "exp2<mode>2"
14253 [(use (match_operand:MODEF 0 "register_operand" ""))
14254 (use (match_operand:MODEF 1 "general_operand" ""))]
14255 "TARGET_USE_FANCY_MATH_387
14256 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14257 || TARGET_MIX_SSE_I387)
14258 && flag_unsafe_math_optimizations"
14262 if (optimize_insn_for_size_p ())
14265 op0 = gen_reg_rtx (XFmode);
14266 op1 = gen_reg_rtx (XFmode);
14268 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14269 emit_insn (gen_exp2xf2 (op0, op1));
14270 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14274 (define_expand "expm1xf2"
14275 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14277 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14278 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14279 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14280 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14281 (parallel [(set (match_dup 7)
14282 (unspec:XF [(match_dup 6) (match_dup 4)]
14283 UNSPEC_FSCALE_FRACT))
14285 (unspec:XF [(match_dup 6) (match_dup 4)]
14286 UNSPEC_FSCALE_EXP))])
14287 (parallel [(set (match_dup 10)
14288 (unspec:XF [(match_dup 9) (match_dup 8)]
14289 UNSPEC_FSCALE_FRACT))
14290 (set (match_dup 11)
14291 (unspec:XF [(match_dup 9) (match_dup 8)]
14292 UNSPEC_FSCALE_EXP))])
14293 (set (match_dup 12) (minus:XF (match_dup 10)
14294 (float_extend:XF (match_dup 13))))
14295 (set (match_operand:XF 0 "register_operand" "")
14296 (plus:XF (match_dup 12) (match_dup 7)))]
14297 "TARGET_USE_FANCY_MATH_387
14298 && flag_unsafe_math_optimizations"
14302 if (optimize_insn_for_size_p ())
14305 for (i = 2; i < 13; i++)
14306 operands[i] = gen_reg_rtx (XFmode);
14309 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14311 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14314 (define_expand "expm1<mode>2"
14315 [(use (match_operand:MODEF 0 "register_operand" ""))
14316 (use (match_operand:MODEF 1 "general_operand" ""))]
14317 "TARGET_USE_FANCY_MATH_387
14318 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14319 || TARGET_MIX_SSE_I387)
14320 && flag_unsafe_math_optimizations"
14324 if (optimize_insn_for_size_p ())
14327 op0 = gen_reg_rtx (XFmode);
14328 op1 = gen_reg_rtx (XFmode);
14330 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14331 emit_insn (gen_expm1xf2 (op0, op1));
14332 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14336 (define_expand "ldexpxf3"
14337 [(set (match_dup 3)
14338 (float:XF (match_operand:SI 2 "register_operand" "")))
14339 (parallel [(set (match_operand:XF 0 " register_operand" "")
14340 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14342 UNSPEC_FSCALE_FRACT))
14344 (unspec:XF [(match_dup 1) (match_dup 3)]
14345 UNSPEC_FSCALE_EXP))])]
14346 "TARGET_USE_FANCY_MATH_387
14347 && flag_unsafe_math_optimizations"
14349 if (optimize_insn_for_size_p ())
14352 operands[3] = gen_reg_rtx (XFmode);
14353 operands[4] = gen_reg_rtx (XFmode);
14356 (define_expand "ldexp<mode>3"
14357 [(use (match_operand:MODEF 0 "register_operand" ""))
14358 (use (match_operand:MODEF 1 "general_operand" ""))
14359 (use (match_operand:SI 2 "register_operand" ""))]
14360 "TARGET_USE_FANCY_MATH_387
14361 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14362 || TARGET_MIX_SSE_I387)
14363 && flag_unsafe_math_optimizations"
14367 if (optimize_insn_for_size_p ())
14370 op0 = gen_reg_rtx (XFmode);
14371 op1 = gen_reg_rtx (XFmode);
14373 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14374 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14375 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14379 (define_expand "scalbxf3"
14380 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14381 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14382 (match_operand:XF 2 "register_operand" "")]
14383 UNSPEC_FSCALE_FRACT))
14385 (unspec:XF [(match_dup 1) (match_dup 2)]
14386 UNSPEC_FSCALE_EXP))])]
14387 "TARGET_USE_FANCY_MATH_387
14388 && flag_unsafe_math_optimizations"
14390 if (optimize_insn_for_size_p ())
14393 operands[3] = gen_reg_rtx (XFmode);
14396 (define_expand "scalb<mode>3"
14397 [(use (match_operand:MODEF 0 "register_operand" ""))
14398 (use (match_operand:MODEF 1 "general_operand" ""))
14399 (use (match_operand:MODEF 2 "general_operand" ""))]
14400 "TARGET_USE_FANCY_MATH_387
14401 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14402 || TARGET_MIX_SSE_I387)
14403 && flag_unsafe_math_optimizations"
14407 if (optimize_insn_for_size_p ())
14410 op0 = gen_reg_rtx (XFmode);
14411 op1 = gen_reg_rtx (XFmode);
14412 op2 = gen_reg_rtx (XFmode);
14414 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14415 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14416 emit_insn (gen_scalbxf3 (op0, op1, op2));
14417 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14421 (define_expand "significandxf2"
14422 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14423 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14424 UNSPEC_XTRACT_FRACT))
14426 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14427 "TARGET_USE_FANCY_MATH_387
14428 && flag_unsafe_math_optimizations"
14429 "operands[2] = gen_reg_rtx (XFmode);")
14431 (define_expand "significand<mode>2"
14432 [(use (match_operand:MODEF 0 "register_operand" ""))
14433 (use (match_operand:MODEF 1 "register_operand" ""))]
14434 "TARGET_USE_FANCY_MATH_387
14435 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14436 || TARGET_MIX_SSE_I387)
14437 && flag_unsafe_math_optimizations"
14439 rtx op0 = gen_reg_rtx (XFmode);
14440 rtx op1 = gen_reg_rtx (XFmode);
14442 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14443 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14448 (define_insn "sse4_1_round<mode>2"
14449 [(set (match_operand:MODEF 0 "register_operand" "=x")
14450 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14451 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14454 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14455 [(set_attr "type" "ssecvt")
14456 (set_attr "prefix_extra" "1")
14457 (set_attr "prefix" "maybe_vex")
14458 (set_attr "mode" "<MODE>")])
14460 (define_insn "rintxf2"
14461 [(set (match_operand:XF 0 "register_operand" "=f")
14462 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14464 "TARGET_USE_FANCY_MATH_387
14465 && flag_unsafe_math_optimizations"
14467 [(set_attr "type" "fpspc")
14468 (set_attr "mode" "XF")])
14470 (define_expand "rint<mode>2"
14471 [(use (match_operand:MODEF 0 "register_operand" ""))
14472 (use (match_operand:MODEF 1 "register_operand" ""))]
14473 "(TARGET_USE_FANCY_MATH_387
14474 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14475 || TARGET_MIX_SSE_I387)
14476 && flag_unsafe_math_optimizations)
14477 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14478 && !flag_trapping_math)"
14480 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14481 && !flag_trapping_math)
14483 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14486 emit_insn (gen_sse4_1_round<mode>2
14487 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14489 ix86_expand_rint (operand0, operand1);
14493 rtx op0 = gen_reg_rtx (XFmode);
14494 rtx op1 = gen_reg_rtx (XFmode);
14496 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14497 emit_insn (gen_rintxf2 (op0, op1));
14499 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14504 (define_expand "round<mode>2"
14505 [(match_operand:MODEF 0 "register_operand" "")
14506 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14507 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14508 && !flag_trapping_math && !flag_rounding_math"
14510 if (optimize_insn_for_size_p ())
14512 if (TARGET_64BIT || (<MODE>mode != DFmode))
14513 ix86_expand_round (operand0, operand1);
14515 ix86_expand_rounddf_32 (operand0, operand1);
14519 (define_insn_and_split "*fistdi2_1"
14520 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14521 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14523 "TARGET_USE_FANCY_MATH_387
14524 && can_create_pseudo_p ()"
14529 if (memory_operand (operands[0], VOIDmode))
14530 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14533 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14534 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14539 [(set_attr "type" "fpspc")
14540 (set_attr "mode" "DI")])
14542 (define_insn "fistdi2"
14543 [(set (match_operand:DI 0 "memory_operand" "=m")
14544 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14546 (clobber (match_scratch:XF 2 "=&1f"))]
14547 "TARGET_USE_FANCY_MATH_387"
14548 "* return output_fix_trunc (insn, operands, 0);"
14549 [(set_attr "type" "fpspc")
14550 (set_attr "mode" "DI")])
14552 (define_insn "fistdi2_with_temp"
14553 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14554 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14556 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14557 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14558 "TARGET_USE_FANCY_MATH_387"
14560 [(set_attr "type" "fpspc")
14561 (set_attr "mode" "DI")])
14564 [(set (match_operand:DI 0 "register_operand" "")
14565 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14567 (clobber (match_operand:DI 2 "memory_operand" ""))
14568 (clobber (match_scratch 3 ""))]
14570 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14571 (clobber (match_dup 3))])
14572 (set (match_dup 0) (match_dup 2))])
14575 [(set (match_operand:DI 0 "memory_operand" "")
14576 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14578 (clobber (match_operand:DI 2 "memory_operand" ""))
14579 (clobber (match_scratch 3 ""))]
14581 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14582 (clobber (match_dup 3))])])
14584 (define_insn_and_split "*fist<mode>2_1"
14585 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14586 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14588 "TARGET_USE_FANCY_MATH_387
14589 && can_create_pseudo_p ()"
14594 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14595 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14599 [(set_attr "type" "fpspc")
14600 (set_attr "mode" "<MODE>")])
14602 (define_insn "fist<mode>2"
14603 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14604 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14606 "TARGET_USE_FANCY_MATH_387"
14607 "* return output_fix_trunc (insn, operands, 0);"
14608 [(set_attr "type" "fpspc")
14609 (set_attr "mode" "<MODE>")])
14611 (define_insn "fist<mode>2_with_temp"
14612 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14613 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14615 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14616 "TARGET_USE_FANCY_MATH_387"
14618 [(set_attr "type" "fpspc")
14619 (set_attr "mode" "<MODE>")])
14622 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14623 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14625 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14627 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14628 (set (match_dup 0) (match_dup 2))])
14631 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14632 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14634 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14636 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14638 (define_expand "lrintxf<mode>2"
14639 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14640 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14642 "TARGET_USE_FANCY_MATH_387")
14644 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14645 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14646 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14647 UNSPEC_FIX_NOTRUNC))]
14648 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14649 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14651 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14652 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14653 (match_operand:MODEF 1 "register_operand" "")]
14654 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14655 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14656 && !flag_trapping_math && !flag_rounding_math"
14658 if (optimize_insn_for_size_p ())
14660 ix86_expand_lround (operand0, operand1);
14664 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14665 (define_insn_and_split "frndintxf2_floor"
14666 [(set (match_operand:XF 0 "register_operand" "")
14667 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14668 UNSPEC_FRNDINT_FLOOR))
14669 (clobber (reg:CC FLAGS_REG))]
14670 "TARGET_USE_FANCY_MATH_387
14671 && flag_unsafe_math_optimizations
14672 && can_create_pseudo_p ()"
14677 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14679 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14680 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14682 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14683 operands[2], operands[3]));
14686 [(set_attr "type" "frndint")
14687 (set_attr "i387_cw" "floor")
14688 (set_attr "mode" "XF")])
14690 (define_insn "frndintxf2_floor_i387"
14691 [(set (match_operand:XF 0 "register_operand" "=f")
14692 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14693 UNSPEC_FRNDINT_FLOOR))
14694 (use (match_operand:HI 2 "memory_operand" "m"))
14695 (use (match_operand:HI 3 "memory_operand" "m"))]
14696 "TARGET_USE_FANCY_MATH_387
14697 && flag_unsafe_math_optimizations"
14698 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14699 [(set_attr "type" "frndint")
14700 (set_attr "i387_cw" "floor")
14701 (set_attr "mode" "XF")])
14703 (define_expand "floorxf2"
14704 [(use (match_operand:XF 0 "register_operand" ""))
14705 (use (match_operand:XF 1 "register_operand" ""))]
14706 "TARGET_USE_FANCY_MATH_387
14707 && flag_unsafe_math_optimizations"
14709 if (optimize_insn_for_size_p ())
14711 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14715 (define_expand "floor<mode>2"
14716 [(use (match_operand:MODEF 0 "register_operand" ""))
14717 (use (match_operand:MODEF 1 "register_operand" ""))]
14718 "(TARGET_USE_FANCY_MATH_387
14719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14720 || TARGET_MIX_SSE_I387)
14721 && flag_unsafe_math_optimizations)
14722 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14723 && !flag_trapping_math)"
14725 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14726 && !flag_trapping_math
14727 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14729 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14732 emit_insn (gen_sse4_1_round<mode>2
14733 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14734 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14735 ix86_expand_floorceil (operand0, operand1, true);
14737 ix86_expand_floorceildf_32 (operand0, operand1, true);
14743 if (optimize_insn_for_size_p ())
14746 op0 = gen_reg_rtx (XFmode);
14747 op1 = gen_reg_rtx (XFmode);
14748 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14749 emit_insn (gen_frndintxf2_floor (op0, op1));
14751 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14756 (define_insn_and_split "*fist<mode>2_floor_1"
14757 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14758 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14759 UNSPEC_FIST_FLOOR))
14760 (clobber (reg:CC FLAGS_REG))]
14761 "TARGET_USE_FANCY_MATH_387
14762 && flag_unsafe_math_optimizations
14763 && can_create_pseudo_p ()"
14768 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14770 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14771 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14772 if (memory_operand (operands[0], VOIDmode))
14773 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14774 operands[2], operands[3]));
14777 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14778 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14779 operands[2], operands[3],
14784 [(set_attr "type" "fistp")
14785 (set_attr "i387_cw" "floor")
14786 (set_attr "mode" "<MODE>")])
14788 (define_insn "fistdi2_floor"
14789 [(set (match_operand:DI 0 "memory_operand" "=m")
14790 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14791 UNSPEC_FIST_FLOOR))
14792 (use (match_operand:HI 2 "memory_operand" "m"))
14793 (use (match_operand:HI 3 "memory_operand" "m"))
14794 (clobber (match_scratch:XF 4 "=&1f"))]
14795 "TARGET_USE_FANCY_MATH_387
14796 && flag_unsafe_math_optimizations"
14797 "* return output_fix_trunc (insn, operands, 0);"
14798 [(set_attr "type" "fistp")
14799 (set_attr "i387_cw" "floor")
14800 (set_attr "mode" "DI")])
14802 (define_insn "fistdi2_floor_with_temp"
14803 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14804 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14805 UNSPEC_FIST_FLOOR))
14806 (use (match_operand:HI 2 "memory_operand" "m,m"))
14807 (use (match_operand:HI 3 "memory_operand" "m,m"))
14808 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14809 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14810 "TARGET_USE_FANCY_MATH_387
14811 && flag_unsafe_math_optimizations"
14813 [(set_attr "type" "fistp")
14814 (set_attr "i387_cw" "floor")
14815 (set_attr "mode" "DI")])
14818 [(set (match_operand:DI 0 "register_operand" "")
14819 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14820 UNSPEC_FIST_FLOOR))
14821 (use (match_operand:HI 2 "memory_operand" ""))
14822 (use (match_operand:HI 3 "memory_operand" ""))
14823 (clobber (match_operand:DI 4 "memory_operand" ""))
14824 (clobber (match_scratch 5 ""))]
14826 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14827 (use (match_dup 2))
14828 (use (match_dup 3))
14829 (clobber (match_dup 5))])
14830 (set (match_dup 0) (match_dup 4))])
14833 [(set (match_operand:DI 0 "memory_operand" "")
14834 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14835 UNSPEC_FIST_FLOOR))
14836 (use (match_operand:HI 2 "memory_operand" ""))
14837 (use (match_operand:HI 3 "memory_operand" ""))
14838 (clobber (match_operand:DI 4 "memory_operand" ""))
14839 (clobber (match_scratch 5 ""))]
14841 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14842 (use (match_dup 2))
14843 (use (match_dup 3))
14844 (clobber (match_dup 5))])])
14846 (define_insn "fist<mode>2_floor"
14847 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14848 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14849 UNSPEC_FIST_FLOOR))
14850 (use (match_operand:HI 2 "memory_operand" "m"))
14851 (use (match_operand:HI 3 "memory_operand" "m"))]
14852 "TARGET_USE_FANCY_MATH_387
14853 && flag_unsafe_math_optimizations"
14854 "* return output_fix_trunc (insn, operands, 0);"
14855 [(set_attr "type" "fistp")
14856 (set_attr "i387_cw" "floor")
14857 (set_attr "mode" "<MODE>")])
14859 (define_insn "fist<mode>2_floor_with_temp"
14860 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14861 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14862 UNSPEC_FIST_FLOOR))
14863 (use (match_operand:HI 2 "memory_operand" "m,m"))
14864 (use (match_operand:HI 3 "memory_operand" "m,m"))
14865 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14866 "TARGET_USE_FANCY_MATH_387
14867 && flag_unsafe_math_optimizations"
14869 [(set_attr "type" "fistp")
14870 (set_attr "i387_cw" "floor")
14871 (set_attr "mode" "<MODE>")])
14874 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14875 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14876 UNSPEC_FIST_FLOOR))
14877 (use (match_operand:HI 2 "memory_operand" ""))
14878 (use (match_operand:HI 3 "memory_operand" ""))
14879 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14881 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14882 UNSPEC_FIST_FLOOR))
14883 (use (match_dup 2))
14884 (use (match_dup 3))])
14885 (set (match_dup 0) (match_dup 4))])
14888 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14889 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14890 UNSPEC_FIST_FLOOR))
14891 (use (match_operand:HI 2 "memory_operand" ""))
14892 (use (match_operand:HI 3 "memory_operand" ""))
14893 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14895 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14896 UNSPEC_FIST_FLOOR))
14897 (use (match_dup 2))
14898 (use (match_dup 3))])])
14900 (define_expand "lfloorxf<mode>2"
14901 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14902 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14903 UNSPEC_FIST_FLOOR))
14904 (clobber (reg:CC FLAGS_REG))])]
14905 "TARGET_USE_FANCY_MATH_387
14906 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14907 && flag_unsafe_math_optimizations")
14909 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14910 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14911 (match_operand:MODEF 1 "register_operand" "")]
14912 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14913 && !flag_trapping_math"
14915 if (TARGET_64BIT && optimize_insn_for_size_p ())
14917 ix86_expand_lfloorceil (operand0, operand1, true);
14921 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14922 (define_insn_and_split "frndintxf2_ceil"
14923 [(set (match_operand:XF 0 "register_operand" "")
14924 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14925 UNSPEC_FRNDINT_CEIL))
14926 (clobber (reg:CC FLAGS_REG))]
14927 "TARGET_USE_FANCY_MATH_387
14928 && flag_unsafe_math_optimizations
14929 && can_create_pseudo_p ()"
14934 ix86_optimize_mode_switching[I387_CEIL] = 1;
14936 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14937 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14939 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14940 operands[2], operands[3]));
14943 [(set_attr "type" "frndint")
14944 (set_attr "i387_cw" "ceil")
14945 (set_attr "mode" "XF")])
14947 (define_insn "frndintxf2_ceil_i387"
14948 [(set (match_operand:XF 0 "register_operand" "=f")
14949 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14950 UNSPEC_FRNDINT_CEIL))
14951 (use (match_operand:HI 2 "memory_operand" "m"))
14952 (use (match_operand:HI 3 "memory_operand" "m"))]
14953 "TARGET_USE_FANCY_MATH_387
14954 && flag_unsafe_math_optimizations"
14955 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14956 [(set_attr "type" "frndint")
14957 (set_attr "i387_cw" "ceil")
14958 (set_attr "mode" "XF")])
14960 (define_expand "ceilxf2"
14961 [(use (match_operand:XF 0 "register_operand" ""))
14962 (use (match_operand:XF 1 "register_operand" ""))]
14963 "TARGET_USE_FANCY_MATH_387
14964 && flag_unsafe_math_optimizations"
14966 if (optimize_insn_for_size_p ())
14968 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14972 (define_expand "ceil<mode>2"
14973 [(use (match_operand:MODEF 0 "register_operand" ""))
14974 (use (match_operand:MODEF 1 "register_operand" ""))]
14975 "(TARGET_USE_FANCY_MATH_387
14976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14977 || TARGET_MIX_SSE_I387)
14978 && flag_unsafe_math_optimizations)
14979 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14980 && !flag_trapping_math)"
14982 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14983 && !flag_trapping_math
14984 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14987 emit_insn (gen_sse4_1_round<mode>2
14988 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14989 else if (optimize_insn_for_size_p ())
14991 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14992 ix86_expand_floorceil (operand0, operand1, false);
14994 ix86_expand_floorceildf_32 (operand0, operand1, false);
15000 if (optimize_insn_for_size_p ())
15003 op0 = gen_reg_rtx (XFmode);
15004 op1 = gen_reg_rtx (XFmode);
15005 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15006 emit_insn (gen_frndintxf2_ceil (op0, op1));
15008 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15013 (define_insn_and_split "*fist<mode>2_ceil_1"
15014 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15015 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15017 (clobber (reg:CC FLAGS_REG))]
15018 "TARGET_USE_FANCY_MATH_387
15019 && flag_unsafe_math_optimizations
15020 && can_create_pseudo_p ()"
15025 ix86_optimize_mode_switching[I387_CEIL] = 1;
15027 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15028 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15029 if (memory_operand (operands[0], VOIDmode))
15030 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15031 operands[2], operands[3]));
15034 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15035 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15036 operands[2], operands[3],
15041 [(set_attr "type" "fistp")
15042 (set_attr "i387_cw" "ceil")
15043 (set_attr "mode" "<MODE>")])
15045 (define_insn "fistdi2_ceil"
15046 [(set (match_operand:DI 0 "memory_operand" "=m")
15047 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15049 (use (match_operand:HI 2 "memory_operand" "m"))
15050 (use (match_operand:HI 3 "memory_operand" "m"))
15051 (clobber (match_scratch:XF 4 "=&1f"))]
15052 "TARGET_USE_FANCY_MATH_387
15053 && flag_unsafe_math_optimizations"
15054 "* return output_fix_trunc (insn, operands, 0);"
15055 [(set_attr "type" "fistp")
15056 (set_attr "i387_cw" "ceil")
15057 (set_attr "mode" "DI")])
15059 (define_insn "fistdi2_ceil_with_temp"
15060 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15061 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15063 (use (match_operand:HI 2 "memory_operand" "m,m"))
15064 (use (match_operand:HI 3 "memory_operand" "m,m"))
15065 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15066 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15067 "TARGET_USE_FANCY_MATH_387
15068 && flag_unsafe_math_optimizations"
15070 [(set_attr "type" "fistp")
15071 (set_attr "i387_cw" "ceil")
15072 (set_attr "mode" "DI")])
15075 [(set (match_operand:DI 0 "register_operand" "")
15076 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15078 (use (match_operand:HI 2 "memory_operand" ""))
15079 (use (match_operand:HI 3 "memory_operand" ""))
15080 (clobber (match_operand:DI 4 "memory_operand" ""))
15081 (clobber (match_scratch 5 ""))]
15083 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15084 (use (match_dup 2))
15085 (use (match_dup 3))
15086 (clobber (match_dup 5))])
15087 (set (match_dup 0) (match_dup 4))])
15090 [(set (match_operand:DI 0 "memory_operand" "")
15091 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15093 (use (match_operand:HI 2 "memory_operand" ""))
15094 (use (match_operand:HI 3 "memory_operand" ""))
15095 (clobber (match_operand:DI 4 "memory_operand" ""))
15096 (clobber (match_scratch 5 ""))]
15098 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15099 (use (match_dup 2))
15100 (use (match_dup 3))
15101 (clobber (match_dup 5))])])
15103 (define_insn "fist<mode>2_ceil"
15104 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15105 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15107 (use (match_operand:HI 2 "memory_operand" "m"))
15108 (use (match_operand:HI 3 "memory_operand" "m"))]
15109 "TARGET_USE_FANCY_MATH_387
15110 && flag_unsafe_math_optimizations"
15111 "* return output_fix_trunc (insn, operands, 0);"
15112 [(set_attr "type" "fistp")
15113 (set_attr "i387_cw" "ceil")
15114 (set_attr "mode" "<MODE>")])
15116 (define_insn "fist<mode>2_ceil_with_temp"
15117 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15118 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15120 (use (match_operand:HI 2 "memory_operand" "m,m"))
15121 (use (match_operand:HI 3 "memory_operand" "m,m"))
15122 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15123 "TARGET_USE_FANCY_MATH_387
15124 && flag_unsafe_math_optimizations"
15126 [(set_attr "type" "fistp")
15127 (set_attr "i387_cw" "ceil")
15128 (set_attr "mode" "<MODE>")])
15131 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15132 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15134 (use (match_operand:HI 2 "memory_operand" ""))
15135 (use (match_operand:HI 3 "memory_operand" ""))
15136 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15138 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15140 (use (match_dup 2))
15141 (use (match_dup 3))])
15142 (set (match_dup 0) (match_dup 4))])
15145 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15146 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15148 (use (match_operand:HI 2 "memory_operand" ""))
15149 (use (match_operand:HI 3 "memory_operand" ""))
15150 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15152 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15154 (use (match_dup 2))
15155 (use (match_dup 3))])])
15157 (define_expand "lceilxf<mode>2"
15158 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15159 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15161 (clobber (reg:CC FLAGS_REG))])]
15162 "TARGET_USE_FANCY_MATH_387
15163 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15164 && flag_unsafe_math_optimizations")
15166 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15167 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15168 (match_operand:MODEF 1 "register_operand" "")]
15169 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15170 && !flag_trapping_math"
15172 ix86_expand_lfloorceil (operand0, operand1, false);
15176 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15177 (define_insn_and_split "frndintxf2_trunc"
15178 [(set (match_operand:XF 0 "register_operand" "")
15179 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15180 UNSPEC_FRNDINT_TRUNC))
15181 (clobber (reg:CC FLAGS_REG))]
15182 "TARGET_USE_FANCY_MATH_387
15183 && flag_unsafe_math_optimizations
15184 && can_create_pseudo_p ()"
15189 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15191 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15192 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15194 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15195 operands[2], operands[3]));
15198 [(set_attr "type" "frndint")
15199 (set_attr "i387_cw" "trunc")
15200 (set_attr "mode" "XF")])
15202 (define_insn "frndintxf2_trunc_i387"
15203 [(set (match_operand:XF 0 "register_operand" "=f")
15204 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15205 UNSPEC_FRNDINT_TRUNC))
15206 (use (match_operand:HI 2 "memory_operand" "m"))
15207 (use (match_operand:HI 3 "memory_operand" "m"))]
15208 "TARGET_USE_FANCY_MATH_387
15209 && flag_unsafe_math_optimizations"
15210 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15211 [(set_attr "type" "frndint")
15212 (set_attr "i387_cw" "trunc")
15213 (set_attr "mode" "XF")])
15215 (define_expand "btruncxf2"
15216 [(use (match_operand:XF 0 "register_operand" ""))
15217 (use (match_operand:XF 1 "register_operand" ""))]
15218 "TARGET_USE_FANCY_MATH_387
15219 && flag_unsafe_math_optimizations"
15221 if (optimize_insn_for_size_p ())
15223 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15227 (define_expand "btrunc<mode>2"
15228 [(use (match_operand:MODEF 0 "register_operand" ""))
15229 (use (match_operand:MODEF 1 "register_operand" ""))]
15230 "(TARGET_USE_FANCY_MATH_387
15231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15232 || TARGET_MIX_SSE_I387)
15233 && flag_unsafe_math_optimizations)
15234 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15235 && !flag_trapping_math)"
15237 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15238 && !flag_trapping_math
15239 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15242 emit_insn (gen_sse4_1_round<mode>2
15243 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15244 else if (optimize_insn_for_size_p ())
15246 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15247 ix86_expand_trunc (operand0, operand1);
15249 ix86_expand_truncdf_32 (operand0, operand1);
15255 if (optimize_insn_for_size_p ())
15258 op0 = gen_reg_rtx (XFmode);
15259 op1 = gen_reg_rtx (XFmode);
15260 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15261 emit_insn (gen_frndintxf2_trunc (op0, op1));
15263 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15268 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15269 (define_insn_and_split "frndintxf2_mask_pm"
15270 [(set (match_operand:XF 0 "register_operand" "")
15271 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15272 UNSPEC_FRNDINT_MASK_PM))
15273 (clobber (reg:CC FLAGS_REG))]
15274 "TARGET_USE_FANCY_MATH_387
15275 && flag_unsafe_math_optimizations
15276 && can_create_pseudo_p ()"
15281 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15283 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15284 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15286 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15287 operands[2], operands[3]));
15290 [(set_attr "type" "frndint")
15291 (set_attr "i387_cw" "mask_pm")
15292 (set_attr "mode" "XF")])
15294 (define_insn "frndintxf2_mask_pm_i387"
15295 [(set (match_operand:XF 0 "register_operand" "=f")
15296 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15297 UNSPEC_FRNDINT_MASK_PM))
15298 (use (match_operand:HI 2 "memory_operand" "m"))
15299 (use (match_operand:HI 3 "memory_operand" "m"))]
15300 "TARGET_USE_FANCY_MATH_387
15301 && flag_unsafe_math_optimizations"
15302 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15303 [(set_attr "type" "frndint")
15304 (set_attr "i387_cw" "mask_pm")
15305 (set_attr "mode" "XF")])
15307 (define_expand "nearbyintxf2"
15308 [(use (match_operand:XF 0 "register_operand" ""))
15309 (use (match_operand:XF 1 "register_operand" ""))]
15310 "TARGET_USE_FANCY_MATH_387
15311 && flag_unsafe_math_optimizations"
15313 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15317 (define_expand "nearbyint<mode>2"
15318 [(use (match_operand:MODEF 0 "register_operand" ""))
15319 (use (match_operand:MODEF 1 "register_operand" ""))]
15320 "TARGET_USE_FANCY_MATH_387
15321 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15322 || TARGET_MIX_SSE_I387)
15323 && flag_unsafe_math_optimizations"
15325 rtx op0 = gen_reg_rtx (XFmode);
15326 rtx op1 = gen_reg_rtx (XFmode);
15328 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15329 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15331 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15335 (define_insn "fxam<mode>2_i387"
15336 [(set (match_operand:HI 0 "register_operand" "=a")
15338 [(match_operand:X87MODEF 1 "register_operand" "f")]
15340 "TARGET_USE_FANCY_MATH_387"
15341 "fxam\n\tfnstsw\t%0"
15342 [(set_attr "type" "multi")
15343 (set_attr "length" "4")
15344 (set_attr "unit" "i387")
15345 (set_attr "mode" "<MODE>")])
15347 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15348 [(set (match_operand:HI 0 "register_operand" "")
15350 [(match_operand:MODEF 1 "memory_operand" "")]
15352 "TARGET_USE_FANCY_MATH_387
15353 && can_create_pseudo_p ()"
15356 [(set (match_dup 2)(match_dup 1))
15358 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15360 operands[2] = gen_reg_rtx (<MODE>mode);
15362 MEM_VOLATILE_P (operands[1]) = 1;
15364 [(set_attr "type" "multi")
15365 (set_attr "unit" "i387")
15366 (set_attr "mode" "<MODE>")])
15368 (define_expand "isinfxf2"
15369 [(use (match_operand:SI 0 "register_operand" ""))
15370 (use (match_operand:XF 1 "register_operand" ""))]
15371 "TARGET_USE_FANCY_MATH_387
15372 && TARGET_C99_FUNCTIONS"
15374 rtx mask = GEN_INT (0x45);
15375 rtx val = GEN_INT (0x05);
15379 rtx scratch = gen_reg_rtx (HImode);
15380 rtx res = gen_reg_rtx (QImode);
15382 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15384 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15385 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15386 cond = gen_rtx_fmt_ee (EQ, QImode,
15387 gen_rtx_REG (CCmode, FLAGS_REG),
15389 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15390 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15394 (define_expand "isinf<mode>2"
15395 [(use (match_operand:SI 0 "register_operand" ""))
15396 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15397 "TARGET_USE_FANCY_MATH_387
15398 && TARGET_C99_FUNCTIONS
15399 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15401 rtx mask = GEN_INT (0x45);
15402 rtx val = GEN_INT (0x05);
15406 rtx scratch = gen_reg_rtx (HImode);
15407 rtx res = gen_reg_rtx (QImode);
15409 /* Remove excess precision by forcing value through memory. */
15410 if (memory_operand (operands[1], VOIDmode))
15411 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15414 enum ix86_stack_slot slot = (virtuals_instantiated
15417 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15419 emit_move_insn (temp, operands[1]);
15420 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15423 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15424 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15425 cond = gen_rtx_fmt_ee (EQ, QImode,
15426 gen_rtx_REG (CCmode, FLAGS_REG),
15428 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15429 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15433 (define_expand "signbitxf2"
15434 [(use (match_operand:SI 0 "register_operand" ""))
15435 (use (match_operand:XF 1 "register_operand" ""))]
15436 "TARGET_USE_FANCY_MATH_387"
15438 rtx scratch = gen_reg_rtx (HImode);
15440 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15441 emit_insn (gen_andsi3 (operands[0],
15442 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15446 (define_insn "movmsk_df"
15447 [(set (match_operand:SI 0 "register_operand" "=r")
15449 [(match_operand:DF 1 "register_operand" "x")]
15451 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15452 "%vmovmskpd\t{%1, %0|%0, %1}"
15453 [(set_attr "type" "ssemov")
15454 (set_attr "prefix" "maybe_vex")
15455 (set_attr "mode" "DF")])
15457 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15458 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15459 (define_expand "signbitdf2"
15460 [(use (match_operand:SI 0 "register_operand" ""))
15461 (use (match_operand:DF 1 "register_operand" ""))]
15462 "TARGET_USE_FANCY_MATH_387
15463 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15465 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15467 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15468 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15472 rtx scratch = gen_reg_rtx (HImode);
15474 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15475 emit_insn (gen_andsi3 (operands[0],
15476 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15481 (define_expand "signbitsf2"
15482 [(use (match_operand:SI 0 "register_operand" ""))
15483 (use (match_operand:SF 1 "register_operand" ""))]
15484 "TARGET_USE_FANCY_MATH_387
15485 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15487 rtx scratch = gen_reg_rtx (HImode);
15489 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15490 emit_insn (gen_andsi3 (operands[0],
15491 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15495 ;; Block operation instructions
15498 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15501 [(set_attr "length" "1")
15502 (set_attr "length_immediate" "0")
15503 (set_attr "modrm" "0")])
15505 (define_expand "movmem<mode>"
15506 [(use (match_operand:BLK 0 "memory_operand" ""))
15507 (use (match_operand:BLK 1 "memory_operand" ""))
15508 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15509 (use (match_operand:SWI48 3 "const_int_operand" ""))
15510 (use (match_operand:SI 4 "const_int_operand" ""))
15511 (use (match_operand:SI 5 "const_int_operand" ""))]
15514 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15515 operands[4], operands[5]))
15521 ;; Most CPUs don't like single string operations
15522 ;; Handle this case here to simplify previous expander.
15524 (define_expand "strmov"
15525 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15526 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15527 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15528 (clobber (reg:CC FLAGS_REG))])
15529 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15530 (clobber (reg:CC FLAGS_REG))])]
15533 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15535 /* If .md ever supports :P for Pmode, these can be directly
15536 in the pattern above. */
15537 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15538 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15540 /* Can't use this if the user has appropriated esi or edi. */
15541 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15542 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15544 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15545 operands[2], operands[3],
15546 operands[5], operands[6]));
15550 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15553 (define_expand "strmov_singleop"
15554 [(parallel [(set (match_operand 1 "memory_operand" "")
15555 (match_operand 3 "memory_operand" ""))
15556 (set (match_operand 0 "register_operand" "")
15557 (match_operand 4 "" ""))
15558 (set (match_operand 2 "register_operand" "")
15559 (match_operand 5 "" ""))])]
15561 "ix86_current_function_needs_cld = 1;")
15563 (define_insn "*strmovdi_rex_1"
15564 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15565 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15566 (set (match_operand:DI 0 "register_operand" "=D")
15567 (plus:DI (match_dup 2)
15569 (set (match_operand:DI 1 "register_operand" "=S")
15570 (plus:DI (match_dup 3)
15574 [(set_attr "type" "str")
15575 (set_attr "memory" "both")
15576 (set_attr "mode" "DI")])
15578 (define_insn "*strmovsi_1"
15579 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15580 (mem:SI (match_operand:P 3 "register_operand" "1")))
15581 (set (match_operand:P 0 "register_operand" "=D")
15582 (plus:P (match_dup 2)
15584 (set (match_operand:P 1 "register_operand" "=S")
15585 (plus:P (match_dup 3)
15589 [(set_attr "type" "str")
15590 (set_attr "memory" "both")
15591 (set_attr "mode" "SI")])
15593 (define_insn "*strmovhi_1"
15594 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15595 (mem:HI (match_operand:P 3 "register_operand" "1")))
15596 (set (match_operand:P 0 "register_operand" "=D")
15597 (plus:P (match_dup 2)
15599 (set (match_operand:P 1 "register_operand" "=S")
15600 (plus:P (match_dup 3)
15604 [(set_attr "type" "str")
15605 (set_attr "memory" "both")
15606 (set_attr "mode" "HI")])
15608 (define_insn "*strmovqi_1"
15609 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15610 (mem:QI (match_operand:P 3 "register_operand" "1")))
15611 (set (match_operand:P 0 "register_operand" "=D")
15612 (plus:P (match_dup 2)
15614 (set (match_operand:P 1 "register_operand" "=S")
15615 (plus:P (match_dup 3)
15619 [(set_attr "type" "str")
15620 (set_attr "memory" "both")
15621 (set (attr "prefix_rex")
15623 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15625 (const_string "*")))
15626 (set_attr "mode" "QI")])
15628 (define_expand "rep_mov"
15629 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15630 (set (match_operand 0 "register_operand" "")
15631 (match_operand 5 "" ""))
15632 (set (match_operand 2 "register_operand" "")
15633 (match_operand 6 "" ""))
15634 (set (match_operand 1 "memory_operand" "")
15635 (match_operand 3 "memory_operand" ""))
15636 (use (match_dup 4))])]
15638 "ix86_current_function_needs_cld = 1;")
15640 (define_insn "*rep_movdi_rex64"
15641 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15642 (set (match_operand:DI 0 "register_operand" "=D")
15643 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15645 (match_operand:DI 3 "register_operand" "0")))
15646 (set (match_operand:DI 1 "register_operand" "=S")
15647 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15648 (match_operand:DI 4 "register_operand" "1")))
15649 (set (mem:BLK (match_dup 3))
15650 (mem:BLK (match_dup 4)))
15651 (use (match_dup 5))]
15654 [(set_attr "type" "str")
15655 (set_attr "prefix_rep" "1")
15656 (set_attr "memory" "both")
15657 (set_attr "mode" "DI")])
15659 (define_insn "*rep_movsi"
15660 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15661 (set (match_operand:P 0 "register_operand" "=D")
15662 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15664 (match_operand:P 3 "register_operand" "0")))
15665 (set (match_operand:P 1 "register_operand" "=S")
15666 (plus:P (ashift:P (match_dup 5) (const_int 2))
15667 (match_operand:P 4 "register_operand" "1")))
15668 (set (mem:BLK (match_dup 3))
15669 (mem:BLK (match_dup 4)))
15670 (use (match_dup 5))]
15672 "rep{%;} movs{l|d}"
15673 [(set_attr "type" "str")
15674 (set_attr "prefix_rep" "1")
15675 (set_attr "memory" "both")
15676 (set_attr "mode" "SI")])
15678 (define_insn "*rep_movqi"
15679 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15680 (set (match_operand:P 0 "register_operand" "=D")
15681 (plus:P (match_operand:P 3 "register_operand" "0")
15682 (match_operand:P 5 "register_operand" "2")))
15683 (set (match_operand:P 1 "register_operand" "=S")
15684 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15685 (set (mem:BLK (match_dup 3))
15686 (mem:BLK (match_dup 4)))
15687 (use (match_dup 5))]
15690 [(set_attr "type" "str")
15691 (set_attr "prefix_rep" "1")
15692 (set_attr "memory" "both")
15693 (set_attr "mode" "QI")])
15695 (define_expand "setmem<mode>"
15696 [(use (match_operand:BLK 0 "memory_operand" ""))
15697 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15698 (use (match_operand:QI 2 "nonmemory_operand" ""))
15699 (use (match_operand 3 "const_int_operand" ""))
15700 (use (match_operand:SI 4 "const_int_operand" ""))
15701 (use (match_operand:SI 5 "const_int_operand" ""))]
15704 if (ix86_expand_setmem (operands[0], operands[1],
15705 operands[2], operands[3],
15706 operands[4], operands[5]))
15712 ;; Most CPUs don't like single string operations
15713 ;; Handle this case here to simplify previous expander.
15715 (define_expand "strset"
15716 [(set (match_operand 1 "memory_operand" "")
15717 (match_operand 2 "register_operand" ""))
15718 (parallel [(set (match_operand 0 "register_operand" "")
15720 (clobber (reg:CC FLAGS_REG))])]
15723 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15724 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15726 /* If .md ever supports :P for Pmode, this can be directly
15727 in the pattern above. */
15728 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15729 GEN_INT (GET_MODE_SIZE (GET_MODE
15731 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15733 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15739 (define_expand "strset_singleop"
15740 [(parallel [(set (match_operand 1 "memory_operand" "")
15741 (match_operand 2 "register_operand" ""))
15742 (set (match_operand 0 "register_operand" "")
15743 (match_operand 3 "" ""))])]
15745 "ix86_current_function_needs_cld = 1;")
15747 (define_insn "*strsetdi_rex_1"
15748 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15749 (match_operand:DI 2 "register_operand" "a"))
15750 (set (match_operand:DI 0 "register_operand" "=D")
15751 (plus:DI (match_dup 1)
15755 [(set_attr "type" "str")
15756 (set_attr "memory" "store")
15757 (set_attr "mode" "DI")])
15759 (define_insn "*strsetsi_1"
15760 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15761 (match_operand:SI 2 "register_operand" "a"))
15762 (set (match_operand:P 0 "register_operand" "=D")
15763 (plus:P (match_dup 1)
15767 [(set_attr "type" "str")
15768 (set_attr "memory" "store")
15769 (set_attr "mode" "SI")])
15771 (define_insn "*strsethi_1"
15772 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15773 (match_operand:HI 2 "register_operand" "a"))
15774 (set (match_operand:P 0 "register_operand" "=D")
15775 (plus:P (match_dup 1)
15779 [(set_attr "type" "str")
15780 (set_attr "memory" "store")
15781 (set_attr "mode" "HI")])
15783 (define_insn "*strsetqi_1"
15784 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15785 (match_operand:QI 2 "register_operand" "a"))
15786 (set (match_operand:P 0 "register_operand" "=D")
15787 (plus:P (match_dup 1)
15791 [(set_attr "type" "str")
15792 (set_attr "memory" "store")
15793 (set (attr "prefix_rex")
15795 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15797 (const_string "*")))
15798 (set_attr "mode" "QI")])
15800 (define_expand "rep_stos"
15801 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15802 (set (match_operand 0 "register_operand" "")
15803 (match_operand 4 "" ""))
15804 (set (match_operand 2 "memory_operand" "") (const_int 0))
15805 (use (match_operand 3 "register_operand" ""))
15806 (use (match_dup 1))])]
15808 "ix86_current_function_needs_cld = 1;")
15810 (define_insn "*rep_stosdi_rex64"
15811 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15812 (set (match_operand:DI 0 "register_operand" "=D")
15813 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15815 (match_operand:DI 3 "register_operand" "0")))
15816 (set (mem:BLK (match_dup 3))
15818 (use (match_operand:DI 2 "register_operand" "a"))
15819 (use (match_dup 4))]
15822 [(set_attr "type" "str")
15823 (set_attr "prefix_rep" "1")
15824 (set_attr "memory" "store")
15825 (set_attr "mode" "DI")])
15827 (define_insn "*rep_stossi"
15828 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15829 (set (match_operand:P 0 "register_operand" "=D")
15830 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15832 (match_operand:P 3 "register_operand" "0")))
15833 (set (mem:BLK (match_dup 3))
15835 (use (match_operand:SI 2 "register_operand" "a"))
15836 (use (match_dup 4))]
15838 "rep{%;} stos{l|d}"
15839 [(set_attr "type" "str")
15840 (set_attr "prefix_rep" "1")
15841 (set_attr "memory" "store")
15842 (set_attr "mode" "SI")])
15844 (define_insn "*rep_stosqi"
15845 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15846 (set (match_operand:P 0 "register_operand" "=D")
15847 (plus:P (match_operand:P 3 "register_operand" "0")
15848 (match_operand:P 4 "register_operand" "1")))
15849 (set (mem:BLK (match_dup 3))
15851 (use (match_operand:QI 2 "register_operand" "a"))
15852 (use (match_dup 4))]
15855 [(set_attr "type" "str")
15856 (set_attr "prefix_rep" "1")
15857 (set_attr "memory" "store")
15858 (set (attr "prefix_rex")
15860 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15862 (const_string "*")))
15863 (set_attr "mode" "QI")])
15865 (define_expand "cmpstrnsi"
15866 [(set (match_operand:SI 0 "register_operand" "")
15867 (compare:SI (match_operand:BLK 1 "general_operand" "")
15868 (match_operand:BLK 2 "general_operand" "")))
15869 (use (match_operand 3 "general_operand" ""))
15870 (use (match_operand 4 "immediate_operand" ""))]
15873 rtx addr1, addr2, out, outlow, count, countreg, align;
15875 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15878 /* Can't use this if the user has appropriated esi or edi. */
15879 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15884 out = gen_reg_rtx (SImode);
15886 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15887 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15888 if (addr1 != XEXP (operands[1], 0))
15889 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15890 if (addr2 != XEXP (operands[2], 0))
15891 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15893 count = operands[3];
15894 countreg = ix86_zero_extend_to_Pmode (count);
15896 /* %%% Iff we are testing strict equality, we can use known alignment
15897 to good advantage. This may be possible with combine, particularly
15898 once cc0 is dead. */
15899 align = operands[4];
15901 if (CONST_INT_P (count))
15903 if (INTVAL (count) == 0)
15905 emit_move_insn (operands[0], const0_rtx);
15908 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15909 operands[1], operands[2]));
15913 rtx (*gen_cmp) (rtx, rtx);
15915 gen_cmp = (TARGET_64BIT
15916 ? gen_cmpdi_1 : gen_cmpsi_1);
15918 emit_insn (gen_cmp (countreg, countreg));
15919 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15920 operands[1], operands[2]));
15923 outlow = gen_lowpart (QImode, out);
15924 emit_insn (gen_cmpintqi (outlow));
15925 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15927 if (operands[0] != out)
15928 emit_move_insn (operands[0], out);
15933 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15935 (define_expand "cmpintqi"
15936 [(set (match_dup 1)
15937 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15939 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15940 (parallel [(set (match_operand:QI 0 "register_operand" "")
15941 (minus:QI (match_dup 1)
15943 (clobber (reg:CC FLAGS_REG))])]
15946 operands[1] = gen_reg_rtx (QImode);
15947 operands[2] = gen_reg_rtx (QImode);
15950 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15951 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15953 (define_expand "cmpstrnqi_nz_1"
15954 [(parallel [(set (reg:CC FLAGS_REG)
15955 (compare:CC (match_operand 4 "memory_operand" "")
15956 (match_operand 5 "memory_operand" "")))
15957 (use (match_operand 2 "register_operand" ""))
15958 (use (match_operand:SI 3 "immediate_operand" ""))
15959 (clobber (match_operand 0 "register_operand" ""))
15960 (clobber (match_operand 1 "register_operand" ""))
15961 (clobber (match_dup 2))])]
15963 "ix86_current_function_needs_cld = 1;")
15965 (define_insn "*cmpstrnqi_nz_1"
15966 [(set (reg:CC FLAGS_REG)
15967 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15968 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15969 (use (match_operand:P 6 "register_operand" "2"))
15970 (use (match_operand:SI 3 "immediate_operand" "i"))
15971 (clobber (match_operand:P 0 "register_operand" "=S"))
15972 (clobber (match_operand:P 1 "register_operand" "=D"))
15973 (clobber (match_operand:P 2 "register_operand" "=c"))]
15976 [(set_attr "type" "str")
15977 (set_attr "mode" "QI")
15978 (set (attr "prefix_rex")
15980 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15982 (const_string "*")))
15983 (set_attr "prefix_rep" "1")])
15985 ;; The same, but the count is not known to not be zero.
15987 (define_expand "cmpstrnqi_1"
15988 [(parallel [(set (reg:CC FLAGS_REG)
15989 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15991 (compare:CC (match_operand 4 "memory_operand" "")
15992 (match_operand 5 "memory_operand" ""))
15994 (use (match_operand:SI 3 "immediate_operand" ""))
15995 (use (reg:CC FLAGS_REG))
15996 (clobber (match_operand 0 "register_operand" ""))
15997 (clobber (match_operand 1 "register_operand" ""))
15998 (clobber (match_dup 2))])]
16000 "ix86_current_function_needs_cld = 1;")
16002 (define_insn "*cmpstrnqi_1"
16003 [(set (reg:CC FLAGS_REG)
16004 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16006 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16007 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16009 (use (match_operand:SI 3 "immediate_operand" "i"))
16010 (use (reg:CC FLAGS_REG))
16011 (clobber (match_operand:P 0 "register_operand" "=S"))
16012 (clobber (match_operand:P 1 "register_operand" "=D"))
16013 (clobber (match_operand:P 2 "register_operand" "=c"))]
16016 [(set_attr "type" "str")
16017 (set_attr "mode" "QI")
16018 (set (attr "prefix_rex")
16020 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16022 (const_string "*")))
16023 (set_attr "prefix_rep" "1")])
16025 (define_expand "strlen<mode>"
16026 [(set (match_operand:SWI48x 0 "register_operand" "")
16027 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16028 (match_operand:QI 2 "immediate_operand" "")
16029 (match_operand 3 "immediate_operand" "")]
16033 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16039 (define_expand "strlenqi_1"
16040 [(parallel [(set (match_operand 0 "register_operand" "")
16041 (match_operand 2 "" ""))
16042 (clobber (match_operand 1 "register_operand" ""))
16043 (clobber (reg:CC FLAGS_REG))])]
16045 "ix86_current_function_needs_cld = 1;")
16047 (define_insn "*strlenqi_1"
16048 [(set (match_operand:P 0 "register_operand" "=&c")
16049 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16050 (match_operand:QI 2 "register_operand" "a")
16051 (match_operand:P 3 "immediate_operand" "i")
16052 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16053 (clobber (match_operand:P 1 "register_operand" "=D"))
16054 (clobber (reg:CC FLAGS_REG))]
16057 [(set_attr "type" "str")
16058 (set_attr "mode" "QI")
16059 (set (attr "prefix_rex")
16061 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16063 (const_string "*")))
16064 (set_attr "prefix_rep" "1")])
16066 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16067 ;; handled in combine, but it is not currently up to the task.
16068 ;; When used for their truth value, the cmpstrn* expanders generate
16077 ;; The intermediate three instructions are unnecessary.
16079 ;; This one handles cmpstrn*_nz_1...
16082 (set (reg:CC FLAGS_REG)
16083 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16084 (mem:BLK (match_operand 5 "register_operand" ""))))
16085 (use (match_operand 6 "register_operand" ""))
16086 (use (match_operand:SI 3 "immediate_operand" ""))
16087 (clobber (match_operand 0 "register_operand" ""))
16088 (clobber (match_operand 1 "register_operand" ""))
16089 (clobber (match_operand 2 "register_operand" ""))])
16090 (set (match_operand:QI 7 "register_operand" "")
16091 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16092 (set (match_operand:QI 8 "register_operand" "")
16093 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16094 (set (reg FLAGS_REG)
16095 (compare (match_dup 7) (match_dup 8)))
16097 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16099 (set (reg:CC FLAGS_REG)
16100 (compare:CC (mem:BLK (match_dup 4))
16101 (mem:BLK (match_dup 5))))
16102 (use (match_dup 6))
16103 (use (match_dup 3))
16104 (clobber (match_dup 0))
16105 (clobber (match_dup 1))
16106 (clobber (match_dup 2))])])
16108 ;; ...and this one handles cmpstrn*_1.
16111 (set (reg:CC FLAGS_REG)
16112 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16114 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16115 (mem:BLK (match_operand 5 "register_operand" "")))
16117 (use (match_operand:SI 3 "immediate_operand" ""))
16118 (use (reg:CC FLAGS_REG))
16119 (clobber (match_operand 0 "register_operand" ""))
16120 (clobber (match_operand 1 "register_operand" ""))
16121 (clobber (match_operand 2 "register_operand" ""))])
16122 (set (match_operand:QI 7 "register_operand" "")
16123 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16124 (set (match_operand:QI 8 "register_operand" "")
16125 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16126 (set (reg FLAGS_REG)
16127 (compare (match_dup 7) (match_dup 8)))
16129 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16131 (set (reg:CC FLAGS_REG)
16132 (if_then_else:CC (ne (match_dup 6)
16134 (compare:CC (mem:BLK (match_dup 4))
16135 (mem:BLK (match_dup 5)))
16137 (use (match_dup 3))
16138 (use (reg:CC FLAGS_REG))
16139 (clobber (match_dup 0))
16140 (clobber (match_dup 1))
16141 (clobber (match_dup 2))])])
16143 ;; Conditional move instructions.
16145 (define_expand "mov<mode>cc"
16146 [(set (match_operand:SWIM 0 "register_operand" "")
16147 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16148 (match_operand:SWIM 2 "general_operand" "")
16149 (match_operand:SWIM 3 "general_operand" "")))]
16151 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16153 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16154 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16155 ;; So just document what we're doing explicitly.
16157 (define_expand "x86_mov<mode>cc_0_m1"
16159 [(set (match_operand:SWI48 0 "register_operand" "")
16160 (if_then_else:SWI48
16161 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16162 [(match_operand 1 "flags_reg_operand" "")
16166 (clobber (reg:CC FLAGS_REG))])])
16168 (define_insn "*x86_mov<mode>cc_0_m1"
16169 [(set (match_operand:SWI48 0 "register_operand" "=r")
16170 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16171 [(reg FLAGS_REG) (const_int 0)])
16174 (clobber (reg:CC FLAGS_REG))]
16176 "sbb{<imodesuffix>}\t%0, %0"
16177 ; Since we don't have the proper number of operands for an alu insn,
16178 ; fill in all the blanks.
16179 [(set_attr "type" "alu")
16180 (set_attr "use_carry" "1")
16181 (set_attr "pent_pair" "pu")
16182 (set_attr "memory" "none")
16183 (set_attr "imm_disp" "false")
16184 (set_attr "mode" "<MODE>")
16185 (set_attr "length_immediate" "0")])
16187 (define_insn "*x86_mov<mode>cc_0_m1_se"
16188 [(set (match_operand:SWI48 0 "register_operand" "=r")
16189 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16190 [(reg FLAGS_REG) (const_int 0)])
16193 (clobber (reg:CC FLAGS_REG))]
16195 "sbb{<imodesuffix>}\t%0, %0"
16196 [(set_attr "type" "alu")
16197 (set_attr "use_carry" "1")
16198 (set_attr "pent_pair" "pu")
16199 (set_attr "memory" "none")
16200 (set_attr "imm_disp" "false")
16201 (set_attr "mode" "<MODE>")
16202 (set_attr "length_immediate" "0")])
16204 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16205 [(set (match_operand:SWI48 0 "register_operand" "=r")
16206 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16207 [(reg FLAGS_REG) (const_int 0)])))]
16209 "sbb{<imodesuffix>}\t%0, %0"
16210 [(set_attr "type" "alu")
16211 (set_attr "use_carry" "1")
16212 (set_attr "pent_pair" "pu")
16213 (set_attr "memory" "none")
16214 (set_attr "imm_disp" "false")
16215 (set_attr "mode" "<MODE>")
16216 (set_attr "length_immediate" "0")])
16218 (define_insn "*mov<mode>cc_noc"
16219 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16220 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16221 [(reg FLAGS_REG) (const_int 0)])
16222 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16223 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16224 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16226 cmov%O2%C1\t{%2, %0|%0, %2}
16227 cmov%O2%c1\t{%3, %0|%0, %3}"
16228 [(set_attr "type" "icmov")
16229 (set_attr "mode" "<MODE>")])
16231 (define_insn_and_split "*movqicc_noc"
16232 [(set (match_operand:QI 0 "register_operand" "=r,r")
16233 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16234 [(match_operand 4 "flags_reg_operand" "")
16236 (match_operand:QI 2 "register_operand" "r,0")
16237 (match_operand:QI 3 "register_operand" "0,r")))]
16238 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16240 "&& reload_completed"
16241 [(set (match_dup 0)
16242 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16245 "operands[0] = gen_lowpart (SImode, operands[0]);
16246 operands[2] = gen_lowpart (SImode, operands[2]);
16247 operands[3] = gen_lowpart (SImode, operands[3]);"
16248 [(set_attr "type" "icmov")
16249 (set_attr "mode" "SI")])
16251 (define_expand "mov<mode>cc"
16252 [(set (match_operand:X87MODEF 0 "register_operand" "")
16253 (if_then_else:X87MODEF
16254 (match_operand 1 "ix86_fp_comparison_operator" "")
16255 (match_operand:X87MODEF 2 "register_operand" "")
16256 (match_operand:X87MODEF 3 "register_operand" "")))]
16257 "(TARGET_80387 && TARGET_CMOVE)
16258 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16259 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16261 (define_insn "*movxfcc_1"
16262 [(set (match_operand:XF 0 "register_operand" "=f,f")
16263 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16264 [(reg FLAGS_REG) (const_int 0)])
16265 (match_operand:XF 2 "register_operand" "f,0")
16266 (match_operand:XF 3 "register_operand" "0,f")))]
16267 "TARGET_80387 && TARGET_CMOVE"
16269 fcmov%F1\t{%2, %0|%0, %2}
16270 fcmov%f1\t{%3, %0|%0, %3}"
16271 [(set_attr "type" "fcmov")
16272 (set_attr "mode" "XF")])
16274 (define_insn "*movdfcc_1_rex64"
16275 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16276 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16277 [(reg FLAGS_REG) (const_int 0)])
16278 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16279 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16280 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16281 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16283 fcmov%F1\t{%2, %0|%0, %2}
16284 fcmov%f1\t{%3, %0|%0, %3}
16285 cmov%O2%C1\t{%2, %0|%0, %2}
16286 cmov%O2%c1\t{%3, %0|%0, %3}"
16287 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16288 (set_attr "mode" "DF,DF,DI,DI")])
16290 (define_insn "*movdfcc_1"
16291 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16292 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16293 [(reg FLAGS_REG) (const_int 0)])
16294 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16295 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16296 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16297 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16299 fcmov%F1\t{%2, %0|%0, %2}
16300 fcmov%f1\t{%3, %0|%0, %3}
16303 [(set_attr "type" "fcmov,fcmov,multi,multi")
16304 (set_attr "mode" "DF,DF,DI,DI")])
16307 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16308 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16309 [(match_operand 4 "flags_reg_operand" "")
16311 (match_operand:DF 2 "nonimmediate_operand" "")
16312 (match_operand:DF 3 "nonimmediate_operand" "")))]
16313 "!TARGET_64BIT && reload_completed"
16314 [(set (match_dup 2)
16315 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16319 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16323 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16324 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16327 (define_insn "*movsfcc_1_387"
16328 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16329 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16330 [(reg FLAGS_REG) (const_int 0)])
16331 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16332 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16333 "TARGET_80387 && TARGET_CMOVE
16334 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16336 fcmov%F1\t{%2, %0|%0, %2}
16337 fcmov%f1\t{%3, %0|%0, %3}
16338 cmov%O2%C1\t{%2, %0|%0, %2}
16339 cmov%O2%c1\t{%3, %0|%0, %3}"
16340 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16341 (set_attr "mode" "SF,SF,SI,SI")])
16343 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16344 ;; the scalar versions to have only XMM registers as operands.
16346 ;; XOP conditional move
16347 (define_insn "*xop_pcmov_<mode>"
16348 [(set (match_operand:MODEF 0 "register_operand" "=x")
16349 (if_then_else:MODEF
16350 (match_operand:MODEF 1 "register_operand" "x")
16351 (match_operand:MODEF 2 "register_operand" "x")
16352 (match_operand:MODEF 3 "register_operand" "x")))]
16354 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16355 [(set_attr "type" "sse4arg")])
16357 ;; These versions of the min/max patterns are intentionally ignorant of
16358 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16359 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16360 ;; are undefined in this condition, we're certain this is correct.
16362 (define_insn "<code><mode>3"
16363 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16365 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16366 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16367 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16369 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16370 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16371 [(set_attr "isa" "noavx,avx")
16372 (set_attr "prefix" "orig,vex")
16373 (set_attr "type" "sseadd")
16374 (set_attr "mode" "<MODE>")])
16376 ;; These versions of the min/max patterns implement exactly the operations
16377 ;; min = (op1 < op2 ? op1 : op2)
16378 ;; max = (!(op1 < op2) ? op1 : op2)
16379 ;; Their operands are not commutative, and thus they may be used in the
16380 ;; presence of -0.0 and NaN.
16382 (define_insn "*ieee_smin<mode>3"
16383 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16385 [(match_operand:MODEF 1 "register_operand" "0,x")
16386 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16388 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16390 min<ssemodesuffix>\t{%2, %0|%0, %2}
16391 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16392 [(set_attr "isa" "noavx,avx")
16393 (set_attr "prefix" "orig,vex")
16394 (set_attr "type" "sseadd")
16395 (set_attr "mode" "<MODE>")])
16397 (define_insn "*ieee_smax<mode>3"
16398 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16400 [(match_operand:MODEF 1 "register_operand" "0,x")
16401 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16403 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16405 max<ssemodesuffix>\t{%2, %0|%0, %2}
16406 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16407 [(set_attr "isa" "noavx,avx")
16408 (set_attr "prefix" "orig,vex")
16409 (set_attr "type" "sseadd")
16410 (set_attr "mode" "<MODE>")])
16412 ;; Make two stack loads independent:
16414 ;; fld %st(0) -> fld bb
16415 ;; fmul bb fmul %st(1), %st
16417 ;; Actually we only match the last two instructions for simplicity.
16419 [(set (match_operand 0 "fp_register_operand" "")
16420 (match_operand 1 "fp_register_operand" ""))
16422 (match_operator 2 "binary_fp_operator"
16424 (match_operand 3 "memory_operand" "")]))]
16425 "REGNO (operands[0]) != REGNO (operands[1])"
16426 [(set (match_dup 0) (match_dup 3))
16427 (set (match_dup 0) (match_dup 4))]
16429 ;; The % modifier is not operational anymore in peephole2's, so we have to
16430 ;; swap the operands manually in the case of addition and multiplication.
16431 "if (COMMUTATIVE_ARITH_P (operands[2]))
16432 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16433 GET_MODE (operands[2]),
16434 operands[0], operands[1]);
16436 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16437 GET_MODE (operands[2]),
16438 operands[1], operands[0]);")
16440 ;; Conditional addition patterns
16441 (define_expand "add<mode>cc"
16442 [(match_operand:SWI 0 "register_operand" "")
16443 (match_operand 1 "ordered_comparison_operator" "")
16444 (match_operand:SWI 2 "register_operand" "")
16445 (match_operand:SWI 3 "const_int_operand" "")]
16447 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16449 ;; Misc patterns (?)
16451 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16452 ;; Otherwise there will be nothing to keep
16454 ;; [(set (reg ebp) (reg esp))]
16455 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16456 ;; (clobber (eflags)]
16457 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16459 ;; in proper program order.
16461 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16462 [(set (match_operand:P 0 "register_operand" "=r,r")
16463 (plus:P (match_operand:P 1 "register_operand" "0,r")
16464 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16465 (clobber (reg:CC FLAGS_REG))
16466 (clobber (mem:BLK (scratch)))]
16469 switch (get_attr_type (insn))
16472 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16475 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16476 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16477 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16479 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16482 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16483 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16486 [(set (attr "type")
16487 (cond [(and (eq_attr "alternative" "0")
16488 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16489 (const_string "alu")
16490 (match_operand:<MODE> 2 "const0_operand" "")
16491 (const_string "imov")
16493 (const_string "lea")))
16494 (set (attr "length_immediate")
16495 (cond [(eq_attr "type" "imov")
16497 (and (eq_attr "type" "alu")
16498 (match_operand 2 "const128_operand" ""))
16501 (const_string "*")))
16502 (set_attr "mode" "<MODE>")])
16504 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16505 [(set (match_operand:P 0 "register_operand" "=r")
16506 (minus:P (match_operand:P 1 "register_operand" "0")
16507 (match_operand:P 2 "register_operand" "r")))
16508 (clobber (reg:CC FLAGS_REG))
16509 (clobber (mem:BLK (scratch)))]
16511 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16512 [(set_attr "type" "alu")
16513 (set_attr "mode" "<MODE>")])
16515 (define_insn "allocate_stack_worker_probe_<mode>"
16516 [(set (match_operand:P 0 "register_operand" "=a")
16517 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16518 UNSPECV_STACK_PROBE))
16519 (clobber (reg:CC FLAGS_REG))]
16520 "ix86_target_stack_probe ()"
16521 "call\t___chkstk_ms"
16522 [(set_attr "type" "multi")
16523 (set_attr "length" "5")])
16525 (define_expand "allocate_stack"
16526 [(match_operand 0 "register_operand" "")
16527 (match_operand 1 "general_operand" "")]
16528 "ix86_target_stack_probe ()"
16532 #ifndef CHECK_STACK_LIMIT
16533 #define CHECK_STACK_LIMIT 0
16536 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16537 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16539 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16540 stack_pointer_rtx, 0, OPTAB_DIRECT);
16541 if (x != stack_pointer_rtx)
16542 emit_move_insn (stack_pointer_rtx, x);
16546 x = copy_to_mode_reg (Pmode, operands[1]);
16548 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16550 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16551 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16552 stack_pointer_rtx, 0, OPTAB_DIRECT);
16553 if (x != stack_pointer_rtx)
16554 emit_move_insn (stack_pointer_rtx, x);
16557 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16561 ;; Use IOR for stack probes, this is shorter.
16562 (define_expand "probe_stack"
16563 [(match_operand 0 "memory_operand" "")]
16566 rtx (*gen_ior3) (rtx, rtx, rtx);
16568 gen_ior3 = (GET_MODE (operands[0]) == DImode
16569 ? gen_iordi3 : gen_iorsi3);
16571 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16575 (define_insn "adjust_stack_and_probe<mode>"
16576 [(set (match_operand:P 0 "register_operand" "=r")
16577 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16578 UNSPECV_PROBE_STACK_RANGE))
16579 (set (reg:P SP_REG)
16580 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16581 (clobber (reg:CC FLAGS_REG))
16582 (clobber (mem:BLK (scratch)))]
16584 "* return output_adjust_stack_and_probe (operands[0]);"
16585 [(set_attr "type" "multi")])
16587 (define_insn "probe_stack_range<mode>"
16588 [(set (match_operand:P 0 "register_operand" "=r")
16589 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16590 (match_operand:P 2 "const_int_operand" "n")]
16591 UNSPECV_PROBE_STACK_RANGE))
16592 (clobber (reg:CC FLAGS_REG))]
16594 "* return output_probe_stack_range (operands[0], operands[2]);"
16595 [(set_attr "type" "multi")])
16597 (define_expand "builtin_setjmp_receiver"
16598 [(label_ref (match_operand 0 "" ""))]
16599 "!TARGET_64BIT && flag_pic"
16605 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16606 rtx label_rtx = gen_label_rtx ();
16607 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16608 xops[0] = xops[1] = picreg;
16609 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16610 ix86_expand_binary_operator (MINUS, SImode, xops);
16614 emit_insn (gen_set_got (pic_offset_table_rtx));
16618 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16621 [(set (match_operand 0 "register_operand" "")
16622 (match_operator 3 "promotable_binary_operator"
16623 [(match_operand 1 "register_operand" "")
16624 (match_operand 2 "aligned_operand" "")]))
16625 (clobber (reg:CC FLAGS_REG))]
16626 "! TARGET_PARTIAL_REG_STALL && reload_completed
16627 && ((GET_MODE (operands[0]) == HImode
16628 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16629 /* ??? next two lines just !satisfies_constraint_K (...) */
16630 || !CONST_INT_P (operands[2])
16631 || satisfies_constraint_K (operands[2])))
16632 || (GET_MODE (operands[0]) == QImode
16633 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16634 [(parallel [(set (match_dup 0)
16635 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16636 (clobber (reg:CC FLAGS_REG))])]
16637 "operands[0] = gen_lowpart (SImode, operands[0]);
16638 operands[1] = gen_lowpart (SImode, operands[1]);
16639 if (GET_CODE (operands[3]) != ASHIFT)
16640 operands[2] = gen_lowpart (SImode, operands[2]);
16641 PUT_MODE (operands[3], SImode);")
16643 ; Promote the QImode tests, as i386 has encoding of the AND
16644 ; instruction with 32-bit sign-extended immediate and thus the
16645 ; instruction size is unchanged, except in the %eax case for
16646 ; which it is increased by one byte, hence the ! optimize_size.
16648 [(set (match_operand 0 "flags_reg_operand" "")
16649 (match_operator 2 "compare_operator"
16650 [(and (match_operand 3 "aligned_operand" "")
16651 (match_operand 4 "const_int_operand" ""))
16653 (set (match_operand 1 "register_operand" "")
16654 (and (match_dup 3) (match_dup 4)))]
16655 "! TARGET_PARTIAL_REG_STALL && reload_completed
16656 && optimize_insn_for_speed_p ()
16657 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16658 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16659 /* Ensure that the operand will remain sign-extended immediate. */
16660 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16661 [(parallel [(set (match_dup 0)
16662 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16665 (and:SI (match_dup 3) (match_dup 4)))])]
16668 = gen_int_mode (INTVAL (operands[4])
16669 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16670 operands[1] = gen_lowpart (SImode, operands[1]);
16671 operands[3] = gen_lowpart (SImode, operands[3]);
16674 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16675 ; the TEST instruction with 32-bit sign-extended immediate and thus
16676 ; the instruction size would at least double, which is not what we
16677 ; want even with ! optimize_size.
16679 [(set (match_operand 0 "flags_reg_operand" "")
16680 (match_operator 1 "compare_operator"
16681 [(and (match_operand:HI 2 "aligned_operand" "")
16682 (match_operand:HI 3 "const_int_operand" ""))
16684 "! TARGET_PARTIAL_REG_STALL && reload_completed
16685 && ! TARGET_FAST_PREFIX
16686 && optimize_insn_for_speed_p ()
16687 /* Ensure that the operand will remain sign-extended immediate. */
16688 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16689 [(set (match_dup 0)
16690 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16694 = gen_int_mode (INTVAL (operands[3])
16695 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16696 operands[2] = gen_lowpart (SImode, operands[2]);
16700 [(set (match_operand 0 "register_operand" "")
16701 (neg (match_operand 1 "register_operand" "")))
16702 (clobber (reg:CC FLAGS_REG))]
16703 "! TARGET_PARTIAL_REG_STALL && reload_completed
16704 && (GET_MODE (operands[0]) == HImode
16705 || (GET_MODE (operands[0]) == QImode
16706 && (TARGET_PROMOTE_QImode
16707 || optimize_insn_for_size_p ())))"
16708 [(parallel [(set (match_dup 0)
16709 (neg:SI (match_dup 1)))
16710 (clobber (reg:CC FLAGS_REG))])]
16711 "operands[0] = gen_lowpart (SImode, operands[0]);
16712 operands[1] = gen_lowpart (SImode, operands[1]);")
16715 [(set (match_operand 0 "register_operand" "")
16716 (not (match_operand 1 "register_operand" "")))]
16717 "! TARGET_PARTIAL_REG_STALL && reload_completed
16718 && (GET_MODE (operands[0]) == HImode
16719 || (GET_MODE (operands[0]) == QImode
16720 && (TARGET_PROMOTE_QImode
16721 || optimize_insn_for_size_p ())))"
16722 [(set (match_dup 0)
16723 (not:SI (match_dup 1)))]
16724 "operands[0] = gen_lowpart (SImode, operands[0]);
16725 operands[1] = gen_lowpart (SImode, operands[1]);")
16728 [(set (match_operand 0 "register_operand" "")
16729 (if_then_else (match_operator 1 "ordered_comparison_operator"
16730 [(reg FLAGS_REG) (const_int 0)])
16731 (match_operand 2 "register_operand" "")
16732 (match_operand 3 "register_operand" "")))]
16733 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16734 && (GET_MODE (operands[0]) == HImode
16735 || (GET_MODE (operands[0]) == QImode
16736 && (TARGET_PROMOTE_QImode
16737 || optimize_insn_for_size_p ())))"
16738 [(set (match_dup 0)
16739 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16740 "operands[0] = gen_lowpart (SImode, operands[0]);
16741 operands[2] = gen_lowpart (SImode, operands[2]);
16742 operands[3] = gen_lowpart (SImode, operands[3]);")
16744 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16745 ;; transform a complex memory operation into two memory to register operations.
16747 ;; Don't push memory operands
16749 [(set (match_operand:SWI 0 "push_operand" "")
16750 (match_operand:SWI 1 "memory_operand" ""))
16751 (match_scratch:SWI 2 "<r>")]
16752 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16753 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16754 [(set (match_dup 2) (match_dup 1))
16755 (set (match_dup 0) (match_dup 2))])
16757 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16760 [(set (match_operand:SF 0 "push_operand" "")
16761 (match_operand:SF 1 "memory_operand" ""))
16762 (match_scratch:SF 2 "r")]
16763 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16764 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16765 [(set (match_dup 2) (match_dup 1))
16766 (set (match_dup 0) (match_dup 2))])
16768 ;; Don't move an immediate directly to memory when the instruction
16771 [(match_scratch:SWI124 1 "<r>")
16772 (set (match_operand:SWI124 0 "memory_operand" "")
16774 "optimize_insn_for_speed_p ()
16775 && !TARGET_USE_MOV0
16776 && TARGET_SPLIT_LONG_MOVES
16777 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16778 && peep2_regno_dead_p (0, FLAGS_REG)"
16779 [(parallel [(set (match_dup 2) (const_int 0))
16780 (clobber (reg:CC FLAGS_REG))])
16781 (set (match_dup 0) (match_dup 1))]
16782 "operands[2] = gen_lowpart (SImode, operands[1]);")
16785 [(match_scratch:SWI124 2 "<r>")
16786 (set (match_operand:SWI124 0 "memory_operand" "")
16787 (match_operand:SWI124 1 "immediate_operand" ""))]
16788 "optimize_insn_for_speed_p ()
16789 && TARGET_SPLIT_LONG_MOVES
16790 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16791 [(set (match_dup 2) (match_dup 1))
16792 (set (match_dup 0) (match_dup 2))])
16794 ;; Don't compare memory with zero, load and use a test instead.
16796 [(set (match_operand 0 "flags_reg_operand" "")
16797 (match_operator 1 "compare_operator"
16798 [(match_operand:SI 2 "memory_operand" "")
16800 (match_scratch:SI 3 "r")]
16801 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16802 [(set (match_dup 3) (match_dup 2))
16803 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16805 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16806 ;; Don't split NOTs with a displacement operand, because resulting XOR
16807 ;; will not be pairable anyway.
16809 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16810 ;; represented using a modRM byte. The XOR replacement is long decoded,
16811 ;; so this split helps here as well.
16813 ;; Note: Can't do this as a regular split because we can't get proper
16814 ;; lifetime information then.
16817 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16818 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16819 "optimize_insn_for_speed_p ()
16820 && ((TARGET_NOT_UNPAIRABLE
16821 && (!MEM_P (operands[0])
16822 || !memory_displacement_operand (operands[0], <MODE>mode)))
16823 || (TARGET_NOT_VECTORMODE
16824 && long_memory_operand (operands[0], <MODE>mode)))
16825 && peep2_regno_dead_p (0, FLAGS_REG)"
16826 [(parallel [(set (match_dup 0)
16827 (xor:SWI124 (match_dup 1) (const_int -1)))
16828 (clobber (reg:CC FLAGS_REG))])])
16830 ;; Non pairable "test imm, reg" instructions can be translated to
16831 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16832 ;; byte opcode instead of two, have a short form for byte operands),
16833 ;; so do it for other CPUs as well. Given that the value was dead,
16834 ;; this should not create any new dependencies. Pass on the sub-word
16835 ;; versions if we're concerned about partial register stalls.
16838 [(set (match_operand 0 "flags_reg_operand" "")
16839 (match_operator 1 "compare_operator"
16840 [(and:SI (match_operand:SI 2 "register_operand" "")
16841 (match_operand:SI 3 "immediate_operand" ""))
16843 "ix86_match_ccmode (insn, CCNOmode)
16844 && (true_regnum (operands[2]) != AX_REG
16845 || satisfies_constraint_K (operands[3]))
16846 && peep2_reg_dead_p (1, operands[2])"
16848 [(set (match_dup 0)
16849 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16852 (and:SI (match_dup 2) (match_dup 3)))])])
16854 ;; We don't need to handle HImode case, because it will be promoted to SImode
16855 ;; on ! TARGET_PARTIAL_REG_STALL
16858 [(set (match_operand 0 "flags_reg_operand" "")
16859 (match_operator 1 "compare_operator"
16860 [(and:QI (match_operand:QI 2 "register_operand" "")
16861 (match_operand:QI 3 "immediate_operand" ""))
16863 "! TARGET_PARTIAL_REG_STALL
16864 && ix86_match_ccmode (insn, CCNOmode)
16865 && true_regnum (operands[2]) != AX_REG
16866 && peep2_reg_dead_p (1, operands[2])"
16868 [(set (match_dup 0)
16869 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16872 (and:QI (match_dup 2) (match_dup 3)))])])
16875 [(set (match_operand 0 "flags_reg_operand" "")
16876 (match_operator 1 "compare_operator"
16879 (match_operand 2 "ext_register_operand" "")
16882 (match_operand 3 "const_int_operand" ""))
16884 "! TARGET_PARTIAL_REG_STALL
16885 && ix86_match_ccmode (insn, CCNOmode)
16886 && true_regnum (operands[2]) != AX_REG
16887 && peep2_reg_dead_p (1, operands[2])"
16888 [(parallel [(set (match_dup 0)
16897 (set (zero_extract:SI (match_dup 2)
16905 (match_dup 3)))])])
16907 ;; Don't do logical operations with memory inputs.
16909 [(match_scratch:SI 2 "r")
16910 (parallel [(set (match_operand:SI 0 "register_operand" "")
16911 (match_operator:SI 3 "arith_or_logical_operator"
16913 (match_operand:SI 1 "memory_operand" "")]))
16914 (clobber (reg:CC FLAGS_REG))])]
16915 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16916 [(set (match_dup 2) (match_dup 1))
16917 (parallel [(set (match_dup 0)
16918 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16919 (clobber (reg:CC FLAGS_REG))])])
16922 [(match_scratch:SI 2 "r")
16923 (parallel [(set (match_operand:SI 0 "register_operand" "")
16924 (match_operator:SI 3 "arith_or_logical_operator"
16925 [(match_operand:SI 1 "memory_operand" "")
16927 (clobber (reg:CC FLAGS_REG))])]
16928 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16929 [(set (match_dup 2) (match_dup 1))
16930 (parallel [(set (match_dup 0)
16931 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16932 (clobber (reg:CC FLAGS_REG))])])
16934 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16935 ;; refers to the destination of the load!
16938 [(set (match_operand:SI 0 "register_operand" "")
16939 (match_operand:SI 1 "register_operand" ""))
16940 (parallel [(set (match_dup 0)
16941 (match_operator:SI 3 "commutative_operator"
16943 (match_operand:SI 2 "memory_operand" "")]))
16944 (clobber (reg:CC FLAGS_REG))])]
16945 "REGNO (operands[0]) != REGNO (operands[1])
16946 && GENERAL_REGNO_P (REGNO (operands[0]))
16947 && GENERAL_REGNO_P (REGNO (operands[1]))"
16948 [(set (match_dup 0) (match_dup 4))
16949 (parallel [(set (match_dup 0)
16950 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16951 (clobber (reg:CC FLAGS_REG))])]
16952 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16955 [(set (match_operand 0 "register_operand" "")
16956 (match_operand 1 "register_operand" ""))
16958 (match_operator 3 "commutative_operator"
16960 (match_operand 2 "memory_operand" "")]))]
16961 "REGNO (operands[0]) != REGNO (operands[1])
16962 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16963 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16964 [(set (match_dup 0) (match_dup 2))
16966 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16968 ; Don't do logical operations with memory outputs
16970 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16971 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16972 ; the same decoder scheduling characteristics as the original.
16975 [(match_scratch:SI 2 "r")
16976 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16977 (match_operator:SI 3 "arith_or_logical_operator"
16979 (match_operand:SI 1 "nonmemory_operand" "")]))
16980 (clobber (reg:CC FLAGS_REG))])]
16981 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16982 /* Do not split stack checking probes. */
16983 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16984 [(set (match_dup 2) (match_dup 0))
16985 (parallel [(set (match_dup 2)
16986 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16987 (clobber (reg:CC FLAGS_REG))])
16988 (set (match_dup 0) (match_dup 2))])
16991 [(match_scratch:SI 2 "r")
16992 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16993 (match_operator:SI 3 "arith_or_logical_operator"
16994 [(match_operand:SI 1 "nonmemory_operand" "")
16996 (clobber (reg:CC FLAGS_REG))])]
16997 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16998 /* Do not split stack checking probes. */
16999 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17000 [(set (match_dup 2) (match_dup 0))
17001 (parallel [(set (match_dup 2)
17002 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17003 (clobber (reg:CC FLAGS_REG))])
17004 (set (match_dup 0) (match_dup 2))])
17006 ;; Attempt to always use XOR for zeroing registers.
17008 [(set (match_operand 0 "register_operand" "")
17009 (match_operand 1 "const0_operand" ""))]
17010 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17011 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17012 && GENERAL_REG_P (operands[0])
17013 && peep2_regno_dead_p (0, FLAGS_REG)"
17014 [(parallel [(set (match_dup 0) (const_int 0))
17015 (clobber (reg:CC FLAGS_REG))])]
17016 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17019 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17021 "(GET_MODE (operands[0]) == QImode
17022 || GET_MODE (operands[0]) == HImode)
17023 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17024 && peep2_regno_dead_p (0, FLAGS_REG)"
17025 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17026 (clobber (reg:CC FLAGS_REG))])])
17028 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17030 [(set (match_operand:SWI248 0 "register_operand" "")
17032 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17033 && peep2_regno_dead_p (0, FLAGS_REG)"
17034 [(parallel [(set (match_dup 0) (const_int -1))
17035 (clobber (reg:CC FLAGS_REG))])]
17037 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17038 operands[0] = gen_lowpart (SImode, operands[0]);
17041 ;; Attempt to convert simple lea to add/shift.
17042 ;; These can be created by move expanders.
17045 [(set (match_operand:SWI48 0 "register_operand" "")
17046 (plus:SWI48 (match_dup 0)
17047 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17048 "peep2_regno_dead_p (0, FLAGS_REG)"
17049 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17050 (clobber (reg:CC FLAGS_REG))])])
17053 [(set (match_operand:SI 0 "register_operand" "")
17054 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17055 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17057 && peep2_regno_dead_p (0, FLAGS_REG)
17058 && REGNO (operands[0]) == REGNO (operands[1])"
17059 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17060 (clobber (reg:CC FLAGS_REG))])]
17061 "operands[2] = gen_lowpart (SImode, operands[2]);")
17064 [(set (match_operand:SWI48 0 "register_operand" "")
17065 (mult:SWI48 (match_dup 0)
17066 (match_operand:SWI48 1 "const_int_operand" "")))]
17067 "exact_log2 (INTVAL (operands[1])) >= 0
17068 && peep2_regno_dead_p (0, FLAGS_REG)"
17069 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17070 (clobber (reg:CC FLAGS_REG))])]
17071 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17074 [(set (match_operand:SI 0 "register_operand" "")
17075 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17076 (match_operand:DI 2 "const_int_operand" "")) 0))]
17078 && exact_log2 (INTVAL (operands[2])) >= 0
17079 && REGNO (operands[0]) == REGNO (operands[1])
17080 && peep2_regno_dead_p (0, FLAGS_REG)"
17081 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17082 (clobber (reg:CC FLAGS_REG))])]
17083 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17085 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17086 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17087 ;; On many CPUs it is also faster, since special hardware to avoid esp
17088 ;; dependencies is present.
17090 ;; While some of these conversions may be done using splitters, we use
17091 ;; peepholes in order to allow combine_stack_adjustments pass to see
17092 ;; nonobfuscated RTL.
17094 ;; Convert prologue esp subtractions to push.
17095 ;; We need register to push. In order to keep verify_flow_info happy we have
17097 ;; - use scratch and clobber it in order to avoid dependencies
17098 ;; - use already live register
17099 ;; We can't use the second way right now, since there is no reliable way how to
17100 ;; verify that given register is live. First choice will also most likely in
17101 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17102 ;; call clobbered registers are dead. We may want to use base pointer as an
17103 ;; alternative when no register is available later.
17106 [(match_scratch:P 1 "r")
17107 (parallel [(set (reg:P SP_REG)
17108 (plus:P (reg:P SP_REG)
17109 (match_operand:P 0 "const_int_operand" "")))
17110 (clobber (reg:CC FLAGS_REG))
17111 (clobber (mem:BLK (scratch)))])]
17112 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17113 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17114 [(clobber (match_dup 1))
17115 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17116 (clobber (mem:BLK (scratch)))])])
17119 [(match_scratch:P 1 "r")
17120 (parallel [(set (reg:P SP_REG)
17121 (plus:P (reg:P SP_REG)
17122 (match_operand:P 0 "const_int_operand" "")))
17123 (clobber (reg:CC FLAGS_REG))
17124 (clobber (mem:BLK (scratch)))])]
17125 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17126 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17127 [(clobber (match_dup 1))
17128 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17129 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17130 (clobber (mem:BLK (scratch)))])])
17132 ;; Convert esp subtractions to push.
17134 [(match_scratch:P 1 "r")
17135 (parallel [(set (reg:P SP_REG)
17136 (plus:P (reg:P SP_REG)
17137 (match_operand:P 0 "const_int_operand" "")))
17138 (clobber (reg:CC FLAGS_REG))])]
17139 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17140 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17141 [(clobber (match_dup 1))
17142 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17145 [(match_scratch:P 1 "r")
17146 (parallel [(set (reg:P SP_REG)
17147 (plus:P (reg:P SP_REG)
17148 (match_operand:P 0 "const_int_operand" "")))
17149 (clobber (reg:CC FLAGS_REG))])]
17150 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17151 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17152 [(clobber (match_dup 1))
17153 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17154 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17156 ;; Convert epilogue deallocator to pop.
17158 [(match_scratch:P 1 "r")
17159 (parallel [(set (reg:P SP_REG)
17160 (plus:P (reg:P SP_REG)
17161 (match_operand:P 0 "const_int_operand" "")))
17162 (clobber (reg:CC FLAGS_REG))
17163 (clobber (mem:BLK (scratch)))])]
17164 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17165 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17166 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17167 (clobber (mem:BLK (scratch)))])])
17169 ;; Two pops case is tricky, since pop causes dependency
17170 ;; on destination register. We use two registers if available.
17172 [(match_scratch:P 1 "r")
17173 (match_scratch:P 2 "r")
17174 (parallel [(set (reg:P SP_REG)
17175 (plus:P (reg:P SP_REG)
17176 (match_operand:P 0 "const_int_operand" "")))
17177 (clobber (reg:CC FLAGS_REG))
17178 (clobber (mem:BLK (scratch)))])]
17179 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17180 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17181 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17182 (clobber (mem:BLK (scratch)))])
17183 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17186 [(match_scratch:P 1 "r")
17187 (parallel [(set (reg:P SP_REG)
17188 (plus:P (reg:P SP_REG)
17189 (match_operand:P 0 "const_int_operand" "")))
17190 (clobber (reg:CC FLAGS_REG))
17191 (clobber (mem:BLK (scratch)))])]
17192 "optimize_insn_for_size_p ()
17193 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17194 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17195 (clobber (mem:BLK (scratch)))])
17196 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17198 ;; Convert esp additions to pop.
17200 [(match_scratch:P 1 "r")
17201 (parallel [(set (reg:P SP_REG)
17202 (plus:P (reg:P SP_REG)
17203 (match_operand:P 0 "const_int_operand" "")))
17204 (clobber (reg:CC FLAGS_REG))])]
17205 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17206 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17208 ;; Two pops case is tricky, since pop causes dependency
17209 ;; on destination register. We use two registers if available.
17211 [(match_scratch:P 1 "r")
17212 (match_scratch:P 2 "r")
17213 (parallel [(set (reg:P SP_REG)
17214 (plus:P (reg:P SP_REG)
17215 (match_operand:P 0 "const_int_operand" "")))
17216 (clobber (reg:CC FLAGS_REG))])]
17217 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17218 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17219 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17222 [(match_scratch:P 1 "r")
17223 (parallel [(set (reg:P SP_REG)
17224 (plus:P (reg:P SP_REG)
17225 (match_operand:P 0 "const_int_operand" "")))
17226 (clobber (reg:CC FLAGS_REG))])]
17227 "optimize_insn_for_size_p ()
17228 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17229 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17230 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17232 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17233 ;; required and register dies. Similarly for 128 to -128.
17235 [(set (match_operand 0 "flags_reg_operand" "")
17236 (match_operator 1 "compare_operator"
17237 [(match_operand 2 "register_operand" "")
17238 (match_operand 3 "const_int_operand" "")]))]
17239 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17240 && incdec_operand (operands[3], GET_MODE (operands[3])))
17241 || (!TARGET_FUSE_CMP_AND_BRANCH
17242 && INTVAL (operands[3]) == 128))
17243 && ix86_match_ccmode (insn, CCGCmode)
17244 && peep2_reg_dead_p (1, operands[2])"
17245 [(parallel [(set (match_dup 0)
17246 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17247 (clobber (match_dup 2))])])
17249 ;; Convert imul by three, five and nine into lea
17252 [(set (match_operand:SWI48 0 "register_operand" "")
17253 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17254 (match_operand:SWI48 2 "const_int_operand" "")))
17255 (clobber (reg:CC FLAGS_REG))])]
17256 "INTVAL (operands[2]) == 3
17257 || INTVAL (operands[2]) == 5
17258 || INTVAL (operands[2]) == 9"
17259 [(set (match_dup 0)
17260 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17262 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17266 [(set (match_operand:SWI48 0 "register_operand" "")
17267 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17268 (match_operand:SWI48 2 "const_int_operand" "")))
17269 (clobber (reg:CC FLAGS_REG))])]
17270 "optimize_insn_for_speed_p ()
17271 && (INTVAL (operands[2]) == 3
17272 || INTVAL (operands[2]) == 5
17273 || INTVAL (operands[2]) == 9)"
17274 [(set (match_dup 0) (match_dup 1))
17276 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17278 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17280 ;; imul $32bit_imm, mem, reg is vector decoded, while
17281 ;; imul $32bit_imm, reg, reg is direct decoded.
17283 [(match_scratch:SWI48 3 "r")
17284 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17285 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17286 (match_operand:SWI48 2 "immediate_operand" "")))
17287 (clobber (reg:CC FLAGS_REG))])]
17288 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17289 && !satisfies_constraint_K (operands[2])"
17290 [(set (match_dup 3) (match_dup 1))
17291 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17292 (clobber (reg:CC FLAGS_REG))])])
17295 [(match_scratch:SI 3 "r")
17296 (parallel [(set (match_operand:DI 0 "register_operand" "")
17298 (mult:SI (match_operand:SI 1 "memory_operand" "")
17299 (match_operand:SI 2 "immediate_operand" ""))))
17300 (clobber (reg:CC FLAGS_REG))])]
17302 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17303 && !satisfies_constraint_K (operands[2])"
17304 [(set (match_dup 3) (match_dup 1))
17305 (parallel [(set (match_dup 0)
17306 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17307 (clobber (reg:CC FLAGS_REG))])])
17309 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17310 ;; Convert it into imul reg, reg
17311 ;; It would be better to force assembler to encode instruction using long
17312 ;; immediate, but there is apparently no way to do so.
17314 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17316 (match_operand:SWI248 1 "nonimmediate_operand" "")
17317 (match_operand:SWI248 2 "const_int_operand" "")))
17318 (clobber (reg:CC FLAGS_REG))])
17319 (match_scratch:SWI248 3 "r")]
17320 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17321 && satisfies_constraint_K (operands[2])"
17322 [(set (match_dup 3) (match_dup 2))
17323 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17324 (clobber (reg:CC FLAGS_REG))])]
17326 if (!rtx_equal_p (operands[0], operands[1]))
17327 emit_move_insn (operands[0], operands[1]);
17330 ;; After splitting up read-modify operations, array accesses with memory
17331 ;; operands might end up in form:
17333 ;; movl 4(%esp), %edx
17335 ;; instead of pre-splitting:
17337 ;; addl 4(%esp), %eax
17339 ;; movl 4(%esp), %edx
17340 ;; leal (%edx,%eax,4), %eax
17343 [(match_scratch:P 5 "r")
17344 (parallel [(set (match_operand 0 "register_operand" "")
17345 (ashift (match_operand 1 "register_operand" "")
17346 (match_operand 2 "const_int_operand" "")))
17347 (clobber (reg:CC FLAGS_REG))])
17348 (parallel [(set (match_operand 3 "register_operand" "")
17349 (plus (match_dup 0)
17350 (match_operand 4 "x86_64_general_operand" "")))
17351 (clobber (reg:CC FLAGS_REG))])]
17352 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17353 /* Validate MODE for lea. */
17354 && ((!TARGET_PARTIAL_REG_STALL
17355 && (GET_MODE (operands[0]) == QImode
17356 || GET_MODE (operands[0]) == HImode))
17357 || GET_MODE (operands[0]) == SImode
17358 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17359 && (rtx_equal_p (operands[0], operands[3])
17360 || peep2_reg_dead_p (2, operands[0]))
17361 /* We reorder load and the shift. */
17362 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17363 [(set (match_dup 5) (match_dup 4))
17364 (set (match_dup 0) (match_dup 1))]
17366 enum machine_mode op1mode = GET_MODE (operands[1]);
17367 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17368 int scale = 1 << INTVAL (operands[2]);
17369 rtx index = gen_lowpart (Pmode, operands[1]);
17370 rtx base = gen_lowpart (Pmode, operands[5]);
17371 rtx dest = gen_lowpart (mode, operands[3]);
17373 operands[1] = gen_rtx_PLUS (Pmode, base,
17374 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17375 operands[5] = base;
17377 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17378 if (op1mode != Pmode)
17379 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17380 operands[0] = dest;
17383 ;; Call-value patterns last so that the wildcard operand does not
17384 ;; disrupt insn-recog's switch tables.
17386 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17388 [(set (match_operand 0 "" "")
17389 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17390 (match_operand:SI 2 "" "")))
17391 (set (reg:SI SP_REG)
17392 (plus:SI (reg:SI SP_REG)
17393 (match_operand:SI 3 "immediate_operand" "")))])
17394 (unspec [(match_operand 4 "const_int_operand" "")]
17395 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17396 "TARGET_VZEROUPPER && !TARGET_64BIT"
17398 "&& reload_completed"
17400 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17401 [(set_attr "type" "callv")])
17403 (define_insn "*call_value_pop_0"
17404 [(set (match_operand 0 "" "")
17405 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17406 (match_operand:SI 2 "" "")))
17407 (set (reg:SI SP_REG)
17408 (plus:SI (reg:SI SP_REG)
17409 (match_operand:SI 3 "immediate_operand" "")))]
17411 { return ix86_output_call_insn (insn, operands[1], 1); }
17412 [(set_attr "type" "callv")])
17414 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17416 [(set (match_operand 0 "" "")
17417 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17418 (match_operand:SI 2 "" "")))
17419 (set (reg:SI SP_REG)
17420 (plus:SI (reg:SI SP_REG)
17421 (match_operand:SI 3 "immediate_operand" "i")))])
17422 (unspec [(match_operand 4 "const_int_operand" "")]
17423 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17424 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17426 "&& reload_completed"
17428 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17429 [(set_attr "type" "callv")])
17431 (define_insn "*call_value_pop_1"
17432 [(set (match_operand 0 "" "")
17433 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17434 (match_operand:SI 2 "" "")))
17435 (set (reg:SI SP_REG)
17436 (plus:SI (reg:SI SP_REG)
17437 (match_operand:SI 3 "immediate_operand" "i")))]
17438 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17439 { return ix86_output_call_insn (insn, operands[1], 1); }
17440 [(set_attr "type" "callv")])
17442 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17444 [(set (match_operand 0 "" "")
17445 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17446 (match_operand:SI 2 "" "")))
17447 (set (reg:SI SP_REG)
17448 (plus:SI (reg:SI SP_REG)
17449 (match_operand:SI 3 "immediate_operand" "i,i")))])
17450 (unspec [(match_operand 4 "const_int_operand" "")]
17451 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17452 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17454 "&& reload_completed"
17456 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17457 [(set_attr "type" "callv")])
17459 (define_insn "*sibcall_value_pop_1"
17460 [(set (match_operand 0 "" "")
17461 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17462 (match_operand:SI 2 "" "")))
17463 (set (reg:SI SP_REG)
17464 (plus:SI (reg:SI SP_REG)
17465 (match_operand:SI 3 "immediate_operand" "i,i")))]
17466 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17467 { return ix86_output_call_insn (insn, operands[1], 1); }
17468 [(set_attr "type" "callv")])
17470 (define_insn_and_split "*call_value_0_vzeroupper"
17471 [(set (match_operand 0 "" "")
17472 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17473 (match_operand:SI 2 "" "")))
17474 (unspec [(match_operand 3 "const_int_operand" "")]
17475 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17476 "TARGET_VZEROUPPER && !TARGET_64BIT"
17478 "&& reload_completed"
17480 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17481 [(set_attr "type" "callv")])
17483 (define_insn "*call_value_0"
17484 [(set (match_operand 0 "" "")
17485 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17486 (match_operand:SI 2 "" "")))]
17488 { return ix86_output_call_insn (insn, operands[1], 1); }
17489 [(set_attr "type" "callv")])
17491 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17492 [(set (match_operand 0 "" "")
17493 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17494 (match_operand:DI 2 "const_int_operand" "")))
17495 (unspec [(match_operand 3 "const_int_operand" "")]
17496 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17497 "TARGET_VZEROUPPER && TARGET_64BIT"
17499 "&& reload_completed"
17501 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17502 [(set_attr "type" "callv")])
17504 (define_insn "*call_value_0_rex64"
17505 [(set (match_operand 0 "" "")
17506 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17507 (match_operand:DI 2 "const_int_operand" "")))]
17509 { return ix86_output_call_insn (insn, operands[1], 1); }
17510 [(set_attr "type" "callv")])
17512 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17514 [(set (match_operand 0 "" "")
17515 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17516 (match_operand:DI 2 "const_int_operand" "")))
17517 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17518 (clobber (reg:TI XMM6_REG))
17519 (clobber (reg:TI XMM7_REG))
17520 (clobber (reg:TI XMM8_REG))
17521 (clobber (reg:TI XMM9_REG))
17522 (clobber (reg:TI XMM10_REG))
17523 (clobber (reg:TI XMM11_REG))
17524 (clobber (reg:TI XMM12_REG))
17525 (clobber (reg:TI XMM13_REG))
17526 (clobber (reg:TI XMM14_REG))
17527 (clobber (reg:TI XMM15_REG))
17528 (clobber (reg:DI SI_REG))
17529 (clobber (reg:DI DI_REG))])
17530 (unspec [(match_operand 3 "const_int_operand" "")]
17531 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17532 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17534 "&& reload_completed"
17536 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17537 [(set_attr "type" "callv")])
17539 (define_insn "*call_value_0_rex64_ms_sysv"
17540 [(set (match_operand 0 "" "")
17541 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17542 (match_operand:DI 2 "const_int_operand" "")))
17543 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17544 (clobber (reg:TI XMM6_REG))
17545 (clobber (reg:TI XMM7_REG))
17546 (clobber (reg:TI XMM8_REG))
17547 (clobber (reg:TI XMM9_REG))
17548 (clobber (reg:TI XMM10_REG))
17549 (clobber (reg:TI XMM11_REG))
17550 (clobber (reg:TI XMM12_REG))
17551 (clobber (reg:TI XMM13_REG))
17552 (clobber (reg:TI XMM14_REG))
17553 (clobber (reg:TI XMM15_REG))
17554 (clobber (reg:DI SI_REG))
17555 (clobber (reg:DI DI_REG))]
17556 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17557 { return ix86_output_call_insn (insn, operands[1], 1); }
17558 [(set_attr "type" "callv")])
17560 (define_insn_and_split "*call_value_1_vzeroupper"
17561 [(set (match_operand 0 "" "")
17562 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17563 (match_operand:SI 2 "" "")))
17564 (unspec [(match_operand 3 "const_int_operand" "")]
17565 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17566 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17568 "&& reload_completed"
17570 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17571 [(set_attr "type" "callv")])
17573 (define_insn "*call_value_1"
17574 [(set (match_operand 0 "" "")
17575 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17576 (match_operand:SI 2 "" "")))]
17577 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17578 { return ix86_output_call_insn (insn, operands[1], 1); }
17579 [(set_attr "type" "callv")])
17581 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17582 [(set (match_operand 0 "" "")
17583 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17584 (match_operand:SI 2 "" "")))
17585 (unspec [(match_operand 3 "const_int_operand" "")]
17586 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17587 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17589 "&& reload_completed"
17591 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17592 [(set_attr "type" "callv")])
17594 (define_insn "*sibcall_value_1"
17595 [(set (match_operand 0 "" "")
17596 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17597 (match_operand:SI 2 "" "")))]
17598 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17599 { return ix86_output_call_insn (insn, operands[1], 1); }
17600 [(set_attr "type" "callv")])
17602 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17603 [(set (match_operand 0 "" "")
17604 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17605 (match_operand:DI 2 "" "")))
17606 (unspec [(match_operand 3 "const_int_operand" "")]
17607 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17608 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17609 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17611 "&& reload_completed"
17613 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17614 [(set_attr "type" "callv")])
17616 (define_insn "*call_value_1_rex64"
17617 [(set (match_operand 0 "" "")
17618 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17619 (match_operand:DI 2 "" "")))]
17620 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17621 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17622 { return ix86_output_call_insn (insn, operands[1], 1); }
17623 [(set_attr "type" "callv")])
17625 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17627 [(set (match_operand 0 "" "")
17628 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17629 (match_operand:DI 2 "" "")))
17630 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17631 (clobber (reg:TI XMM6_REG))
17632 (clobber (reg:TI XMM7_REG))
17633 (clobber (reg:TI XMM8_REG))
17634 (clobber (reg:TI XMM9_REG))
17635 (clobber (reg:TI XMM10_REG))
17636 (clobber (reg:TI XMM11_REG))
17637 (clobber (reg:TI XMM12_REG))
17638 (clobber (reg:TI XMM13_REG))
17639 (clobber (reg:TI XMM14_REG))
17640 (clobber (reg:TI XMM15_REG))
17641 (clobber (reg:DI SI_REG))
17642 (clobber (reg:DI DI_REG))])
17643 (unspec [(match_operand 3 "const_int_operand" "")]
17644 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17645 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17647 "&& reload_completed"
17649 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17650 [(set_attr "type" "callv")])
17652 (define_insn "*call_value_1_rex64_ms_sysv"
17653 [(set (match_operand 0 "" "")
17654 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17655 (match_operand:DI 2 "" "")))
17656 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17657 (clobber (reg:TI XMM6_REG))
17658 (clobber (reg:TI XMM7_REG))
17659 (clobber (reg:TI XMM8_REG))
17660 (clobber (reg:TI XMM9_REG))
17661 (clobber (reg:TI XMM10_REG))
17662 (clobber (reg:TI XMM11_REG))
17663 (clobber (reg:TI XMM12_REG))
17664 (clobber (reg:TI XMM13_REG))
17665 (clobber (reg:TI XMM14_REG))
17666 (clobber (reg:TI XMM15_REG))
17667 (clobber (reg:DI SI_REG))
17668 (clobber (reg:DI DI_REG))]
17669 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17670 { return ix86_output_call_insn (insn, operands[1], 1); }
17671 [(set_attr "type" "callv")])
17673 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17674 [(set (match_operand 0 "" "")
17675 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17676 (match_operand:DI 2 "" "")))
17677 (unspec [(match_operand 3 "const_int_operand" "")]
17678 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17679 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17681 "&& reload_completed"
17683 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17684 [(set_attr "type" "callv")])
17686 (define_insn "*call_value_1_rex64_large"
17687 [(set (match_operand 0 "" "")
17688 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17689 (match_operand:DI 2 "" "")))]
17690 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17691 { return ix86_output_call_insn (insn, operands[1], 1); }
17692 [(set_attr "type" "callv")])
17694 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17695 [(set (match_operand 0 "" "")
17696 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17697 (match_operand:DI 2 "" "")))
17698 (unspec [(match_operand 3 "const_int_operand" "")]
17699 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17700 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17702 "&& reload_completed"
17704 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17705 [(set_attr "type" "callv")])
17707 (define_insn "*sibcall_value_1_rex64"
17708 [(set (match_operand 0 "" "")
17709 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17710 (match_operand:DI 2 "" "")))]
17711 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17712 { return ix86_output_call_insn (insn, operands[1], 1); }
17713 [(set_attr "type" "callv")])
17715 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17716 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17717 ;; caught for use by garbage collectors and the like. Using an insn that
17718 ;; maps to SIGILL makes it more likely the program will rightfully die.
17719 ;; Keeping with tradition, "6" is in honor of #UD.
17720 (define_insn "trap"
17721 [(trap_if (const_int 1) (const_int 6))]
17723 { return ASM_SHORT "0x0b0f"; }
17724 [(set_attr "length" "2")])
17726 (define_expand "prefetch"
17727 [(prefetch (match_operand 0 "address_operand" "")
17728 (match_operand:SI 1 "const_int_operand" "")
17729 (match_operand:SI 2 "const_int_operand" ""))]
17730 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17732 int rw = INTVAL (operands[1]);
17733 int locality = INTVAL (operands[2]);
17735 gcc_assert (rw == 0 || rw == 1);
17736 gcc_assert (locality >= 0 && locality <= 3);
17737 gcc_assert (GET_MODE (operands[0]) == Pmode
17738 || GET_MODE (operands[0]) == VOIDmode);
17740 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17741 supported by SSE counterpart or the SSE prefetch is not available
17742 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17744 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17745 operands[2] = GEN_INT (3);
17747 operands[1] = const0_rtx;
17750 (define_insn "*prefetch_sse_<mode>"
17751 [(prefetch (match_operand:P 0 "address_operand" "p")
17753 (match_operand:SI 1 "const_int_operand" ""))]
17754 "TARGET_PREFETCH_SSE"
17756 static const char * const patterns[4] = {
17757 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17760 int locality = INTVAL (operands[1]);
17761 gcc_assert (locality >= 0 && locality <= 3);
17763 return patterns[locality];
17765 [(set_attr "type" "sse")
17766 (set_attr "atom_sse_attr" "prefetch")
17767 (set (attr "length_address")
17768 (symbol_ref "memory_address_length (operands[0])"))
17769 (set_attr "memory" "none")])
17771 (define_insn "*prefetch_3dnow_<mode>"
17772 [(prefetch (match_operand:P 0 "address_operand" "p")
17773 (match_operand:SI 1 "const_int_operand" "n")
17777 if (INTVAL (operands[1]) == 0)
17778 return "prefetch\t%a0";
17780 return "prefetchw\t%a0";
17782 [(set_attr "type" "mmx")
17783 (set (attr "length_address")
17784 (symbol_ref "memory_address_length (operands[0])"))
17785 (set_attr "memory" "none")])
17787 (define_expand "stack_protect_set"
17788 [(match_operand 0 "memory_operand" "")
17789 (match_operand 1 "memory_operand" "")]
17792 rtx (*insn)(rtx, rtx);
17794 #ifdef TARGET_THREAD_SSP_OFFSET
17795 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17796 insn = (TARGET_64BIT
17797 ? gen_stack_tls_protect_set_di
17798 : gen_stack_tls_protect_set_si);
17800 insn = (TARGET_64BIT
17801 ? gen_stack_protect_set_di
17802 : gen_stack_protect_set_si);
17805 emit_insn (insn (operands[0], operands[1]));
17809 (define_insn "stack_protect_set_<mode>"
17810 [(set (match_operand:P 0 "memory_operand" "=m")
17811 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17812 (set (match_scratch:P 2 "=&r") (const_int 0))
17813 (clobber (reg:CC FLAGS_REG))]
17815 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17816 [(set_attr "type" "multi")])
17818 (define_insn "stack_tls_protect_set_<mode>"
17819 [(set (match_operand:P 0 "memory_operand" "=m")
17820 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17821 UNSPEC_SP_TLS_SET))
17822 (set (match_scratch:P 2 "=&r") (const_int 0))
17823 (clobber (reg:CC FLAGS_REG))]
17825 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17826 [(set_attr "type" "multi")])
17828 (define_expand "stack_protect_test"
17829 [(match_operand 0 "memory_operand" "")
17830 (match_operand 1 "memory_operand" "")
17831 (match_operand 2 "" "")]
17834 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17836 rtx (*insn)(rtx, rtx, rtx);
17838 #ifdef TARGET_THREAD_SSP_OFFSET
17839 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17840 insn = (TARGET_64BIT
17841 ? gen_stack_tls_protect_test_di
17842 : gen_stack_tls_protect_test_si);
17844 insn = (TARGET_64BIT
17845 ? gen_stack_protect_test_di
17846 : gen_stack_protect_test_si);
17849 emit_insn (insn (flags, operands[0], operands[1]));
17851 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17852 flags, const0_rtx, operands[2]));
17856 (define_insn "stack_protect_test_<mode>"
17857 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17858 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17859 (match_operand:P 2 "memory_operand" "m")]
17861 (clobber (match_scratch:P 3 "=&r"))]
17863 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17864 [(set_attr "type" "multi")])
17866 (define_insn "stack_tls_protect_test_<mode>"
17867 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17868 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17869 (match_operand:P 2 "const_int_operand" "i")]
17870 UNSPEC_SP_TLS_TEST))
17871 (clobber (match_scratch:P 3 "=r"))]
17873 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17874 [(set_attr "type" "multi")])
17876 (define_insn "sse4_2_crc32<mode>"
17877 [(set (match_operand:SI 0 "register_operand" "=r")
17879 [(match_operand:SI 1 "register_operand" "0")
17880 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17882 "TARGET_SSE4_2 || TARGET_CRC32"
17883 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17884 [(set_attr "type" "sselog1")
17885 (set_attr "prefix_rep" "1")
17886 (set_attr "prefix_extra" "1")
17887 (set (attr "prefix_data16")
17888 (if_then_else (match_operand:HI 2 "" "")
17890 (const_string "*")))
17891 (set (attr "prefix_rex")
17892 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17894 (const_string "*")))
17895 (set_attr "mode" "SI")])
17897 (define_insn "sse4_2_crc32di"
17898 [(set (match_operand:DI 0 "register_operand" "=r")
17900 [(match_operand:DI 1 "register_operand" "0")
17901 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17903 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17904 "crc32{q}\t{%2, %0|%0, %2}"
17905 [(set_attr "type" "sselog1")
17906 (set_attr "prefix_rep" "1")
17907 (set_attr "prefix_extra" "1")
17908 (set_attr "mode" "DI")])
17910 (define_expand "rdpmc"
17911 [(match_operand:DI 0 "register_operand" "")
17912 (match_operand:SI 1 "register_operand" "")]
17915 rtx reg = gen_reg_rtx (DImode);
17918 /* Force operand 1 into ECX. */
17919 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17920 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17921 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17926 rtvec vec = rtvec_alloc (2);
17927 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17928 rtx upper = gen_reg_rtx (DImode);
17929 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17930 gen_rtvec (1, const0_rtx),
17932 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17933 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17935 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17936 NULL, 1, OPTAB_DIRECT);
17937 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17941 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17942 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17946 (define_insn "*rdpmc"
17947 [(set (match_operand:DI 0 "register_operand" "=A")
17948 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17952 [(set_attr "type" "other")
17953 (set_attr "length" "2")])
17955 (define_insn "*rdpmc_rex64"
17956 [(set (match_operand:DI 0 "register_operand" "=a")
17957 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17959 (set (match_operand:DI 1 "register_operand" "=d")
17960 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17963 [(set_attr "type" "other")
17964 (set_attr "length" "2")])
17966 (define_expand "rdtsc"
17967 [(set (match_operand:DI 0 "register_operand" "")
17968 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17973 rtvec vec = rtvec_alloc (2);
17974 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17975 rtx upper = gen_reg_rtx (DImode);
17976 rtx lower = gen_reg_rtx (DImode);
17977 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17978 gen_rtvec (1, const0_rtx),
17980 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17981 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17983 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17984 NULL, 1, OPTAB_DIRECT);
17985 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17987 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17992 (define_insn "*rdtsc"
17993 [(set (match_operand:DI 0 "register_operand" "=A")
17994 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17997 [(set_attr "type" "other")
17998 (set_attr "length" "2")])
18000 (define_insn "*rdtsc_rex64"
18001 [(set (match_operand:DI 0 "register_operand" "=a")
18002 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18003 (set (match_operand:DI 1 "register_operand" "=d")
18004 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18007 [(set_attr "type" "other")
18008 (set_attr "length" "2")])
18010 (define_expand "rdtscp"
18011 [(match_operand:DI 0 "register_operand" "")
18012 (match_operand:SI 1 "memory_operand" "")]
18015 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18016 gen_rtvec (1, const0_rtx),
18018 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18019 gen_rtvec (1, const0_rtx),
18021 rtx reg = gen_reg_rtx (DImode);
18022 rtx tmp = gen_reg_rtx (SImode);
18026 rtvec vec = rtvec_alloc (3);
18027 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18028 rtx upper = gen_reg_rtx (DImode);
18029 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18030 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18031 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18033 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18034 NULL, 1, OPTAB_DIRECT);
18035 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18040 rtvec vec = rtvec_alloc (2);
18041 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18042 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18043 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18046 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18047 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18051 (define_insn "*rdtscp"
18052 [(set (match_operand:DI 0 "register_operand" "=A")
18053 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18054 (set (match_operand:SI 1 "register_operand" "=c")
18055 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18058 [(set_attr "type" "other")
18059 (set_attr "length" "3")])
18061 (define_insn "*rdtscp_rex64"
18062 [(set (match_operand:DI 0 "register_operand" "=a")
18063 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18064 (set (match_operand:DI 1 "register_operand" "=d")
18065 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18066 (set (match_operand:SI 2 "register_operand" "=c")
18067 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18070 [(set_attr "type" "other")
18071 (set_attr "length" "3")])
18073 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18075 ;; LWP instructions
18077 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18079 (define_expand "lwp_llwpcb"
18080 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18081 UNSPECV_LLWP_INTRINSIC)]
18084 (define_insn "*lwp_llwpcb<mode>1"
18085 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18086 UNSPECV_LLWP_INTRINSIC)]
18089 [(set_attr "type" "lwp")
18090 (set_attr "mode" "<MODE>")
18091 (set_attr "length" "5")])
18093 (define_expand "lwp_slwpcb"
18094 [(set (match_operand 0 "register_operand" "=r")
18095 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18100 insn = (TARGET_64BIT
18102 : gen_lwp_slwpcbsi);
18104 emit_insn (insn (operands[0]));
18108 (define_insn "lwp_slwpcb<mode>"
18109 [(set (match_operand:P 0 "register_operand" "=r")
18110 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18113 [(set_attr "type" "lwp")
18114 (set_attr "mode" "<MODE>")
18115 (set_attr "length" "5")])
18117 (define_expand "lwp_lwpval<mode>3"
18118 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18119 (match_operand:SI 2 "nonimmediate_operand" "rm")
18120 (match_operand:SI 3 "const_int_operand" "i")]
18121 UNSPECV_LWPVAL_INTRINSIC)]
18123 "/* Avoid unused variable warning. */
18126 (define_insn "*lwp_lwpval<mode>3_1"
18127 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18128 (match_operand:SI 1 "nonimmediate_operand" "rm")
18129 (match_operand:SI 2 "const_int_operand" "i")]
18130 UNSPECV_LWPVAL_INTRINSIC)]
18132 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18133 [(set_attr "type" "lwp")
18134 (set_attr "mode" "<MODE>")
18135 (set (attr "length")
18136 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18138 (define_expand "lwp_lwpins<mode>3"
18139 [(set (reg:CCC FLAGS_REG)
18140 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18141 (match_operand:SI 2 "nonimmediate_operand" "rm")
18142 (match_operand:SI 3 "const_int_operand" "i")]
18143 UNSPECV_LWPINS_INTRINSIC))
18144 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18145 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18148 (define_insn "*lwp_lwpins<mode>3_1"
18149 [(set (reg:CCC FLAGS_REG)
18150 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18151 (match_operand:SI 1 "nonimmediate_operand" "rm")
18152 (match_operand:SI 2 "const_int_operand" "i")]
18153 UNSPECV_LWPINS_INTRINSIC))]
18155 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18156 [(set_attr "type" "lwp")
18157 (set_attr "mode" "<MODE>")
18158 (set (attr "length")
18159 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18161 (define_insn "rdfsbase<mode>"
18162 [(set (match_operand:SWI48 0 "register_operand" "=r")
18163 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18164 "TARGET_64BIT && TARGET_FSGSBASE"
18166 [(set_attr "type" "other")
18167 (set_attr "prefix_extra" "2")])
18169 (define_insn "rdgsbase<mode>"
18170 [(set (match_operand:SWI48 0 "register_operand" "=r")
18171 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18172 "TARGET_64BIT && TARGET_FSGSBASE"
18174 [(set_attr "type" "other")
18175 (set_attr "prefix_extra" "2")])
18177 (define_insn "wrfsbase<mode>"
18178 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18180 "TARGET_64BIT && TARGET_FSGSBASE"
18182 [(set_attr "type" "other")
18183 (set_attr "prefix_extra" "2")])
18185 (define_insn "wrgsbase<mode>"
18186 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18188 "TARGET_64BIT && TARGET_FSGSBASE"
18190 [(set_attr "type" "other")
18191 (set_attr "prefix_extra" "2")])
18193 (define_insn "rdrand<mode>_1"
18194 [(set (match_operand:SWI248 0 "register_operand" "=r")
18195 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18196 (set (reg:CCC FLAGS_REG)
18197 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18200 [(set_attr "type" "other")
18201 (set_attr "prefix_extra" "1")])
18205 (include "sync.md")