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 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2706 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2707 ;; On the average, pushdf using integers can be still shorter.
2709 (define_insn "*pushdf"
2710 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2711 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2714 /* This insn should be already split before reg-stack. */
2717 [(set_attr "type" "multi")
2718 (set_attr "unit" "i387,*,*")
2719 (set_attr "mode" "DF,SI,DF")])
2721 ;; %%% Kill this when call knows how to work this out.
2723 [(set (match_operand:DF 0 "push_operand" "")
2724 (match_operand:DF 1 "any_fp_register_operand" ""))]
2726 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2727 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2730 [(set (match_operand:DF 0 "push_operand" "")
2731 (match_operand:DF 1 "general_operand" ""))]
2733 && !ANY_FP_REG_P (operands[1])"
2735 "ix86_split_long_move (operands); DONE;")
2737 (define_insn "*pushsf_rex64"
2738 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2739 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2742 /* Anything else should be already split before reg-stack. */
2743 gcc_assert (which_alternative == 1);
2744 return "push{q}\t%q1";
2746 [(set_attr "type" "multi,push,multi")
2747 (set_attr "unit" "i387,*,*")
2748 (set_attr "mode" "SF,DI,SF")])
2750 (define_insn "*pushsf"
2751 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2752 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2755 /* Anything else should be already split before reg-stack. */
2756 gcc_assert (which_alternative == 1);
2757 return "push{l}\t%1";
2759 [(set_attr "type" "multi,push,multi")
2760 (set_attr "unit" "i387,*,*")
2761 (set_attr "mode" "SF,SI,SF")])
2764 [(set (match_operand:SF 0 "push_operand" "")
2765 (match_operand:SF 1 "memory_operand" ""))]
2767 && MEM_P (operands[1])
2768 && (operands[2] = find_constant_src (insn))"
2772 ;; %%% Kill this when call knows how to work this out.
2774 [(set (match_operand:SF 0 "push_operand" "")
2775 (match_operand:SF 1 "any_fp_register_operand" ""))]
2777 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2781 ;; Floating point move instructions.
2783 (define_expand "movtf"
2784 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2785 (match_operand:TF 1 "nonimmediate_operand" ""))]
2788 ix86_expand_move (TFmode, operands);
2792 (define_expand "mov<mode>"
2793 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2794 (match_operand:X87MODEF 1 "general_operand" ""))]
2796 "ix86_expand_move (<MODE>mode, operands); DONE;")
2798 (define_insn "*movtf_internal"
2799 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2800 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2802 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2804 switch (which_alternative)
2808 if (get_attr_mode (insn) == MODE_V4SF)
2809 return "%vmovaps\t{%1, %0|%0, %1}";
2811 return "%vmovdqa\t{%1, %0|%0, %1}";
2814 return standard_sse_constant_opcode (insn, operands[1]);
2824 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2825 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2827 (cond [(eq_attr "alternative" "0,2")
2829 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2831 (const_string "V4SF")
2832 (const_string "TI"))
2833 (eq_attr "alternative" "1")
2835 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2837 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2839 (const_string "V4SF")
2840 (const_string "TI"))]
2841 (const_string "DI")))])
2844 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2845 (match_operand:TF 1 "general_operand" ""))]
2847 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2849 "ix86_split_long_move (operands); DONE;")
2851 (define_insn "*movxf_internal"
2852 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,Yx*r ,o")
2853 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2854 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2855 && (!can_create_pseudo_p ()
2856 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2857 || GET_CODE (operands[1]) != CONST_DOUBLE
2858 || (optimize_function_for_size_p (cfun)
2859 && standard_80387_constant_p (operands[1]) > 0)
2860 || memory_operand (operands[0], XFmode))"
2862 switch (which_alternative)
2866 return output_387_reg_move (insn, operands);
2869 return standard_80387_constant_opcode (operands[1]);
2877 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2878 (set_attr "mode" "XF,XF,XF,SI,SI")])
2881 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2882 (match_operand:XF 1 "general_operand" ""))]
2884 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2885 && ! (FP_REG_P (operands[0]) ||
2886 (GET_CODE (operands[0]) == SUBREG
2887 && FP_REG_P (SUBREG_REG (operands[0]))))
2888 && ! (FP_REG_P (operands[1]) ||
2889 (GET_CODE (operands[1]) == SUBREG
2890 && FP_REG_P (SUBREG_REG (operands[1]))))"
2892 "ix86_split_long_move (operands); DONE;")
2894 (define_insn "*movdf_internal_rex64"
2895 [(set (match_operand:DF 0 "nonimmediate_operand"
2896 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2897 (match_operand:DF 1 "general_operand"
2898 "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2899 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2900 && (!can_create_pseudo_p ()
2901 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2902 || GET_CODE (operands[1]) != CONST_DOUBLE
2903 || (optimize_function_for_size_p (cfun)
2904 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2905 && standard_80387_constant_p (operands[1]) > 0)
2906 || (TARGET_SSE2 && TARGET_SSE_MATH
2907 && standard_sse_constant_p (operands[1]))))
2908 || memory_operand (operands[0], DFmode))"
2910 switch (which_alternative)
2914 return output_387_reg_move (insn, operands);
2917 return standard_80387_constant_opcode (operands[1]);
2921 return "mov{q}\t{%1, %0|%0, %1}";
2924 return "movabs{q}\t{%1, %0|%0, %1}";
2930 return standard_sse_constant_opcode (insn, operands[1]);
2935 switch (get_attr_mode (insn))
2938 return "%vmovaps\t{%1, %0|%0, %1}";
2940 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2941 return "%vmovaps\t{%1, %0|%0, %1}";
2943 return "%vmovapd\t{%1, %0|%0, %1}";
2945 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946 return "%vmovaps\t{%1, %0|%0, %1}";
2948 return "%vmovdqa\t{%1, %0|%0, %1}";
2950 return "%vmovq\t{%1, %0|%0, %1}";
2952 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2953 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2955 return "%vmovsd\t{%1, %0|%0, %1}";
2957 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2959 return "%vmovlps\t{%1, %d0|%d0, %1}";
2966 /* Handle broken assemblers that require movd instead of movq. */
2967 return "%vmovd\t{%1, %0|%0, %1}";
2973 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2976 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2978 (const_string "*")))
2979 (set (attr "length_immediate")
2981 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2983 (const_string "*")))
2984 (set (attr "prefix")
2985 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2986 (const_string "orig")
2987 (const_string "maybe_vex")))
2988 (set (attr "prefix_data16")
2989 (if_then_else (eq_attr "mode" "V1DF")
2991 (const_string "*")))
2993 (cond [(eq_attr "alternative" "0,1,2")
2995 (eq_attr "alternative" "3,4,5,6,11,12")
2998 /* For SSE1, we have many fewer alternatives. */
2999 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3000 (cond [(eq_attr "alternative" "7,8")
3001 (const_string "V4SF")
3003 (const_string "V2SF"))
3005 /* xorps is one byte shorter. */
3006 (eq_attr "alternative" "7")
3007 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3009 (const_string "V4SF")
3010 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3014 (const_string "V2DF"))
3016 /* For architectures resolving dependencies on
3017 whole SSE registers use APD move to break dependency
3018 chains, otherwise use short move to avoid extra work.
3020 movaps encodes one byte shorter. */
3021 (eq_attr "alternative" "8")
3023 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3025 (const_string "V4SF")
3026 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3028 (const_string "V2DF")
3030 (const_string "DF"))
3031 /* For architectures resolving dependencies on register
3032 parts we may avoid extra work to zero out upper part
3034 (eq_attr "alternative" "9")
3036 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3038 (const_string "V1DF")
3039 (const_string "DF"))
3041 (const_string "DF")))])
3043 ;; Possible store forwarding (partial memory) stall in alternative 4.
3044 (define_insn "*movdf_internal"
3045 [(set (match_operand:DF 0 "nonimmediate_operand"
3046 "=f,m,f,Yd*r ,o ,Y2*x,Y2*x,Y2*x,m ")
3047 (match_operand:DF 1 "general_operand"
3048 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3049 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3050 && (!can_create_pseudo_p ()
3051 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3052 || GET_CODE (operands[1]) != CONST_DOUBLE
3053 || (!TARGET_INTEGER_DFMODE_MOVES
3054 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3055 && standard_80387_constant_p (operands[1]) > 0)
3056 || (TARGET_SSE2 && TARGET_SSE_MATH
3057 && standard_sse_constant_p (operands[1])))
3058 && !memory_operand (operands[0], DFmode))
3059 || ((TARGET_INTEGER_DFMODE_MOVES
3060 || !TARGET_MEMORY_MISMATCH_STALL)
3061 && memory_operand (operands[0], DFmode)))"
3063 switch (which_alternative)
3067 return output_387_reg_move (insn, operands);
3070 return standard_80387_constant_opcode (operands[1]);
3077 return standard_sse_constant_opcode (insn, operands[1]);
3082 switch (get_attr_mode (insn))
3085 return "%vmovaps\t{%1, %0|%0, %1}";
3087 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3088 return "%vmovaps\t{%1, %0|%0, %1}";
3090 return "%vmovapd\t{%1, %0|%0, %1}";
3092 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093 return "%vmovaps\t{%1, %0|%0, %1}";
3095 return "%vmovdqa\t{%1, %0|%0, %1}";
3097 return "%vmovq\t{%1, %0|%0, %1}";
3099 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3100 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3102 return "%vmovsd\t{%1, %0|%0, %1}";
3104 if (TARGET_AVX && REG_P (operands[0]))
3105 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3107 return "%vmovlpd\t{%1, %0|%0, %1}";
3109 if (TARGET_AVX && REG_P (operands[0]))
3110 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3112 return "%vmovlps\t{%1, %0|%0, %1}";
3121 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3122 (set (attr "prefix")
3123 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3124 (const_string "orig")
3125 (const_string "maybe_vex")))
3126 (set (attr "prefix_data16")
3127 (if_then_else (eq_attr "mode" "V1DF")
3129 (const_string "*")))
3131 (cond [(eq_attr "alternative" "0,1,2")
3133 (eq_attr "alternative" "3,4")
3136 /* For SSE1, we have many fewer alternatives. */
3137 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3138 (cond [(eq_attr "alternative" "5,6")
3139 (const_string "V4SF")
3141 (const_string "V2SF"))
3143 /* xorps is one byte shorter. */
3144 (eq_attr "alternative" "5")
3145 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3147 (const_string "V4SF")
3148 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3152 (const_string "V2DF"))
3154 /* For architectures resolving dependencies on
3155 whole SSE registers use APD move to break dependency
3156 chains, otherwise use short move to avoid extra work.
3158 movaps encodes one byte shorter. */
3159 (eq_attr "alternative" "6")
3161 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3163 (const_string "V4SF")
3164 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3166 (const_string "V2DF")
3168 (const_string "DF"))
3169 /* For architectures resolving dependencies on register
3170 parts we may avoid extra work to zero out upper part
3172 (eq_attr "alternative" "7")
3174 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3176 (const_string "V1DF")
3177 (const_string "DF"))
3179 (const_string "DF")))])
3182 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3183 (match_operand:DF 1 "general_operand" ""))]
3185 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3186 && ! (ANY_FP_REG_P (operands[0]) ||
3187 (GET_CODE (operands[0]) == SUBREG
3188 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3189 && ! (ANY_FP_REG_P (operands[1]) ||
3190 (GET_CODE (operands[1]) == SUBREG
3191 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3193 "ix86_split_long_move (operands); DONE;")
3195 (define_insn "*movsf_internal"
3196 [(set (match_operand:SF 0 "nonimmediate_operand"
3197 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3198 (match_operand:SF 1 "general_operand"
3199 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3200 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3201 && (!can_create_pseudo_p ()
3202 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3203 || GET_CODE (operands[1]) != CONST_DOUBLE
3204 || (optimize_function_for_size_p (cfun)
3205 && ((!TARGET_SSE_MATH
3206 && standard_80387_constant_p (operands[1]) > 0)
3208 && standard_sse_constant_p (operands[1]))))
3209 || memory_operand (operands[0], SFmode))"
3211 switch (which_alternative)
3215 return output_387_reg_move (insn, operands);
3218 return standard_80387_constant_opcode (operands[1]);
3222 return "mov{l}\t{%1, %0|%0, %1}";
3225 return standard_sse_constant_opcode (insn, operands[1]);
3228 if (get_attr_mode (insn) == MODE_V4SF)
3229 return "%vmovaps\t{%1, %0|%0, %1}";
3231 return "%vmovss\t{%1, %d0|%d0, %1}";
3233 if (TARGET_AVX && REG_P (operands[1]))
3234 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3236 return "%vmovss\t{%1, %0|%0, %1}";
3238 return "%vmovss\t{%1, %0|%0, %1}";
3240 case 9: case 10: case 14: case 15:
3241 return "movd\t{%1, %0|%0, %1}";
3244 return "movq\t{%1, %0|%0, %1}";
3247 return "%vmovd\t{%1, %0|%0, %1}";
3253 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3254 (set (attr "prefix")
3255 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3256 (const_string "maybe_vex")
3257 (const_string "orig")))
3259 (cond [(eq_attr "alternative" "3,4,9,10")
3261 (eq_attr "alternative" "5")
3263 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3265 (ne (symbol_ref "TARGET_SSE2")
3267 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3270 (const_string "V4SF"))
3271 /* For architectures resolving dependencies on
3272 whole SSE registers use APS move to break dependency
3273 chains, otherwise use short move to avoid extra work.
3275 Do the same for architectures resolving dependencies on
3276 the parts. While in DF mode it is better to always handle
3277 just register parts, the SF mode is different due to lack
3278 of instructions to load just part of the register. It is
3279 better to maintain the whole registers in single format
3280 to avoid problems on using packed logical operations. */
3281 (eq_attr "alternative" "6")
3283 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3285 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3287 (const_string "V4SF")
3288 (const_string "SF"))
3289 (eq_attr "alternative" "11")
3290 (const_string "DI")]
3291 (const_string "SF")))])
3294 [(set (match_operand 0 "register_operand" "")
3295 (match_operand 1 "memory_operand" ""))]
3297 && MEM_P (operands[1])
3298 && (GET_MODE (operands[0]) == TFmode
3299 || GET_MODE (operands[0]) == XFmode
3300 || GET_MODE (operands[0]) == DFmode
3301 || GET_MODE (operands[0]) == SFmode)
3302 && (operands[2] = find_constant_src (insn))"
3303 [(set (match_dup 0) (match_dup 2))]
3305 rtx c = operands[2];
3306 rtx r = operands[0];
3308 if (GET_CODE (r) == SUBREG)
3313 if (!standard_sse_constant_p (c))
3316 else if (FP_REG_P (r))
3318 if (standard_80387_constant_p (c) < 1)
3321 else if (MMX_REG_P (r))
3326 [(set (match_operand 0 "register_operand" "")
3327 (float_extend (match_operand 1 "memory_operand" "")))]
3329 && MEM_P (operands[1])
3330 && (GET_MODE (operands[0]) == TFmode
3331 || GET_MODE (operands[0]) == XFmode
3332 || GET_MODE (operands[0]) == DFmode
3333 || GET_MODE (operands[0]) == SFmode)
3334 && (operands[2] = find_constant_src (insn))"
3335 [(set (match_dup 0) (match_dup 2))]
3337 rtx c = operands[2];
3338 rtx r = operands[0];
3340 if (GET_CODE (r) == SUBREG)
3345 if (!standard_sse_constant_p (c))
3348 else if (FP_REG_P (r))
3350 if (standard_80387_constant_p (c) < 1)
3353 else if (MMX_REG_P (r))
3357 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3359 [(set (match_operand:X87MODEF 0 "register_operand" "")
3360 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3361 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3362 && (standard_80387_constant_p (operands[1]) == 8
3363 || standard_80387_constant_p (operands[1]) == 9)"
3364 [(set (match_dup 0)(match_dup 1))
3366 (neg:X87MODEF (match_dup 0)))]
3370 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3371 if (real_isnegzero (&r))
3372 operands[1] = CONST0_RTX (<MODE>mode);
3374 operands[1] = CONST1_RTX (<MODE>mode);
3377 (define_insn "swapxf"
3378 [(set (match_operand:XF 0 "register_operand" "+f")
3379 (match_operand:XF 1 "register_operand" "+f"))
3384 if (STACK_TOP_P (operands[0]))
3389 [(set_attr "type" "fxch")
3390 (set_attr "mode" "XF")])
3392 (define_insn "*swap<mode>"
3393 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3394 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3397 "TARGET_80387 || reload_completed"
3399 if (STACK_TOP_P (operands[0]))
3404 [(set_attr "type" "fxch")
3405 (set_attr "mode" "<MODE>")])
3407 ;; Zero extension instructions
3409 (define_expand "zero_extendsidi2"
3410 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3411 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3416 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3421 (define_insn "*zero_extendsidi2_rex64"
3422 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3424 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3427 mov\t{%k1, %k0|%k0, %k1}
3429 movd\t{%1, %0|%0, %1}
3430 movd\t{%1, %0|%0, %1}
3431 %vmovd\t{%1, %0|%0, %1}
3432 %vmovd\t{%1, %0|%0, %1}"
3433 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3434 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3435 (set_attr "prefix_0f" "0,*,*,*,*,*")
3436 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3439 [(set (match_operand:DI 0 "memory_operand" "")
3440 (zero_extend:DI (match_dup 0)))]
3442 [(set (match_dup 4) (const_int 0))]
3443 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3445 ;; %%% Kill me once multi-word ops are sane.
3446 (define_insn "zero_extendsidi2_1"
3447 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3449 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3450 (clobber (reg:CC FLAGS_REG))]
3456 movd\t{%1, %0|%0, %1}
3457 movd\t{%1, %0|%0, %1}
3458 %vmovd\t{%1, %0|%0, %1}
3459 %vmovd\t{%1, %0|%0, %1}"
3460 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3461 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3462 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3465 [(set (match_operand:DI 0 "register_operand" "")
3466 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3467 (clobber (reg:CC FLAGS_REG))]
3468 "!TARGET_64BIT && reload_completed
3469 && true_regnum (operands[0]) == true_regnum (operands[1])"
3470 [(set (match_dup 4) (const_int 0))]
3471 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3474 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3475 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3476 (clobber (reg:CC FLAGS_REG))]
3477 "!TARGET_64BIT && reload_completed
3478 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3479 [(set (match_dup 3) (match_dup 1))
3480 (set (match_dup 4) (const_int 0))]
3481 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3483 (define_insn "zero_extend<mode>di2"
3484 [(set (match_operand:DI 0 "register_operand" "=r")
3486 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3488 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3489 [(set_attr "type" "imovx")
3490 (set_attr "mode" "SI")])
3492 (define_expand "zero_extendhisi2"
3493 [(set (match_operand:SI 0 "register_operand" "")
3494 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3497 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3499 operands[1] = force_reg (HImode, operands[1]);
3500 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3505 (define_insn_and_split "zero_extendhisi2_and"
3506 [(set (match_operand:SI 0 "register_operand" "=r")
3507 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3508 (clobber (reg:CC FLAGS_REG))]
3509 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3511 "&& reload_completed"
3512 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3513 (clobber (reg:CC FLAGS_REG))])]
3515 [(set_attr "type" "alu1")
3516 (set_attr "mode" "SI")])
3518 (define_insn "*zero_extendhisi2_movzwl"
3519 [(set (match_operand:SI 0 "register_operand" "=r")
3520 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3521 "!TARGET_ZERO_EXTEND_WITH_AND
3522 || optimize_function_for_size_p (cfun)"
3523 "movz{wl|x}\t{%1, %0|%0, %1}"
3524 [(set_attr "type" "imovx")
3525 (set_attr "mode" "SI")])
3527 (define_expand "zero_extendqi<mode>2"
3529 [(set (match_operand:SWI24 0 "register_operand" "")
3530 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3531 (clobber (reg:CC FLAGS_REG))])])
3533 (define_insn "*zero_extendqi<mode>2_and"
3534 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3535 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3536 (clobber (reg:CC FLAGS_REG))]
3537 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3539 [(set_attr "type" "alu1")
3540 (set_attr "mode" "<MODE>")])
3542 ;; When source and destination does not overlap, clear destination
3543 ;; first and then do the movb
3545 [(set (match_operand:SWI24 0 "register_operand" "")
3546 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3547 (clobber (reg:CC FLAGS_REG))]
3549 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3550 && ANY_QI_REG_P (operands[0])
3551 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3552 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3553 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3555 operands[2] = gen_lowpart (QImode, operands[0]);
3556 ix86_expand_clear (operands[0]);
3559 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3560 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3561 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3562 (clobber (reg:CC FLAGS_REG))]
3563 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3565 [(set_attr "type" "imovx,alu1")
3566 (set_attr "mode" "<MODE>")])
3568 ;; For the movzbl case strip only the clobber
3570 [(set (match_operand:SWI24 0 "register_operand" "")
3571 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3572 (clobber (reg:CC FLAGS_REG))]
3574 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3575 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3577 (zero_extend:SWI24 (match_dup 1)))])
3579 ; zero extend to SImode to avoid partial register stalls
3580 (define_insn "*zero_extendqi<mode>2_movzbl"
3581 [(set (match_operand:SWI24 0 "register_operand" "=r")
3582 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3584 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3585 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3586 [(set_attr "type" "imovx")
3587 (set_attr "mode" "SI")])
3589 ;; Rest is handled by single and.
3591 [(set (match_operand:SWI24 0 "register_operand" "")
3592 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3593 (clobber (reg:CC FLAGS_REG))]
3595 && true_regnum (operands[0]) == true_regnum (operands[1])"
3596 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3597 (clobber (reg:CC FLAGS_REG))])])
3599 ;; Sign extension instructions
3601 (define_expand "extendsidi2"
3602 [(set (match_operand:DI 0 "register_operand" "")
3603 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3608 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3613 (define_insn "*extendsidi2_rex64"
3614 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3615 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3619 movs{lq|x}\t{%1, %0|%0, %1}"
3620 [(set_attr "type" "imovx")
3621 (set_attr "mode" "DI")
3622 (set_attr "prefix_0f" "0")
3623 (set_attr "modrm" "0,1")])
3625 (define_insn "extendsidi2_1"
3626 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3627 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3628 (clobber (reg:CC FLAGS_REG))
3629 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3633 ;; Extend to memory case when source register does die.
3635 [(set (match_operand:DI 0 "memory_operand" "")
3636 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3637 (clobber (reg:CC FLAGS_REG))
3638 (clobber (match_operand:SI 2 "register_operand" ""))]
3640 && dead_or_set_p (insn, operands[1])
3641 && !reg_mentioned_p (operands[1], operands[0]))"
3642 [(set (match_dup 3) (match_dup 1))
3643 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3644 (clobber (reg:CC FLAGS_REG))])
3645 (set (match_dup 4) (match_dup 1))]
3646 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3648 ;; Extend to memory case when source register does not die.
3650 [(set (match_operand:DI 0 "memory_operand" "")
3651 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3652 (clobber (reg:CC FLAGS_REG))
3653 (clobber (match_operand:SI 2 "register_operand" ""))]
3657 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3659 emit_move_insn (operands[3], operands[1]);
3661 /* Generate a cltd if possible and doing so it profitable. */
3662 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3663 && true_regnum (operands[1]) == AX_REG
3664 && true_regnum (operands[2]) == DX_REG)
3666 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3670 emit_move_insn (operands[2], operands[1]);
3671 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3673 emit_move_insn (operands[4], operands[2]);
3677 ;; Extend to register case. Optimize case where source and destination
3678 ;; registers match and cases where we can use cltd.
3680 [(set (match_operand:DI 0 "register_operand" "")
3681 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3682 (clobber (reg:CC FLAGS_REG))
3683 (clobber (match_scratch:SI 2 ""))]
3687 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3689 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3690 emit_move_insn (operands[3], operands[1]);
3692 /* Generate a cltd if possible and doing so it profitable. */
3693 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3694 && true_regnum (operands[3]) == AX_REG
3695 && true_regnum (operands[4]) == DX_REG)
3697 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3701 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3702 emit_move_insn (operands[4], operands[1]);
3704 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3708 (define_insn "extend<mode>di2"
3709 [(set (match_operand:DI 0 "register_operand" "=r")
3711 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3713 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3714 [(set_attr "type" "imovx")
3715 (set_attr "mode" "DI")])
3717 (define_insn "extendhisi2"
3718 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3719 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3722 switch (get_attr_prefix_0f (insn))
3725 return "{cwtl|cwde}";
3727 return "movs{wl|x}\t{%1, %0|%0, %1}";
3730 [(set_attr "type" "imovx")
3731 (set_attr "mode" "SI")
3732 (set (attr "prefix_0f")
3733 ;; movsx is short decodable while cwtl is vector decoded.
3734 (if_then_else (and (eq_attr "cpu" "!k6")
3735 (eq_attr "alternative" "0"))
3737 (const_string "1")))
3739 (if_then_else (eq_attr "prefix_0f" "0")
3741 (const_string "1")))])
3743 (define_insn "*extendhisi2_zext"
3744 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3747 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3750 switch (get_attr_prefix_0f (insn))
3753 return "{cwtl|cwde}";
3755 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3758 [(set_attr "type" "imovx")
3759 (set_attr "mode" "SI")
3760 (set (attr "prefix_0f")
3761 ;; movsx is short decodable while cwtl is vector decoded.
3762 (if_then_else (and (eq_attr "cpu" "!k6")
3763 (eq_attr "alternative" "0"))
3765 (const_string "1")))
3767 (if_then_else (eq_attr "prefix_0f" "0")
3769 (const_string "1")))])
3771 (define_insn "extendqisi2"
3772 [(set (match_operand:SI 0 "register_operand" "=r")
3773 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3775 "movs{bl|x}\t{%1, %0|%0, %1}"
3776 [(set_attr "type" "imovx")
3777 (set_attr "mode" "SI")])
3779 (define_insn "*extendqisi2_zext"
3780 [(set (match_operand:DI 0 "register_operand" "=r")
3782 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3784 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3785 [(set_attr "type" "imovx")
3786 (set_attr "mode" "SI")])
3788 (define_insn "extendqihi2"
3789 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3790 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3793 switch (get_attr_prefix_0f (insn))
3796 return "{cbtw|cbw}";
3798 return "movs{bw|x}\t{%1, %0|%0, %1}";
3801 [(set_attr "type" "imovx")
3802 (set_attr "mode" "HI")
3803 (set (attr "prefix_0f")
3804 ;; movsx is short decodable while cwtl is vector decoded.
3805 (if_then_else (and (eq_attr "cpu" "!k6")
3806 (eq_attr "alternative" "0"))
3808 (const_string "1")))
3810 (if_then_else (eq_attr "prefix_0f" "0")
3812 (const_string "1")))])
3814 ;; Conversions between float and double.
3816 ;; These are all no-ops in the model used for the 80387.
3817 ;; So just emit moves.
3819 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3821 [(set (match_operand:DF 0 "push_operand" "")
3822 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3824 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3825 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3828 [(set (match_operand:XF 0 "push_operand" "")
3829 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3831 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3832 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3833 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3835 (define_expand "extendsfdf2"
3836 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3837 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3838 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3840 /* ??? Needed for compress_float_constant since all fp constants
3841 are TARGET_LEGITIMATE_CONSTANT_P. */
3842 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3844 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3845 && standard_80387_constant_p (operands[1]) > 0)
3847 operands[1] = simplify_const_unary_operation
3848 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3849 emit_move_insn_1 (operands[0], operands[1]);
3852 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3856 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3858 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3860 We do the conversion post reload to avoid producing of 128bit spills
3861 that might lead to ICE on 32bit target. The sequence unlikely combine
3864 [(set (match_operand:DF 0 "register_operand" "")
3866 (match_operand:SF 1 "nonimmediate_operand" "")))]
3867 "TARGET_USE_VECTOR_FP_CONVERTS
3868 && optimize_insn_for_speed_p ()
3869 && reload_completed && SSE_REG_P (operands[0])"
3874 (parallel [(const_int 0) (const_int 1)]))))]
3876 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3877 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3878 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3879 Try to avoid move when unpacking can be done in source. */
3880 if (REG_P (operands[1]))
3882 /* If it is unsafe to overwrite upper half of source, we need
3883 to move to destination and unpack there. */
3884 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3885 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3886 && true_regnum (operands[0]) != true_regnum (operands[1]))
3888 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3889 emit_move_insn (tmp, operands[1]);
3892 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3893 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3897 emit_insn (gen_vec_setv4sf_0 (operands[3],
3898 CONST0_RTX (V4SFmode), operands[1]));
3901 (define_insn "*extendsfdf2_mixed"
3902 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3904 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3905 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3907 switch (which_alternative)
3911 return output_387_reg_move (insn, operands);
3914 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3920 [(set_attr "type" "fmov,fmov,ssecvt")
3921 (set_attr "prefix" "orig,orig,maybe_vex")
3922 (set_attr "mode" "SF,XF,DF")])
3924 (define_insn "*extendsfdf2_sse"
3925 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3926 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3927 "TARGET_SSE2 && TARGET_SSE_MATH"
3928 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3929 [(set_attr "type" "ssecvt")
3930 (set_attr "prefix" "maybe_vex")
3931 (set_attr "mode" "DF")])
3933 (define_insn "*extendsfdf2_i387"
3934 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3935 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3937 "* return output_387_reg_move (insn, operands);"
3938 [(set_attr "type" "fmov")
3939 (set_attr "mode" "SF,XF")])
3941 (define_expand "extend<mode>xf2"
3942 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3943 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3946 /* ??? Needed for compress_float_constant since all fp constants
3947 are TARGET_LEGITIMATE_CONSTANT_P. */
3948 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3950 if (standard_80387_constant_p (operands[1]) > 0)
3952 operands[1] = simplify_const_unary_operation
3953 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3954 emit_move_insn_1 (operands[0], operands[1]);
3957 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3961 (define_insn "*extend<mode>xf2_i387"
3962 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3964 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3966 "* return output_387_reg_move (insn, operands);"
3967 [(set_attr "type" "fmov")
3968 (set_attr "mode" "<MODE>,XF")])
3970 ;; %%% This seems bad bad news.
3971 ;; This cannot output into an f-reg because there is no way to be sure
3972 ;; of truncating in that case. Otherwise this is just like a simple move
3973 ;; insn. So we pretend we can output to a reg in order to get better
3974 ;; register preferencing, but we really use a stack slot.
3976 ;; Conversion from DFmode to SFmode.
3978 (define_expand "truncdfsf2"
3979 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3981 (match_operand:DF 1 "nonimmediate_operand" "")))]
3982 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3984 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3986 else if (flag_unsafe_math_optimizations)
3990 enum ix86_stack_slot slot = (virtuals_instantiated
3993 rtx temp = assign_386_stack_local (SFmode, slot);
3994 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3999 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4001 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4003 We do the conversion post reload to avoid producing of 128bit spills
4004 that might lead to ICE on 32bit target. The sequence unlikely combine
4007 [(set (match_operand:SF 0 "register_operand" "")
4009 (match_operand:DF 1 "nonimmediate_operand" "")))]
4010 "TARGET_USE_VECTOR_FP_CONVERTS
4011 && optimize_insn_for_speed_p ()
4012 && reload_completed && SSE_REG_P (operands[0])"
4015 (float_truncate:V2SF
4019 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4020 operands[3] = CONST0_RTX (V2SFmode);
4021 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4022 /* Use movsd for loading from memory, unpcklpd for registers.
4023 Try to avoid move when unpacking can be done in source, or SSE3
4024 movddup is available. */
4025 if (REG_P (operands[1]))
4028 && true_regnum (operands[0]) != true_regnum (operands[1])
4029 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4030 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4032 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4033 emit_move_insn (tmp, operands[1]);
4036 else if (!TARGET_SSE3)
4037 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4038 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4041 emit_insn (gen_sse2_loadlpd (operands[4],
4042 CONST0_RTX (V2DFmode), operands[1]));
4045 (define_expand "truncdfsf2_with_temp"
4046 [(parallel [(set (match_operand:SF 0 "" "")
4047 (float_truncate:SF (match_operand:DF 1 "" "")))
4048 (clobber (match_operand:SF 2 "" ""))])])
4050 (define_insn "*truncdfsf_fast_mixed"
4051 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4053 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4054 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4056 switch (which_alternative)
4059 return output_387_reg_move (insn, operands);
4061 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4066 [(set_attr "type" "fmov,ssecvt")
4067 (set_attr "prefix" "orig,maybe_vex")
4068 (set_attr "mode" "SF")])
4070 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4071 ;; because nothing we do here is unsafe.
4072 (define_insn "*truncdfsf_fast_sse"
4073 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4075 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4076 "TARGET_SSE2 && TARGET_SSE_MATH"
4077 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4078 [(set_attr "type" "ssecvt")
4079 (set_attr "prefix" "maybe_vex")
4080 (set_attr "mode" "SF")])
4082 (define_insn "*truncdfsf_fast_i387"
4083 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4085 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4086 "TARGET_80387 && flag_unsafe_math_optimizations"
4087 "* return output_387_reg_move (insn, operands);"
4088 [(set_attr "type" "fmov")
4089 (set_attr "mode" "SF")])
4091 (define_insn "*truncdfsf_mixed"
4092 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4094 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4095 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4096 "TARGET_MIX_SSE_I387"
4098 switch (which_alternative)
4101 return output_387_reg_move (insn, operands);
4103 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4109 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4110 (set_attr "unit" "*,*,i387,i387,i387")
4111 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4112 (set_attr "mode" "SF")])
4114 (define_insn "*truncdfsf_i387"
4115 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4117 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4118 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4121 switch (which_alternative)
4124 return output_387_reg_move (insn, operands);
4130 [(set_attr "type" "fmov,multi,multi,multi")
4131 (set_attr "unit" "*,i387,i387,i387")
4132 (set_attr "mode" "SF")])
4134 (define_insn "*truncdfsf2_i387_1"
4135 [(set (match_operand:SF 0 "memory_operand" "=m")
4137 (match_operand:DF 1 "register_operand" "f")))]
4139 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4140 && !TARGET_MIX_SSE_I387"
4141 "* return output_387_reg_move (insn, operands);"
4142 [(set_attr "type" "fmov")
4143 (set_attr "mode" "SF")])
4146 [(set (match_operand:SF 0 "register_operand" "")
4148 (match_operand:DF 1 "fp_register_operand" "")))
4149 (clobber (match_operand 2 "" ""))]
4151 [(set (match_dup 2) (match_dup 1))
4152 (set (match_dup 0) (match_dup 2))]
4153 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4155 ;; Conversion from XFmode to {SF,DF}mode
4157 (define_expand "truncxf<mode>2"
4158 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4159 (float_truncate:MODEF
4160 (match_operand:XF 1 "register_operand" "")))
4161 (clobber (match_dup 2))])]
4164 if (flag_unsafe_math_optimizations)
4166 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4167 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4168 if (reg != operands[0])
4169 emit_move_insn (operands[0], reg);
4174 enum ix86_stack_slot slot = (virtuals_instantiated
4177 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4181 (define_insn "*truncxfsf2_mixed"
4182 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4184 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4185 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4188 gcc_assert (!which_alternative);
4189 return output_387_reg_move (insn, operands);
4191 [(set_attr "type" "fmov,multi,multi,multi")
4192 (set_attr "unit" "*,i387,i387,i387")
4193 (set_attr "mode" "SF")])
4195 (define_insn "*truncxfdf2_mixed"
4196 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4198 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4199 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4202 gcc_assert (!which_alternative);
4203 return output_387_reg_move (insn, operands);
4205 [(set_attr "type" "fmov,multi,multi,multi")
4206 (set_attr "unit" "*,i387,i387,i387")
4207 (set_attr "mode" "DF")])
4209 (define_insn "truncxf<mode>2_i387_noop"
4210 [(set (match_operand:MODEF 0 "register_operand" "=f")
4211 (float_truncate:MODEF
4212 (match_operand:XF 1 "register_operand" "f")))]
4213 "TARGET_80387 && flag_unsafe_math_optimizations"
4214 "* return output_387_reg_move (insn, operands);"
4215 [(set_attr "type" "fmov")
4216 (set_attr "mode" "<MODE>")])
4218 (define_insn "*truncxf<mode>2_i387"
4219 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4220 (float_truncate:MODEF
4221 (match_operand:XF 1 "register_operand" "f")))]
4223 "* return output_387_reg_move (insn, operands);"
4224 [(set_attr "type" "fmov")
4225 (set_attr "mode" "<MODE>")])
4228 [(set (match_operand:MODEF 0 "register_operand" "")
4229 (float_truncate:MODEF
4230 (match_operand:XF 1 "register_operand" "")))
4231 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4232 "TARGET_80387 && reload_completed"
4233 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4234 (set (match_dup 0) (match_dup 2))])
4237 [(set (match_operand:MODEF 0 "memory_operand" "")
4238 (float_truncate:MODEF
4239 (match_operand:XF 1 "register_operand" "")))
4240 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4242 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4244 ;; Signed conversion to DImode.
4246 (define_expand "fix_truncxfdi2"
4247 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248 (fix:DI (match_operand:XF 1 "register_operand" "")))
4249 (clobber (reg:CC FLAGS_REG))])]
4254 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4259 (define_expand "fix_trunc<mode>di2"
4260 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4262 (clobber (reg:CC FLAGS_REG))])]
4263 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4266 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4268 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4271 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4273 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275 if (out != operands[0])
4276 emit_move_insn (operands[0], out);
4281 ;; Signed conversion to SImode.
4283 (define_expand "fix_truncxfsi2"
4284 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285 (fix:SI (match_operand:XF 1 "register_operand" "")))
4286 (clobber (reg:CC FLAGS_REG))])]
4291 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4296 (define_expand "fix_trunc<mode>si2"
4297 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4299 (clobber (reg:CC FLAGS_REG))])]
4300 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4303 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4305 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4308 if (SSE_FLOAT_MODE_P (<MODE>mode))
4310 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312 if (out != operands[0])
4313 emit_move_insn (operands[0], out);
4318 ;; Signed conversion to HImode.
4320 (define_expand "fix_trunc<mode>hi2"
4321 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323 (clobber (reg:CC FLAGS_REG))])]
4325 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4329 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4334 ;; Unsigned conversion to SImode.
4336 (define_expand "fixuns_trunc<mode>si2"
4338 [(set (match_operand:SI 0 "register_operand" "")
4340 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4342 (clobber (match_scratch:<ssevecmode> 3 ""))
4343 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4344 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4346 enum machine_mode mode = <MODE>mode;
4347 enum machine_mode vecmode = <ssevecmode>mode;
4348 REAL_VALUE_TYPE TWO31r;
4351 if (optimize_insn_for_size_p ())
4354 real_ldexp (&TWO31r, &dconst1, 31);
4355 two31 = const_double_from_real_value (TWO31r, mode);
4356 two31 = ix86_build_const_vector (vecmode, true, two31);
4357 operands[2] = force_reg (vecmode, two31);
4360 (define_insn_and_split "*fixuns_trunc<mode>_1"
4361 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4363 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4364 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4365 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4366 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4367 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4368 && optimize_function_for_speed_p (cfun)"
4370 "&& reload_completed"
4373 ix86_split_convert_uns_si_sse (operands);
4377 ;; Unsigned conversion to HImode.
4378 ;; Without these patterns, we'll try the unsigned SI conversion which
4379 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4381 (define_expand "fixuns_trunc<mode>hi2"
4383 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4384 (set (match_operand:HI 0 "nonimmediate_operand" "")
4385 (subreg:HI (match_dup 2) 0))]
4386 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4387 "operands[2] = gen_reg_rtx (SImode);")
4389 ;; When SSE is available, it is always faster to use it!
4390 (define_insn "fix_trunc<mode>di_sse"
4391 [(set (match_operand:DI 0 "register_operand" "=r,r")
4392 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4393 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4394 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4395 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4396 [(set_attr "type" "sseicvt")
4397 (set_attr "prefix" "maybe_vex")
4398 (set_attr "prefix_rex" "1")
4399 (set_attr "mode" "<MODE>")
4400 (set_attr "athlon_decode" "double,vector")
4401 (set_attr "amdfam10_decode" "double,double")
4402 (set_attr "bdver1_decode" "double,double")])
4404 (define_insn "fix_trunc<mode>si_sse"
4405 [(set (match_operand:SI 0 "register_operand" "=r,r")
4406 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4407 "SSE_FLOAT_MODE_P (<MODE>mode)
4408 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4409 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4410 [(set_attr "type" "sseicvt")
4411 (set_attr "prefix" "maybe_vex")
4412 (set_attr "mode" "<MODE>")
4413 (set_attr "athlon_decode" "double,vector")
4414 (set_attr "amdfam10_decode" "double,double")
4415 (set_attr "bdver1_decode" "double,double")])
4417 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4419 [(set (match_operand:MODEF 0 "register_operand" "")
4420 (match_operand:MODEF 1 "memory_operand" ""))
4421 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4422 (fix:SSEMODEI24 (match_dup 0)))]
4423 "TARGET_SHORTEN_X87_SSE
4424 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4425 && peep2_reg_dead_p (2, operands[0])"
4426 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4428 ;; Avoid vector decoded forms of the instruction.
4430 [(match_scratch:DF 2 "Y2")
4431 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4432 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4433 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4434 [(set (match_dup 2) (match_dup 1))
4435 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4438 [(match_scratch:SF 2 "x")
4439 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4440 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4441 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4442 [(set (match_dup 2) (match_dup 1))
4443 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4445 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4446 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4447 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4448 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4450 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4451 && (TARGET_64BIT || <MODE>mode != DImode))
4453 && can_create_pseudo_p ()"
4458 if (memory_operand (operands[0], VOIDmode))
4459 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4462 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4463 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4469 [(set_attr "type" "fisttp")
4470 (set_attr "mode" "<MODE>")])
4472 (define_insn "fix_trunc<mode>_i387_fisttp"
4473 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4474 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4475 (clobber (match_scratch:XF 2 "=&1f"))]
4476 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4478 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4479 && (TARGET_64BIT || <MODE>mode != DImode))
4480 && TARGET_SSE_MATH)"
4481 "* return output_fix_trunc (insn, operands, 1);"
4482 [(set_attr "type" "fisttp")
4483 (set_attr "mode" "<MODE>")])
4485 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4486 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4487 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4488 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4489 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4490 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4492 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && (TARGET_64BIT || <MODE>mode != DImode))
4494 && TARGET_SSE_MATH)"
4496 [(set_attr "type" "fisttp")
4497 (set_attr "mode" "<MODE>")])
4500 [(set (match_operand:X87MODEI 0 "register_operand" "")
4501 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4502 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4503 (clobber (match_scratch 3 ""))]
4505 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4506 (clobber (match_dup 3))])
4507 (set (match_dup 0) (match_dup 2))])
4510 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4511 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4512 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4513 (clobber (match_scratch 3 ""))]
4515 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4516 (clobber (match_dup 3))])])
4518 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4519 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4520 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4521 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4522 ;; function in i386.c.
4523 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4524 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4525 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4526 (clobber (reg:CC FLAGS_REG))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && (TARGET_64BIT || <MODE>mode != DImode))
4531 && can_create_pseudo_p ()"
4536 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4538 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4539 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4540 if (memory_operand (operands[0], VOIDmode))
4541 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4542 operands[2], operands[3]));
4545 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4546 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4547 operands[2], operands[3],
4552 [(set_attr "type" "fistp")
4553 (set_attr "i387_cw" "trunc")
4554 (set_attr "mode" "<MODE>")])
4556 (define_insn "fix_truncdi_i387"
4557 [(set (match_operand:DI 0 "memory_operand" "=m")
4558 (fix:DI (match_operand 1 "register_operand" "f")))
4559 (use (match_operand:HI 2 "memory_operand" "m"))
4560 (use (match_operand:HI 3 "memory_operand" "m"))
4561 (clobber (match_scratch:XF 4 "=&1f"))]
4562 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4565 "* return output_fix_trunc (insn, operands, 0);"
4566 [(set_attr "type" "fistp")
4567 (set_attr "i387_cw" "trunc")
4568 (set_attr "mode" "DI")])
4570 (define_insn "fix_truncdi_i387_with_temp"
4571 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4572 (fix:DI (match_operand 1 "register_operand" "f,f")))
4573 (use (match_operand:HI 2 "memory_operand" "m,m"))
4574 (use (match_operand:HI 3 "memory_operand" "m,m"))
4575 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4576 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4577 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4579 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4581 [(set_attr "type" "fistp")
4582 (set_attr "i387_cw" "trunc")
4583 (set_attr "mode" "DI")])
4586 [(set (match_operand:DI 0 "register_operand" "")
4587 (fix:DI (match_operand 1 "register_operand" "")))
4588 (use (match_operand:HI 2 "memory_operand" ""))
4589 (use (match_operand:HI 3 "memory_operand" ""))
4590 (clobber (match_operand:DI 4 "memory_operand" ""))
4591 (clobber (match_scratch 5 ""))]
4593 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4596 (clobber (match_dup 5))])
4597 (set (match_dup 0) (match_dup 4))])
4600 [(set (match_operand:DI 0 "memory_operand" "")
4601 (fix:DI (match_operand 1 "register_operand" "")))
4602 (use (match_operand:HI 2 "memory_operand" ""))
4603 (use (match_operand:HI 3 "memory_operand" ""))
4604 (clobber (match_operand:DI 4 "memory_operand" ""))
4605 (clobber (match_scratch 5 ""))]
4607 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4610 (clobber (match_dup 5))])])
4612 (define_insn "fix_trunc<mode>_i387"
4613 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4614 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4615 (use (match_operand:HI 2 "memory_operand" "m"))
4616 (use (match_operand:HI 3 "memory_operand" "m"))]
4617 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4619 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4620 "* return output_fix_trunc (insn, operands, 0);"
4621 [(set_attr "type" "fistp")
4622 (set_attr "i387_cw" "trunc")
4623 (set_attr "mode" "<MODE>")])
4625 (define_insn "fix_trunc<mode>_i387_with_temp"
4626 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4627 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4628 (use (match_operand:HI 2 "memory_operand" "m,m"))
4629 (use (match_operand:HI 3 "memory_operand" "m,m"))
4630 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4631 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4633 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4635 [(set_attr "type" "fistp")
4636 (set_attr "i387_cw" "trunc")
4637 (set_attr "mode" "<MODE>")])
4640 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4641 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4642 (use (match_operand:HI 2 "memory_operand" ""))
4643 (use (match_operand:HI 3 "memory_operand" ""))
4644 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4646 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4648 (use (match_dup 3))])
4649 (set (match_dup 0) (match_dup 4))])
4652 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4653 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4654 (use (match_operand:HI 2 "memory_operand" ""))
4655 (use (match_operand:HI 3 "memory_operand" ""))
4656 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4658 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4660 (use (match_dup 3))])])
4662 (define_insn "x86_fnstcw_1"
4663 [(set (match_operand:HI 0 "memory_operand" "=m")
4664 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4667 [(set (attr "length")
4668 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4669 (set_attr "mode" "HI")
4670 (set_attr "unit" "i387")
4671 (set_attr "bdver1_decode" "vector")])
4673 (define_insn "x86_fldcw_1"
4674 [(set (reg:HI FPCR_REG)
4675 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4678 [(set (attr "length")
4679 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4680 (set_attr "mode" "HI")
4681 (set_attr "unit" "i387")
4682 (set_attr "athlon_decode" "vector")
4683 (set_attr "amdfam10_decode" "vector")
4684 (set_attr "bdver1_decode" "vector")])
4686 ;; Conversion between fixed point and floating point.
4688 ;; Even though we only accept memory inputs, the backend _really_
4689 ;; wants to be able to do this between registers.
4691 (define_expand "floathi<mode>2"
4692 [(set (match_operand:X87MODEF 0 "register_operand" "")
4693 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696 || TARGET_MIX_SSE_I387)")
4698 ;; Pre-reload splitter to add memory clobber to the pattern.
4699 (define_insn_and_split "*floathi<mode>2_1"
4700 [(set (match_operand:X87MODEF 0 "register_operand" "")
4701 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4703 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4704 || TARGET_MIX_SSE_I387)
4705 && can_create_pseudo_p ()"
4708 [(parallel [(set (match_dup 0)
4709 (float:X87MODEF (match_dup 1)))
4710 (clobber (match_dup 2))])]
4711 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4713 (define_insn "*floathi<mode>2_i387_with_temp"
4714 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4715 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4716 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719 || TARGET_MIX_SSE_I387)"
4721 [(set_attr "type" "fmov,multi")
4722 (set_attr "mode" "<MODE>")
4723 (set_attr "unit" "*,i387")
4724 (set_attr "fp_int_src" "true")])
4726 (define_insn "*floathi<mode>2_i387"
4727 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4728 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4731 || TARGET_MIX_SSE_I387)"
4733 [(set_attr "type" "fmov")
4734 (set_attr "mode" "<MODE>")
4735 (set_attr "fp_int_src" "true")])
4738 [(set (match_operand:X87MODEF 0 "register_operand" "")
4739 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4740 (clobber (match_operand:HI 2 "memory_operand" ""))]
4742 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4743 || TARGET_MIX_SSE_I387)
4744 && reload_completed"
4745 [(set (match_dup 2) (match_dup 1))
4746 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4749 [(set (match_operand:X87MODEF 0 "register_operand" "")
4750 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4751 (clobber (match_operand:HI 2 "memory_operand" ""))]
4753 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4754 || TARGET_MIX_SSE_I387)
4755 && reload_completed"
4756 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4758 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4759 [(set (match_operand:X87MODEF 0 "register_operand" "")
4761 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4763 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4764 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4766 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4767 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4768 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4770 rtx reg = gen_reg_rtx (XFmode);
4771 rtx (*insn)(rtx, rtx);
4773 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4775 if (<X87MODEF:MODE>mode == SFmode)
4776 insn = gen_truncxfsf2;
4777 else if (<X87MODEF:MODE>mode == DFmode)
4778 insn = gen_truncxfdf2;
4782 emit_insn (insn (operands[0], reg));
4787 ;; Pre-reload splitter to add memory clobber to the pattern.
4788 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4789 [(set (match_operand:X87MODEF 0 "register_operand" "")
4790 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4792 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4793 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4794 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4795 || TARGET_MIX_SSE_I387))
4796 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4797 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4798 && ((<SSEMODEI24:MODE>mode == SImode
4799 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4800 && optimize_function_for_speed_p (cfun)
4801 && flag_trapping_math)
4802 || !(TARGET_INTER_UNIT_CONVERSIONS
4803 || optimize_function_for_size_p (cfun)))))
4804 && can_create_pseudo_p ()"
4807 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4808 (clobber (match_dup 2))])]
4810 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4812 /* Avoid store forwarding (partial memory) stall penalty
4813 by passing DImode value through XMM registers. */
4814 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4815 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4816 && optimize_function_for_speed_p (cfun))
4818 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4825 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4826 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4828 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4829 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4830 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4831 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4833 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4834 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4835 (set_attr "unit" "*,i387,*,*,*")
4836 (set_attr "athlon_decode" "*,*,double,direct,double")
4837 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4838 (set_attr "bdver1_decode" "*,*,double,direct,double")
4839 (set_attr "fp_int_src" "true")])
4841 (define_insn "*floatsi<mode>2_vector_mixed"
4842 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4843 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4844 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4845 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4849 [(set_attr "type" "fmov,sseicvt")
4850 (set_attr "mode" "<MODE>,<ssevecmode>")
4851 (set_attr "unit" "i387,*")
4852 (set_attr "athlon_decode" "*,direct")
4853 (set_attr "amdfam10_decode" "*,double")
4854 (set_attr "bdver1_decode" "*,direct")
4855 (set_attr "fp_int_src" "true")])
4857 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4858 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4860 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4861 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4862 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4863 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4865 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4866 (set_attr "mode" "<MODEF:MODE>")
4867 (set_attr "unit" "*,i387,*,*")
4868 (set_attr "athlon_decode" "*,*,double,direct")
4869 (set_attr "amdfam10_decode" "*,*,vector,double")
4870 (set_attr "bdver1_decode" "*,*,double,direct")
4871 (set_attr "fp_int_src" "true")])
4874 [(set (match_operand:MODEF 0 "register_operand" "")
4875 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4876 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4877 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4878 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4879 && TARGET_INTER_UNIT_CONVERSIONS
4881 && (SSE_REG_P (operands[0])
4882 || (GET_CODE (operands[0]) == SUBREG
4883 && SSE_REG_P (operands[0])))"
4884 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4887 [(set (match_operand:MODEF 0 "register_operand" "")
4888 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4889 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4890 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4891 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4892 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4894 && (SSE_REG_P (operands[0])
4895 || (GET_CODE (operands[0]) == SUBREG
4896 && SSE_REG_P (operands[0])))"
4897 [(set (match_dup 2) (match_dup 1))
4898 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4900 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
4901 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4903 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
4904 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4905 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4906 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4909 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
4910 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4911 [(set_attr "type" "fmov,sseicvt,sseicvt")
4912 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4913 (set_attr "mode" "<MODEF:MODE>")
4914 (set (attr "prefix_rex")
4916 (and (eq_attr "prefix" "maybe_vex")
4917 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4919 (const_string "*")))
4920 (set_attr "unit" "i387,*,*")
4921 (set_attr "athlon_decode" "*,double,direct")
4922 (set_attr "amdfam10_decode" "*,vector,double")
4923 (set_attr "bdver1_decode" "*,double,direct")
4924 (set_attr "fp_int_src" "true")])
4926 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
4927 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4929 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
4930 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4931 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4935 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4936 [(set_attr "type" "fmov,sseicvt")
4937 (set_attr "prefix" "orig,maybe_vex")
4938 (set_attr "mode" "<MODEF:MODE>")
4939 (set (attr "prefix_rex")
4941 (and (eq_attr "prefix" "maybe_vex")
4942 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4944 (const_string "*")))
4945 (set_attr "athlon_decode" "*,direct")
4946 (set_attr "amdfam10_decode" "*,double")
4947 (set_attr "bdver1_decode" "*,direct")
4948 (set_attr "fp_int_src" "true")])
4950 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4951 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4953 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4954 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4955 "TARGET_SSE2 && TARGET_SSE_MATH
4956 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4958 [(set_attr "type" "sseicvt")
4959 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4960 (set_attr "athlon_decode" "double,direct,double")
4961 (set_attr "amdfam10_decode" "vector,double,double")
4962 (set_attr "bdver1_decode" "double,direct,double")
4963 (set_attr "fp_int_src" "true")])
4965 (define_insn "*floatsi<mode>2_vector_sse"
4966 [(set (match_operand:MODEF 0 "register_operand" "=x")
4967 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4968 "TARGET_SSE2 && TARGET_SSE_MATH
4969 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4971 [(set_attr "type" "sseicvt")
4972 (set_attr "mode" "<MODE>")
4973 (set_attr "athlon_decode" "direct")
4974 (set_attr "amdfam10_decode" "double")
4975 (set_attr "bdver1_decode" "direct")
4976 (set_attr "fp_int_src" "true")])
4979 [(set (match_operand:MODEF 0 "register_operand" "")
4980 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4981 (clobber (match_operand:SI 2 "memory_operand" ""))]
4982 "TARGET_SSE2 && TARGET_SSE_MATH
4983 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4985 && (SSE_REG_P (operands[0])
4986 || (GET_CODE (operands[0]) == SUBREG
4987 && SSE_REG_P (operands[0])))"
4990 rtx op1 = operands[1];
4992 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4994 if (GET_CODE (op1) == SUBREG)
4995 op1 = SUBREG_REG (op1);
4997 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4999 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5000 emit_insn (gen_sse2_loadld (operands[4],
5001 CONST0_RTX (V4SImode), operands[1]));
5003 /* We can ignore possible trapping value in the
5004 high part of SSE register for non-trapping math. */
5005 else if (SSE_REG_P (op1) && !flag_trapping_math)
5006 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5009 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5010 emit_move_insn (operands[2], operands[1]);
5011 emit_insn (gen_sse2_loadld (operands[4],
5012 CONST0_RTX (V4SImode), operands[2]));
5015 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5020 [(set (match_operand:MODEF 0 "register_operand" "")
5021 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5022 (clobber (match_operand:SI 2 "memory_operand" ""))]
5023 "TARGET_SSE2 && TARGET_SSE_MATH
5024 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5026 && (SSE_REG_P (operands[0])
5027 || (GET_CODE (operands[0]) == SUBREG
5028 && SSE_REG_P (operands[0])))"
5031 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5033 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5035 emit_insn (gen_sse2_loadld (operands[4],
5036 CONST0_RTX (V4SImode), operands[1]));
5038 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5043 [(set (match_operand:MODEF 0 "register_operand" "")
5044 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5045 "TARGET_SSE2 && TARGET_SSE_MATH
5046 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5048 && (SSE_REG_P (operands[0])
5049 || (GET_CODE (operands[0]) == SUBREG
5050 && SSE_REG_P (operands[0])))"
5053 rtx op1 = operands[1];
5055 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5057 if (GET_CODE (op1) == SUBREG)
5058 op1 = SUBREG_REG (op1);
5060 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5062 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5063 emit_insn (gen_sse2_loadld (operands[4],
5064 CONST0_RTX (V4SImode), operands[1]));
5066 /* We can ignore possible trapping value in the
5067 high part of SSE register for non-trapping math. */
5068 else if (SSE_REG_P (op1) && !flag_trapping_math)
5069 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5073 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5078 [(set (match_operand:MODEF 0 "register_operand" "")
5079 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5080 "TARGET_SSE2 && TARGET_SSE_MATH
5081 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5083 && (SSE_REG_P (operands[0])
5084 || (GET_CODE (operands[0]) == SUBREG
5085 && SSE_REG_P (operands[0])))"
5088 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5090 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5092 emit_insn (gen_sse2_loadld (operands[4],
5093 CONST0_RTX (V4SImode), operands[1]));
5095 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5099 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5100 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5102 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5103 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5104 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5105 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5107 [(set_attr "type" "sseicvt")
5108 (set_attr "mode" "<MODEF:MODE>")
5109 (set_attr "athlon_decode" "double,direct")
5110 (set_attr "amdfam10_decode" "vector,double")
5111 (set_attr "bdver1_decode" "double,direct")
5112 (set_attr "fp_int_src" "true")])
5114 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5115 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5117 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5118 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5119 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5120 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5121 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5122 [(set_attr "type" "sseicvt")
5123 (set_attr "prefix" "maybe_vex")
5124 (set_attr "mode" "<MODEF:MODE>")
5125 (set (attr "prefix_rex")
5127 (and (eq_attr "prefix" "maybe_vex")
5128 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5130 (const_string "*")))
5131 (set_attr "athlon_decode" "double,direct")
5132 (set_attr "amdfam10_decode" "vector,double")
5133 (set_attr "bdver1_decode" "double,direct")
5134 (set_attr "fp_int_src" "true")])
5137 [(set (match_operand:MODEF 0 "register_operand" "")
5138 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5139 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5140 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5141 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5142 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5144 && (SSE_REG_P (operands[0])
5145 || (GET_CODE (operands[0]) == SUBREG
5146 && SSE_REG_P (operands[0])))"
5147 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5149 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5150 [(set (match_operand:MODEF 0 "register_operand" "=x")
5152 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5153 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5154 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5155 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5156 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5157 [(set_attr "type" "sseicvt")
5158 (set_attr "prefix" "maybe_vex")
5159 (set_attr "mode" "<MODEF:MODE>")
5160 (set (attr "prefix_rex")
5162 (and (eq_attr "prefix" "maybe_vex")
5163 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5165 (const_string "*")))
5166 (set_attr "athlon_decode" "direct")
5167 (set_attr "amdfam10_decode" "double")
5168 (set_attr "bdver1_decode" "direct")
5169 (set_attr "fp_int_src" "true")])
5172 [(set (match_operand:MODEF 0 "register_operand" "")
5173 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5174 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5175 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5176 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5177 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5179 && (SSE_REG_P (operands[0])
5180 || (GET_CODE (operands[0]) == SUBREG
5181 && SSE_REG_P (operands[0])))"
5182 [(set (match_dup 2) (match_dup 1))
5183 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5186 [(set (match_operand:MODEF 0 "register_operand" "")
5187 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5188 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5189 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5190 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5192 && (SSE_REG_P (operands[0])
5193 || (GET_CODE (operands[0]) == SUBREG
5194 && SSE_REG_P (operands[0])))"
5195 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5197 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5198 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5200 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5201 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5203 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5207 [(set_attr "type" "fmov,multi")
5208 (set_attr "mode" "<X87MODEF:MODE>")
5209 (set_attr "unit" "*,i387")
5210 (set_attr "fp_int_src" "true")])
5212 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5213 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5215 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5217 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5219 [(set_attr "type" "fmov")
5220 (set_attr "mode" "<X87MODEF:MODE>")
5221 (set_attr "fp_int_src" "true")])
5224 [(set (match_operand:X87MODEF 0 "register_operand" "")
5225 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5226 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5228 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5230 && FP_REG_P (operands[0])"
5231 [(set (match_dup 2) (match_dup 1))
5232 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5235 [(set (match_operand:X87MODEF 0 "register_operand" "")
5236 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5237 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5239 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5241 && FP_REG_P (operands[0])"
5242 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5244 ;; Avoid store forwarding (partial memory) stall penalty
5245 ;; by passing DImode value through XMM registers. */
5247 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5248 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5250 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5251 (clobber (match_scratch:V4SI 3 "=X,x"))
5252 (clobber (match_scratch:V4SI 4 "=X,x"))
5253 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5254 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5255 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5256 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5258 [(set_attr "type" "multi")
5259 (set_attr "mode" "<X87MODEF:MODE>")
5260 (set_attr "unit" "i387")
5261 (set_attr "fp_int_src" "true")])
5264 [(set (match_operand:X87MODEF 0 "register_operand" "")
5265 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5266 (clobber (match_scratch:V4SI 3 ""))
5267 (clobber (match_scratch:V4SI 4 ""))
5268 (clobber (match_operand:DI 2 "memory_operand" ""))]
5269 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5270 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5271 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5273 && FP_REG_P (operands[0])"
5274 [(set (match_dup 2) (match_dup 3))
5275 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5277 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5278 Assemble the 64-bit DImode value in an xmm register. */
5279 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5280 gen_rtx_SUBREG (SImode, operands[1], 0)));
5281 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5282 gen_rtx_SUBREG (SImode, operands[1], 4)));
5283 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5286 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5290 [(set (match_operand:X87MODEF 0 "register_operand" "")
5291 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5292 (clobber (match_scratch:V4SI 3 ""))
5293 (clobber (match_scratch:V4SI 4 ""))
5294 (clobber (match_operand:DI 2 "memory_operand" ""))]
5295 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5296 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5297 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5299 && FP_REG_P (operands[0])"
5300 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5302 ;; Avoid store forwarding (partial memory) stall penalty by extending
5303 ;; SImode value to DImode through XMM register instead of pushing two
5304 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5305 ;; targets benefit from this optimization. Also note that fild
5306 ;; loads from memory only.
5308 (define_insn "*floatunssi<mode>2_1"
5309 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5310 (unsigned_float:X87MODEF
5311 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5312 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5313 (clobber (match_scratch:SI 3 "=X,x"))]
5315 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5318 [(set_attr "type" "multi")
5319 (set_attr "mode" "<MODE>")])
5322 [(set (match_operand:X87MODEF 0 "register_operand" "")
5323 (unsigned_float:X87MODEF
5324 (match_operand:SI 1 "register_operand" "")))
5325 (clobber (match_operand:DI 2 "memory_operand" ""))
5326 (clobber (match_scratch:SI 3 ""))]
5328 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5330 && reload_completed"
5331 [(set (match_dup 2) (match_dup 1))
5333 (float:X87MODEF (match_dup 2)))]
5334 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5337 [(set (match_operand:X87MODEF 0 "register_operand" "")
5338 (unsigned_float:X87MODEF
5339 (match_operand:SI 1 "memory_operand" "")))
5340 (clobber (match_operand:DI 2 "memory_operand" ""))
5341 (clobber (match_scratch:SI 3 ""))]
5343 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5345 && reload_completed"
5346 [(set (match_dup 2) (match_dup 3))
5348 (float:X87MODEF (match_dup 2)))]
5350 emit_move_insn (operands[3], operands[1]);
5351 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5354 (define_expand "floatunssi<mode>2"
5356 [(set (match_operand:X87MODEF 0 "register_operand" "")
5357 (unsigned_float:X87MODEF
5358 (match_operand:SI 1 "nonimmediate_operand" "")))
5359 (clobber (match_dup 2))
5360 (clobber (match_scratch:SI 3 ""))])]
5362 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5364 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5366 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5368 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5373 enum ix86_stack_slot slot = (virtuals_instantiated
5376 operands[2] = assign_386_stack_local (DImode, slot);
5380 (define_expand "floatunsdisf2"
5381 [(use (match_operand:SF 0 "register_operand" ""))
5382 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5383 "TARGET_64BIT && TARGET_SSE_MATH"
5384 "x86_emit_floatuns (operands); DONE;")
5386 (define_expand "floatunsdidf2"
5387 [(use (match_operand:DF 0 "register_operand" ""))
5388 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5389 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5390 && TARGET_SSE2 && TARGET_SSE_MATH"
5393 x86_emit_floatuns (operands);
5395 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5401 (define_expand "add<mode>3"
5402 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5403 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5404 (match_operand:SDWIM 2 "<general_operand>" "")))]
5406 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5408 (define_insn_and_split "*add<dwi>3_doubleword"
5409 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5411 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5412 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5413 (clobber (reg:CC FLAGS_REG))]
5414 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5417 [(parallel [(set (reg:CC FLAGS_REG)
5418 (unspec:CC [(match_dup 1) (match_dup 2)]
5421 (plus:DWIH (match_dup 1) (match_dup 2)))])
5422 (parallel [(set (match_dup 3)
5426 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5428 (clobber (reg:CC FLAGS_REG))])]
5429 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5431 (define_insn "*add<mode>3_cc"
5432 [(set (reg:CC FLAGS_REG)
5434 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5435 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5437 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5438 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5439 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5440 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5441 [(set_attr "type" "alu")
5442 (set_attr "mode" "<MODE>")])
5444 (define_insn "addqi3_cc"
5445 [(set (reg:CC FLAGS_REG)
5447 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5448 (match_operand:QI 2 "general_operand" "qn,qm")]
5450 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5451 (plus:QI (match_dup 1) (match_dup 2)))]
5452 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5453 "add{b}\t{%2, %0|%0, %2}"
5454 [(set_attr "type" "alu")
5455 (set_attr "mode" "QI")])
5457 (define_insn "*lea_1"
5458 [(set (match_operand:P 0 "register_operand" "=r")
5459 (match_operand:P 1 "no_seg_address_operand" "p"))]
5461 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5462 [(set_attr "type" "lea")
5463 (set_attr "mode" "<MODE>")])
5465 (define_insn "*lea_2"
5466 [(set (match_operand:SI 0 "register_operand" "=r")
5467 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5469 "lea{l}\t{%a1, %0|%0, %a1}"
5470 [(set_attr "type" "lea")
5471 (set_attr "mode" "SI")])
5473 (define_insn "*lea_2_zext"
5474 [(set (match_operand:DI 0 "register_operand" "=r")
5476 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5478 "lea{l}\t{%a1, %k0|%k0, %a1}"
5479 [(set_attr "type" "lea")
5480 (set_attr "mode" "SI")])
5482 (define_insn "*add<mode>_1"
5483 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5485 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5486 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5487 (clobber (reg:CC FLAGS_REG))]
5488 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5490 switch (get_attr_type (insn))
5496 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5497 if (operands[2] == const1_rtx)
5498 return "inc{<imodesuffix>}\t%0";
5501 gcc_assert (operands[2] == constm1_rtx);
5502 return "dec{<imodesuffix>}\t%0";
5506 /* For most processors, ADD is faster than LEA. This alternative
5507 was added to use ADD as much as possible. */
5508 if (which_alternative == 2)
5511 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5514 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5516 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5518 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5522 (cond [(eq_attr "alternative" "3")
5523 (const_string "lea")
5524 (match_operand:SWI48 2 "incdec_operand" "")
5525 (const_string "incdec")
5527 (const_string "alu")))
5528 (set (attr "length_immediate")
5530 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5532 (const_string "*")))
5533 (set_attr "mode" "<MODE>")])
5535 ;; It may seem that nonimmediate operand is proper one for operand 1.
5536 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5537 ;; we take care in ix86_binary_operator_ok to not allow two memory
5538 ;; operands so proper swapping will be done in reload. This allow
5539 ;; patterns constructed from addsi_1 to match.
5541 (define_insn "*addsi_1_zext"
5542 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5544 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5545 (match_operand:SI 2 "general_operand" "g,0,li"))))
5546 (clobber (reg:CC FLAGS_REG))]
5547 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5549 switch (get_attr_type (insn))
5555 if (operands[2] == const1_rtx)
5556 return "inc{l}\t%k0";
5559 gcc_assert (operands[2] == constm1_rtx);
5560 return "dec{l}\t%k0";
5564 /* For most processors, ADD is faster than LEA. This alternative
5565 was added to use ADD as much as possible. */
5566 if (which_alternative == 1)
5569 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5572 if (x86_maybe_negate_const_int (&operands[2], SImode))
5573 return "sub{l}\t{%2, %k0|%k0, %2}";
5575 return "add{l}\t{%2, %k0|%k0, %2}";
5579 (cond [(eq_attr "alternative" "2")
5580 (const_string "lea")
5581 (match_operand:SI 2 "incdec_operand" "")
5582 (const_string "incdec")
5584 (const_string "alu")))
5585 (set (attr "length_immediate")
5587 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5589 (const_string "*")))
5590 (set_attr "mode" "SI")])
5592 (define_insn "*addhi_1"
5593 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5594 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5595 (match_operand:HI 2 "general_operand" "rn,rm")))
5596 (clobber (reg:CC FLAGS_REG))]
5597 "TARGET_PARTIAL_REG_STALL
5598 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5600 switch (get_attr_type (insn))
5603 if (operands[2] == const1_rtx)
5604 return "inc{w}\t%0";
5607 gcc_assert (operands[2] == constm1_rtx);
5608 return "dec{w}\t%0";
5612 if (x86_maybe_negate_const_int (&operands[2], HImode))
5613 return "sub{w}\t{%2, %0|%0, %2}";
5615 return "add{w}\t{%2, %0|%0, %2}";
5619 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5620 (const_string "incdec")
5621 (const_string "alu")))
5622 (set (attr "length_immediate")
5624 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5626 (const_string "*")))
5627 (set_attr "mode" "HI")])
5629 (define_insn "*addhi_1_lea"
5630 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5631 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5632 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5633 (clobber (reg:CC FLAGS_REG))]
5634 "!TARGET_PARTIAL_REG_STALL
5635 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5637 switch (get_attr_type (insn))
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 if (operands[2] == const1_rtx)
5645 return "inc{w}\t%0";
5648 gcc_assert (operands[2] == constm1_rtx);
5649 return "dec{w}\t%0";
5653 /* For most processors, ADD is faster than LEA. This alternative
5654 was added to use ADD as much as possible. */
5655 if (which_alternative == 2)
5658 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5661 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5662 if (x86_maybe_negate_const_int (&operands[2], HImode))
5663 return "sub{w}\t{%2, %0|%0, %2}";
5665 return "add{w}\t{%2, %0|%0, %2}";
5669 (cond [(eq_attr "alternative" "3")
5670 (const_string "lea")
5671 (match_operand:HI 2 "incdec_operand" "")
5672 (const_string "incdec")
5674 (const_string "alu")))
5675 (set (attr "length_immediate")
5677 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5679 (const_string "*")))
5680 (set_attr "mode" "HI,HI,HI,SI")])
5682 ;; %%% Potential partial reg stall on alternative 2. What to do?
5683 (define_insn "*addqi_1"
5684 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5685 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5686 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5687 (clobber (reg:CC FLAGS_REG))]
5688 "TARGET_PARTIAL_REG_STALL
5689 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5691 int widen = (which_alternative == 2);
5692 switch (get_attr_type (insn))
5695 if (operands[2] == const1_rtx)
5696 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5699 gcc_assert (operands[2] == constm1_rtx);
5700 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5704 if (x86_maybe_negate_const_int (&operands[2], QImode))
5707 return "sub{l}\t{%2, %k0|%k0, %2}";
5709 return "sub{b}\t{%2, %0|%0, %2}";
5712 return "add{l}\t{%k2, %k0|%k0, %k2}";
5714 return "add{b}\t{%2, %0|%0, %2}";
5718 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5719 (const_string "incdec")
5720 (const_string "alu")))
5721 (set (attr "length_immediate")
5723 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5725 (const_string "*")))
5726 (set_attr "mode" "QI,QI,SI")])
5728 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5729 (define_insn "*addqi_1_lea"
5730 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5731 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5732 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5733 (clobber (reg:CC FLAGS_REG))]
5734 "!TARGET_PARTIAL_REG_STALL
5735 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5737 int widen = (which_alternative == 3 || which_alternative == 4);
5739 switch (get_attr_type (insn))
5745 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5746 if (operands[2] == const1_rtx)
5747 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5750 gcc_assert (operands[2] == constm1_rtx);
5751 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5755 /* For most processors, ADD is faster than LEA. These alternatives
5756 were added to use ADD as much as possible. */
5757 if (which_alternative == 2 || which_alternative == 4)
5760 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5763 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5764 if (x86_maybe_negate_const_int (&operands[2], QImode))
5767 return "sub{l}\t{%2, %k0|%k0, %2}";
5769 return "sub{b}\t{%2, %0|%0, %2}";
5772 return "add{l}\t{%k2, %k0|%k0, %k2}";
5774 return "add{b}\t{%2, %0|%0, %2}";
5778 (cond [(eq_attr "alternative" "5")
5779 (const_string "lea")
5780 (match_operand:QI 2 "incdec_operand" "")
5781 (const_string "incdec")
5783 (const_string "alu")))
5784 (set (attr "length_immediate")
5786 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5788 (const_string "*")))
5789 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5791 (define_insn "*addqi_1_slp"
5792 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5793 (plus:QI (match_dup 0)
5794 (match_operand:QI 1 "general_operand" "qn,qnm")))
5795 (clobber (reg:CC FLAGS_REG))]
5796 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5797 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5799 switch (get_attr_type (insn))
5802 if (operands[1] == const1_rtx)
5803 return "inc{b}\t%0";
5806 gcc_assert (operands[1] == constm1_rtx);
5807 return "dec{b}\t%0";
5811 if (x86_maybe_negate_const_int (&operands[1], QImode))
5812 return "sub{b}\t{%1, %0|%0, %1}";
5814 return "add{b}\t{%1, %0|%0, %1}";
5818 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5819 (const_string "incdec")
5820 (const_string "alu1")))
5821 (set (attr "memory")
5822 (if_then_else (match_operand 1 "memory_operand" "")
5823 (const_string "load")
5824 (const_string "none")))
5825 (set_attr "mode" "QI")])
5827 ;; Convert lea to the lea pattern to avoid flags dependency.
5829 [(set (match_operand 0 "register_operand" "")
5830 (plus (match_operand 1 "register_operand" "")
5831 (match_operand 2 "nonmemory_operand" "")))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5837 enum machine_mode mode = GET_MODE (operands[0]);
5839 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5840 may confuse gen_lowpart. */
5843 operands[1] = gen_lowpart (Pmode, operands[1]);
5844 operands[2] = gen_lowpart (Pmode, operands[2]);
5847 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5849 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5850 operands[0] = gen_lowpart (SImode, operands[0]);
5852 if (TARGET_64BIT && mode != Pmode)
5853 pat = gen_rtx_SUBREG (SImode, pat, 0);
5855 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5859 ;; Convert lea to the lea pattern to avoid flags dependency.
5860 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5861 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5863 [(set (match_operand:DI 0 "register_operand" "")
5864 (plus:DI (match_operand:DI 1 "register_operand" "")
5865 (match_operand:DI 2 "x86_64_immediate_operand" "")))
5866 (clobber (reg:CC FLAGS_REG))]
5867 "TARGET_64BIT && reload_completed
5868 && true_regnum (operands[0]) != true_regnum (operands[1])"
5870 (plus:DI (match_dup 1) (match_dup 2)))])
5872 ;; Convert lea to the lea pattern to avoid flags dependency.
5874 [(set (match_operand:DI 0 "register_operand" "")
5876 (plus:SI (match_operand:SI 1 "register_operand" "")
5877 (match_operand:SI 2 "nonmemory_operand" ""))))
5878 (clobber (reg:CC FLAGS_REG))]
5879 "TARGET_64BIT && reload_completed
5880 && ix86_lea_for_add_ok (insn, operands)"
5882 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5884 operands[1] = gen_lowpart (DImode, operands[1]);
5885 operands[2] = gen_lowpart (DImode, operands[2]);
5888 (define_insn "*add<mode>_2"
5889 [(set (reg FLAGS_REG)
5892 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5893 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5895 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5896 (plus:SWI (match_dup 1) (match_dup 2)))]
5897 "ix86_match_ccmode (insn, CCGOCmode)
5898 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5900 switch (get_attr_type (insn))
5903 if (operands[2] == const1_rtx)
5904 return "inc{<imodesuffix>}\t%0";
5907 gcc_assert (operands[2] == constm1_rtx);
5908 return "dec{<imodesuffix>}\t%0";
5912 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5913 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5915 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5919 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5920 (const_string "incdec")
5921 (const_string "alu")))
5922 (set (attr "length_immediate")
5924 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5926 (const_string "*")))
5927 (set_attr "mode" "<MODE>")])
5929 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5930 (define_insn "*addsi_2_zext"
5931 [(set (reg FLAGS_REG)
5933 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5934 (match_operand:SI 2 "general_operand" "g"))
5936 (set (match_operand:DI 0 "register_operand" "=r")
5937 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5938 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5939 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5941 switch (get_attr_type (insn))
5944 if (operands[2] == const1_rtx)
5945 return "inc{l}\t%k0";
5948 gcc_assert (operands[2] == constm1_rtx);
5949 return "dec{l}\t%k0";
5953 if (x86_maybe_negate_const_int (&operands[2], SImode))
5954 return "sub{l}\t{%2, %k0|%k0, %2}";
5956 return "add{l}\t{%2, %k0|%k0, %2}";
5960 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5961 (const_string "incdec")
5962 (const_string "alu")))
5963 (set (attr "length_immediate")
5965 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5967 (const_string "*")))
5968 (set_attr "mode" "SI")])
5970 (define_insn "*add<mode>_3"
5971 [(set (reg FLAGS_REG)
5973 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5974 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5975 (clobber (match_scratch:SWI 0 "=<r>"))]
5976 "ix86_match_ccmode (insn, CCZmode)
5977 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5979 switch (get_attr_type (insn))
5982 if (operands[2] == const1_rtx)
5983 return "inc{<imodesuffix>}\t%0";
5986 gcc_assert (operands[2] == constm1_rtx);
5987 return "dec{<imodesuffix>}\t%0";
5991 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5992 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5994 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5998 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5999 (const_string "incdec")
6000 (const_string "alu")))
6001 (set (attr "length_immediate")
6003 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6005 (const_string "*")))
6006 (set_attr "mode" "<MODE>")])
6008 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6009 (define_insn "*addsi_3_zext"
6010 [(set (reg FLAGS_REG)
6012 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6013 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6014 (set (match_operand:DI 0 "register_operand" "=r")
6015 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6016 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6017 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6019 switch (get_attr_type (insn))
6022 if (operands[2] == const1_rtx)
6023 return "inc{l}\t%k0";
6026 gcc_assert (operands[2] == constm1_rtx);
6027 return "dec{l}\t%k0";
6031 if (x86_maybe_negate_const_int (&operands[2], SImode))
6032 return "sub{l}\t{%2, %k0|%k0, %2}";
6034 return "add{l}\t{%2, %k0|%k0, %2}";
6038 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6039 (const_string "incdec")
6040 (const_string "alu")))
6041 (set (attr "length_immediate")
6043 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6045 (const_string "*")))
6046 (set_attr "mode" "SI")])
6048 ; For comparisons against 1, -1 and 128, we may generate better code
6049 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6050 ; is matched then. We can't accept general immediate, because for
6051 ; case of overflows, the result is messed up.
6052 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6053 ; only for comparisons not depending on it.
6055 (define_insn "*adddi_4"
6056 [(set (reg FLAGS_REG)
6058 (match_operand:DI 1 "nonimmediate_operand" "0")
6059 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6060 (clobber (match_scratch:DI 0 "=rm"))]
6062 && ix86_match_ccmode (insn, CCGCmode)"
6064 switch (get_attr_type (insn))
6067 if (operands[2] == constm1_rtx)
6068 return "inc{q}\t%0";
6071 gcc_assert (operands[2] == const1_rtx);
6072 return "dec{q}\t%0";
6076 if (x86_maybe_negate_const_int (&operands[2], DImode))
6077 return "add{q}\t{%2, %0|%0, %2}";
6079 return "sub{q}\t{%2, %0|%0, %2}";
6083 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6084 (const_string "incdec")
6085 (const_string "alu")))
6086 (set (attr "length_immediate")
6088 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6090 (const_string "*")))
6091 (set_attr "mode" "DI")])
6093 ; For comparisons against 1, -1 and 128, we may generate better code
6094 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6095 ; is matched then. We can't accept general immediate, because for
6096 ; case of overflows, the result is messed up.
6097 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6098 ; only for comparisons not depending on it.
6100 (define_insn "*add<mode>_4"
6101 [(set (reg FLAGS_REG)
6103 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6104 (match_operand:SWI124 2 "const_int_operand" "n")))
6105 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6106 "ix86_match_ccmode (insn, CCGCmode)"
6108 switch (get_attr_type (insn))
6111 if (operands[2] == constm1_rtx)
6112 return "inc{<imodesuffix>}\t%0";
6115 gcc_assert (operands[2] == const1_rtx);
6116 return "dec{<imodesuffix>}\t%0";
6120 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6121 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6123 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6127 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6128 (const_string "incdec")
6129 (const_string "alu")))
6130 (set (attr "length_immediate")
6132 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6134 (const_string "*")))
6135 (set_attr "mode" "<MODE>")])
6137 (define_insn "*add<mode>_5"
6138 [(set (reg FLAGS_REG)
6141 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6142 (match_operand:SWI 2 "<general_operand>" "<g>"))
6144 (clobber (match_scratch:SWI 0 "=<r>"))]
6145 "ix86_match_ccmode (insn, CCGOCmode)
6146 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6148 switch (get_attr_type (insn))
6151 if (operands[2] == const1_rtx)
6152 return "inc{<imodesuffix>}\t%0";
6155 gcc_assert (operands[2] == constm1_rtx);
6156 return "dec{<imodesuffix>}\t%0";
6160 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6161 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6163 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6167 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6168 (const_string "incdec")
6169 (const_string "alu")))
6170 (set (attr "length_immediate")
6172 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6174 (const_string "*")))
6175 (set_attr "mode" "<MODE>")])
6177 (define_insn "*addqi_ext_1_rex64"
6178 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6183 (match_operand 1 "ext_register_operand" "0")
6186 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6187 (clobber (reg:CC FLAGS_REG))]
6190 switch (get_attr_type (insn))
6193 if (operands[2] == const1_rtx)
6194 return "inc{b}\t%h0";
6197 gcc_assert (operands[2] == constm1_rtx);
6198 return "dec{b}\t%h0";
6202 return "add{b}\t{%2, %h0|%h0, %2}";
6206 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6207 (const_string "incdec")
6208 (const_string "alu")))
6209 (set_attr "modrm" "1")
6210 (set_attr "mode" "QI")])
6212 (define_insn "addqi_ext_1"
6213 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6218 (match_operand 1 "ext_register_operand" "0")
6221 (match_operand:QI 2 "general_operand" "Qmn")))
6222 (clobber (reg:CC FLAGS_REG))]
6225 switch (get_attr_type (insn))
6228 if (operands[2] == const1_rtx)
6229 return "inc{b}\t%h0";
6232 gcc_assert (operands[2] == constm1_rtx);
6233 return "dec{b}\t%h0";
6237 return "add{b}\t{%2, %h0|%h0, %2}";
6241 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6242 (const_string "incdec")
6243 (const_string "alu")))
6244 (set_attr "modrm" "1")
6245 (set_attr "mode" "QI")])
6247 (define_insn "*addqi_ext_2"
6248 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6253 (match_operand 1 "ext_register_operand" "%0")
6257 (match_operand 2 "ext_register_operand" "Q")
6260 (clobber (reg:CC FLAGS_REG))]
6262 "add{b}\t{%h2, %h0|%h0, %h2}"
6263 [(set_attr "type" "alu")
6264 (set_attr "mode" "QI")])
6266 ;; The lea patterns for non-Pmodes needs to be matched by
6267 ;; several insns converted to real lea by splitters.
6269 (define_insn_and_split "*lea_general_1"
6270 [(set (match_operand 0 "register_operand" "=r")
6271 (plus (plus (match_operand 1 "index_register_operand" "l")
6272 (match_operand 2 "register_operand" "r"))
6273 (match_operand 3 "immediate_operand" "i")))]
6274 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6275 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6276 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6277 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6278 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6279 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6280 || GET_MODE (operands[3]) == VOIDmode)"
6282 "&& reload_completed"
6286 operands[0] = gen_lowpart (SImode, operands[0]);
6287 operands[1] = gen_lowpart (Pmode, operands[1]);
6288 operands[2] = gen_lowpart (Pmode, operands[2]);
6289 operands[3] = gen_lowpart (Pmode, operands[3]);
6290 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6292 if (Pmode != SImode)
6293 pat = gen_rtx_SUBREG (SImode, pat, 0);
6294 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6297 [(set_attr "type" "lea")
6298 (set_attr "mode" "SI")])
6300 (define_insn_and_split "*lea_general_1_zext"
6301 [(set (match_operand:DI 0 "register_operand" "=r")
6304 (match_operand:SI 1 "index_register_operand" "l")
6305 (match_operand:SI 2 "register_operand" "r"))
6306 (match_operand:SI 3 "immediate_operand" "i"))))]
6309 "&& reload_completed"
6311 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6313 (match_dup 3)) 0)))]
6315 operands[1] = gen_lowpart (Pmode, operands[1]);
6316 operands[2] = gen_lowpart (Pmode, operands[2]);
6317 operands[3] = gen_lowpart (Pmode, operands[3]);
6319 [(set_attr "type" "lea")
6320 (set_attr "mode" "SI")])
6322 (define_insn_and_split "*lea_general_2"
6323 [(set (match_operand 0 "register_operand" "=r")
6324 (plus (mult (match_operand 1 "index_register_operand" "l")
6325 (match_operand 2 "const248_operand" "i"))
6326 (match_operand 3 "nonmemory_operand" "ri")))]
6327 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6328 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6329 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6330 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6331 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6332 || GET_MODE (operands[3]) == VOIDmode)"
6334 "&& reload_completed"
6338 operands[0] = gen_lowpart (SImode, operands[0]);
6339 operands[1] = gen_lowpart (Pmode, operands[1]);
6340 operands[3] = gen_lowpart (Pmode, operands[3]);
6341 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6343 if (Pmode != SImode)
6344 pat = gen_rtx_SUBREG (SImode, pat, 0);
6345 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6348 [(set_attr "type" "lea")
6349 (set_attr "mode" "SI")])
6351 (define_insn_and_split "*lea_general_2_zext"
6352 [(set (match_operand:DI 0 "register_operand" "=r")
6355 (match_operand:SI 1 "index_register_operand" "l")
6356 (match_operand:SI 2 "const248_operand" "n"))
6357 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6360 "&& reload_completed"
6362 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6364 (match_dup 3)) 0)))]
6366 operands[1] = gen_lowpart (Pmode, operands[1]);
6367 operands[3] = gen_lowpart (Pmode, operands[3]);
6369 [(set_attr "type" "lea")
6370 (set_attr "mode" "SI")])
6372 (define_insn_and_split "*lea_general_3"
6373 [(set (match_operand 0 "register_operand" "=r")
6374 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6375 (match_operand 2 "const248_operand" "i"))
6376 (match_operand 3 "register_operand" "r"))
6377 (match_operand 4 "immediate_operand" "i")))]
6378 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6379 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6380 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6381 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6382 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6384 "&& reload_completed"
6388 operands[0] = gen_lowpart (SImode, operands[0]);
6389 operands[1] = gen_lowpart (Pmode, operands[1]);
6390 operands[3] = gen_lowpart (Pmode, operands[3]);
6391 operands[4] = gen_lowpart (Pmode, operands[4]);
6392 pat = gen_rtx_PLUS (Pmode,
6393 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6397 if (Pmode != SImode)
6398 pat = gen_rtx_SUBREG (SImode, pat, 0);
6399 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6402 [(set_attr "type" "lea")
6403 (set_attr "mode" "SI")])
6405 (define_insn_and_split "*lea_general_3_zext"
6406 [(set (match_operand:DI 0 "register_operand" "=r")
6410 (match_operand:SI 1 "index_register_operand" "l")
6411 (match_operand:SI 2 "const248_operand" "n"))
6412 (match_operand:SI 3 "register_operand" "r"))
6413 (match_operand:SI 4 "immediate_operand" "i"))))]
6416 "&& reload_completed"
6418 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6421 (match_dup 4)) 0)))]
6423 operands[1] = gen_lowpart (Pmode, operands[1]);
6424 operands[3] = gen_lowpart (Pmode, operands[3]);
6425 operands[4] = gen_lowpart (Pmode, operands[4]);
6427 [(set_attr "type" "lea")
6428 (set_attr "mode" "SI")])
6430 ;; Subtract instructions
6432 (define_expand "sub<mode>3"
6433 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6434 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6435 (match_operand:SDWIM 2 "<general_operand>" "")))]
6437 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6439 (define_insn_and_split "*sub<dwi>3_doubleword"
6440 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6442 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6443 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6444 (clobber (reg:CC FLAGS_REG))]
6445 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6448 [(parallel [(set (reg:CC FLAGS_REG)
6449 (compare:CC (match_dup 1) (match_dup 2)))
6451 (minus:DWIH (match_dup 1) (match_dup 2)))])
6452 (parallel [(set (match_dup 3)
6456 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6458 (clobber (reg:CC FLAGS_REG))])]
6459 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6461 (define_insn "*sub<mode>_1"
6462 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6464 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6465 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6466 (clobber (reg:CC FLAGS_REG))]
6467 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6468 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6469 [(set_attr "type" "alu")
6470 (set_attr "mode" "<MODE>")])
6472 (define_insn "*subsi_1_zext"
6473 [(set (match_operand:DI 0 "register_operand" "=r")
6475 (minus:SI (match_operand:SI 1 "register_operand" "0")
6476 (match_operand:SI 2 "general_operand" "g"))))
6477 (clobber (reg:CC FLAGS_REG))]
6478 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6479 "sub{l}\t{%2, %k0|%k0, %2}"
6480 [(set_attr "type" "alu")
6481 (set_attr "mode" "SI")])
6483 (define_insn "*subqi_1_slp"
6484 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6485 (minus:QI (match_dup 0)
6486 (match_operand:QI 1 "general_operand" "qn,qm")))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6489 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6490 "sub{b}\t{%1, %0|%0, %1}"
6491 [(set_attr "type" "alu1")
6492 (set_attr "mode" "QI")])
6494 (define_insn "*sub<mode>_2"
6495 [(set (reg FLAGS_REG)
6498 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6499 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6501 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6502 (minus:SWI (match_dup 1) (match_dup 2)))]
6503 "ix86_match_ccmode (insn, CCGOCmode)
6504 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6505 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "mode" "<MODE>")])
6509 (define_insn "*subsi_2_zext"
6510 [(set (reg FLAGS_REG)
6512 (minus:SI (match_operand:SI 1 "register_operand" "0")
6513 (match_operand:SI 2 "general_operand" "g"))
6515 (set (match_operand:DI 0 "register_operand" "=r")
6517 (minus:SI (match_dup 1)
6519 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6520 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6521 "sub{l}\t{%2, %k0|%k0, %2}"
6522 [(set_attr "type" "alu")
6523 (set_attr "mode" "SI")])
6525 (define_insn "*sub<mode>_3"
6526 [(set (reg FLAGS_REG)
6527 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6528 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6529 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6530 (minus:SWI (match_dup 1) (match_dup 2)))]
6531 "ix86_match_ccmode (insn, CCmode)
6532 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6533 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6534 [(set_attr "type" "alu")
6535 (set_attr "mode" "<MODE>")])
6537 (define_insn "*subsi_3_zext"
6538 [(set (reg FLAGS_REG)
6539 (compare (match_operand:SI 1 "register_operand" "0")
6540 (match_operand:SI 2 "general_operand" "g")))
6541 (set (match_operand:DI 0 "register_operand" "=r")
6543 (minus:SI (match_dup 1)
6545 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6546 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6547 "sub{l}\t{%2, %1|%1, %2}"
6548 [(set_attr "type" "alu")
6549 (set_attr "mode" "SI")])
6551 ;; Add with carry and subtract with borrow
6553 (define_expand "<plusminus_insn><mode>3_carry"
6555 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6557 (match_operand:SWI 1 "nonimmediate_operand" "")
6558 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6559 [(match_operand 3 "flags_reg_operand" "")
6561 (match_operand:SWI 2 "<general_operand>" ""))))
6562 (clobber (reg:CC FLAGS_REG))])]
6563 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6565 (define_insn "*<plusminus_insn><mode>3_carry"
6566 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6568 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6570 (match_operator 3 "ix86_carry_flag_operator"
6571 [(reg FLAGS_REG) (const_int 0)])
6572 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6573 (clobber (reg:CC FLAGS_REG))]
6574 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6575 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6576 [(set_attr "type" "alu")
6577 (set_attr "use_carry" "1")
6578 (set_attr "pent_pair" "pu")
6579 (set_attr "mode" "<MODE>")])
6581 (define_insn "*addsi3_carry_zext"
6582 [(set (match_operand:DI 0 "register_operand" "=r")
6584 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6585 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6586 [(reg FLAGS_REG) (const_int 0)])
6587 (match_operand:SI 2 "general_operand" "g")))))
6588 (clobber (reg:CC FLAGS_REG))]
6589 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6590 "adc{l}\t{%2, %k0|%k0, %2}"
6591 [(set_attr "type" "alu")
6592 (set_attr "use_carry" "1")
6593 (set_attr "pent_pair" "pu")
6594 (set_attr "mode" "SI")])
6596 (define_insn "*subsi3_carry_zext"
6597 [(set (match_operand:DI 0 "register_operand" "=r")
6599 (minus:SI (match_operand:SI 1 "register_operand" "0")
6600 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6601 [(reg FLAGS_REG) (const_int 0)])
6602 (match_operand:SI 2 "general_operand" "g")))))
6603 (clobber (reg:CC FLAGS_REG))]
6604 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6605 "sbb{l}\t{%2, %k0|%k0, %2}"
6606 [(set_attr "type" "alu")
6607 (set_attr "pent_pair" "pu")
6608 (set_attr "mode" "SI")])
6610 ;; Overflow setting add and subtract instructions
6612 (define_insn "*add<mode>3_cconly_overflow"
6613 [(set (reg:CCC FLAGS_REG)
6616 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6617 (match_operand:SWI 2 "<general_operand>" "<g>"))
6619 (clobber (match_scratch:SWI 0 "=<r>"))]
6620 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6621 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6622 [(set_attr "type" "alu")
6623 (set_attr "mode" "<MODE>")])
6625 (define_insn "*sub<mode>3_cconly_overflow"
6626 [(set (reg:CCC FLAGS_REG)
6629 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6630 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6633 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6634 [(set_attr "type" "icmp")
6635 (set_attr "mode" "<MODE>")])
6637 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6638 [(set (reg:CCC FLAGS_REG)
6641 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6642 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6644 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6645 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6646 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6647 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "mode" "<MODE>")])
6651 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6652 [(set (reg:CCC FLAGS_REG)
6655 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6656 (match_operand:SI 2 "general_operand" "g"))
6658 (set (match_operand:DI 0 "register_operand" "=r")
6659 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6660 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6661 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6662 [(set_attr "type" "alu")
6663 (set_attr "mode" "SI")])
6665 ;; The patterns that match these are at the end of this file.
6667 (define_expand "<plusminus_insn>xf3"
6668 [(set (match_operand:XF 0 "register_operand" "")
6670 (match_operand:XF 1 "register_operand" "")
6671 (match_operand:XF 2 "register_operand" "")))]
6674 (define_expand "<plusminus_insn><mode>3"
6675 [(set (match_operand:MODEF 0 "register_operand" "")
6677 (match_operand:MODEF 1 "register_operand" "")
6678 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6679 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6680 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6682 ;; Multiply instructions
6684 (define_expand "mul<mode>3"
6685 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6687 (match_operand:SWIM248 1 "register_operand" "")
6688 (match_operand:SWIM248 2 "<general_operand>" "")))
6689 (clobber (reg:CC FLAGS_REG))])])
6691 (define_expand "mulqi3"
6692 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6694 (match_operand:QI 1 "register_operand" "")
6695 (match_operand:QI 2 "nonimmediate_operand" "")))
6696 (clobber (reg:CC FLAGS_REG))])]
6697 "TARGET_QIMODE_MATH")
6700 ;; IMUL reg32/64, reg32/64, imm8 Direct
6701 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6702 ;; IMUL reg32/64, reg32/64, imm32 Direct
6703 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6704 ;; IMUL reg32/64, reg32/64 Direct
6705 ;; IMUL reg32/64, mem32/64 Direct
6707 ;; On BDVER1, all above IMULs use DirectPath
6709 (define_insn "*mul<mode>3_1"
6710 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6712 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6713 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6714 (clobber (reg:CC FLAGS_REG))]
6715 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6717 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6718 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6719 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6720 [(set_attr "type" "imul")
6721 (set_attr "prefix_0f" "0,0,1")
6722 (set (attr "athlon_decode")
6723 (cond [(eq_attr "cpu" "athlon")
6724 (const_string "vector")
6725 (eq_attr "alternative" "1")
6726 (const_string "vector")
6727 (and (eq_attr "alternative" "2")
6728 (match_operand 1 "memory_operand" ""))
6729 (const_string "vector")]
6730 (const_string "direct")))
6731 (set (attr "amdfam10_decode")
6732 (cond [(and (eq_attr "alternative" "0,1")
6733 (match_operand 1 "memory_operand" ""))
6734 (const_string "vector")]
6735 (const_string "direct")))
6736 (set_attr "bdver1_decode" "direct")
6737 (set_attr "mode" "<MODE>")])
6739 (define_insn "*mulsi3_1_zext"
6740 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6742 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6743 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6744 (clobber (reg:CC FLAGS_REG))]
6746 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6748 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6749 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6750 imul{l}\t{%2, %k0|%k0, %2}"
6751 [(set_attr "type" "imul")
6752 (set_attr "prefix_0f" "0,0,1")
6753 (set (attr "athlon_decode")
6754 (cond [(eq_attr "cpu" "athlon")
6755 (const_string "vector")
6756 (eq_attr "alternative" "1")
6757 (const_string "vector")
6758 (and (eq_attr "alternative" "2")
6759 (match_operand 1 "memory_operand" ""))
6760 (const_string "vector")]
6761 (const_string "direct")))
6762 (set (attr "amdfam10_decode")
6763 (cond [(and (eq_attr "alternative" "0,1")
6764 (match_operand 1 "memory_operand" ""))
6765 (const_string "vector")]
6766 (const_string "direct")))
6767 (set_attr "bdver1_decode" "direct")
6768 (set_attr "mode" "SI")])
6771 ;; IMUL reg16, reg16, imm8 VectorPath
6772 ;; IMUL reg16, mem16, imm8 VectorPath
6773 ;; IMUL reg16, reg16, imm16 VectorPath
6774 ;; IMUL reg16, mem16, imm16 VectorPath
6775 ;; IMUL reg16, reg16 Direct
6776 ;; IMUL reg16, mem16 Direct
6778 ;; On BDVER1, all HI MULs use DoublePath
6780 (define_insn "*mulhi3_1"
6781 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6782 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6783 (match_operand:HI 2 "general_operand" "K,n,mr")))
6784 (clobber (reg:CC FLAGS_REG))]
6786 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6788 imul{w}\t{%2, %1, %0|%0, %1, %2}
6789 imul{w}\t{%2, %1, %0|%0, %1, %2}
6790 imul{w}\t{%2, %0|%0, %2}"
6791 [(set_attr "type" "imul")
6792 (set_attr "prefix_0f" "0,0,1")
6793 (set (attr "athlon_decode")
6794 (cond [(eq_attr "cpu" "athlon")
6795 (const_string "vector")
6796 (eq_attr "alternative" "1,2")
6797 (const_string "vector")]
6798 (const_string "direct")))
6799 (set (attr "amdfam10_decode")
6800 (cond [(eq_attr "alternative" "0,1")
6801 (const_string "vector")]
6802 (const_string "direct")))
6803 (set_attr "bdver1_decode" "double")
6804 (set_attr "mode" "HI")])
6806 ;;On AMDFAM10 and BDVER1
6810 (define_insn "*mulqi3_1"
6811 [(set (match_operand:QI 0 "register_operand" "=a")
6812 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6813 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6814 (clobber (reg:CC FLAGS_REG))]
6816 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6818 [(set_attr "type" "imul")
6819 (set_attr "length_immediate" "0")
6820 (set (attr "athlon_decode")
6821 (if_then_else (eq_attr "cpu" "athlon")
6822 (const_string "vector")
6823 (const_string "direct")))
6824 (set_attr "amdfam10_decode" "direct")
6825 (set_attr "bdver1_decode" "direct")
6826 (set_attr "mode" "QI")])
6828 (define_expand "<u>mul<mode><dwi>3"
6829 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6832 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6834 (match_operand:DWIH 2 "register_operand" ""))))
6835 (clobber (reg:CC FLAGS_REG))])])
6837 (define_expand "<u>mulqihi3"
6838 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6841 (match_operand:QI 1 "nonimmediate_operand" ""))
6843 (match_operand:QI 2 "register_operand" ""))))
6844 (clobber (reg:CC FLAGS_REG))])]
6845 "TARGET_QIMODE_MATH")
6847 (define_insn "*<u>mul<mode><dwi>3_1"
6848 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6851 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6853 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6854 (clobber (reg:CC FLAGS_REG))]
6855 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 "<sgnprefix>mul{<imodesuffix>}\t%2"
6857 [(set_attr "type" "imul")
6858 (set_attr "length_immediate" "0")
6859 (set (attr "athlon_decode")
6860 (if_then_else (eq_attr "cpu" "athlon")
6861 (const_string "vector")
6862 (const_string "double")))
6863 (set_attr "amdfam10_decode" "double")
6864 (set_attr "bdver1_decode" "direct")
6865 (set_attr "mode" "<MODE>")])
6867 (define_insn "*<u>mulqihi3_1"
6868 [(set (match_operand:HI 0 "register_operand" "=a")
6871 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6873 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6874 (clobber (reg:CC FLAGS_REG))]
6876 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6877 "<sgnprefix>mul{b}\t%2"
6878 [(set_attr "type" "imul")
6879 (set_attr "length_immediate" "0")
6880 (set (attr "athlon_decode")
6881 (if_then_else (eq_attr "cpu" "athlon")
6882 (const_string "vector")
6883 (const_string "direct")))
6884 (set_attr "amdfam10_decode" "direct")
6885 (set_attr "bdver1_decode" "direct")
6886 (set_attr "mode" "QI")])
6888 (define_expand "<s>mul<mode>3_highpart"
6889 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6894 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6896 (match_operand:SWI48 2 "register_operand" "")))
6898 (clobber (match_scratch:SWI48 3 ""))
6899 (clobber (reg:CC FLAGS_REG))])]
6901 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6903 (define_insn "*<s>muldi3_highpart_1"
6904 [(set (match_operand:DI 0 "register_operand" "=d")
6909 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6911 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6913 (clobber (match_scratch:DI 3 "=1"))
6914 (clobber (reg:CC FLAGS_REG))]
6916 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917 "<sgnprefix>mul{q}\t%2"
6918 [(set_attr "type" "imul")
6919 (set_attr "length_immediate" "0")
6920 (set (attr "athlon_decode")
6921 (if_then_else (eq_attr "cpu" "athlon")
6922 (const_string "vector")
6923 (const_string "double")))
6924 (set_attr "amdfam10_decode" "double")
6925 (set_attr "bdver1_decode" "direct")
6926 (set_attr "mode" "DI")])
6928 (define_insn "*<s>mulsi3_highpart_1"
6929 [(set (match_operand:SI 0 "register_operand" "=d")
6934 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6936 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6938 (clobber (match_scratch:SI 3 "=1"))
6939 (clobber (reg:CC FLAGS_REG))]
6940 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6941 "<sgnprefix>mul{l}\t%2"
6942 [(set_attr "type" "imul")
6943 (set_attr "length_immediate" "0")
6944 (set (attr "athlon_decode")
6945 (if_then_else (eq_attr "cpu" "athlon")
6946 (const_string "vector")
6947 (const_string "double")))
6948 (set_attr "amdfam10_decode" "double")
6949 (set_attr "bdver1_decode" "direct")
6950 (set_attr "mode" "SI")])
6952 (define_insn "*<s>mulsi3_highpart_zext"
6953 [(set (match_operand:DI 0 "register_operand" "=d")
6954 (zero_extend:DI (truncate:SI
6956 (mult:DI (any_extend:DI
6957 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6959 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6961 (clobber (match_scratch:SI 3 "=1"))
6962 (clobber (reg:CC FLAGS_REG))]
6964 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6965 "<sgnprefix>mul{l}\t%2"
6966 [(set_attr "type" "imul")
6967 (set_attr "length_immediate" "0")
6968 (set (attr "athlon_decode")
6969 (if_then_else (eq_attr "cpu" "athlon")
6970 (const_string "vector")
6971 (const_string "double")))
6972 (set_attr "amdfam10_decode" "double")
6973 (set_attr "bdver1_decode" "direct")
6974 (set_attr "mode" "SI")])
6976 ;; The patterns that match these are at the end of this file.
6978 (define_expand "mulxf3"
6979 [(set (match_operand:XF 0 "register_operand" "")
6980 (mult:XF (match_operand:XF 1 "register_operand" "")
6981 (match_operand:XF 2 "register_operand" "")))]
6984 (define_expand "mul<mode>3"
6985 [(set (match_operand:MODEF 0 "register_operand" "")
6986 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6987 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6988 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6989 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6991 ;; Divide instructions
6993 ;; The patterns that match these are at the end of this file.
6995 (define_expand "divxf3"
6996 [(set (match_operand:XF 0 "register_operand" "")
6997 (div:XF (match_operand:XF 1 "register_operand" "")
6998 (match_operand:XF 2 "register_operand" "")))]
7001 (define_expand "divdf3"
7002 [(set (match_operand:DF 0 "register_operand" "")
7003 (div:DF (match_operand:DF 1 "register_operand" "")
7004 (match_operand:DF 2 "nonimmediate_operand" "")))]
7005 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7006 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7008 (define_expand "divsf3"
7009 [(set (match_operand:SF 0 "register_operand" "")
7010 (div:SF (match_operand:SF 1 "register_operand" "")
7011 (match_operand:SF 2 "nonimmediate_operand" "")))]
7012 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7015 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7016 && flag_finite_math_only && !flag_trapping_math
7017 && flag_unsafe_math_optimizations)
7019 ix86_emit_swdivsf (operands[0], operands[1],
7020 operands[2], SFmode);
7025 ;; Divmod instructions.
7027 (define_expand "divmod<mode>4"
7028 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7030 (match_operand:SWIM248 1 "register_operand" "")
7031 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7032 (set (match_operand:SWIM248 3 "register_operand" "")
7033 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7034 (clobber (reg:CC FLAGS_REG))])])
7036 ;; Split with 8bit unsigned divide:
7037 ;; if (dividend an divisor are in [0-255])
7038 ;; use 8bit unsigned integer divide
7040 ;; use original integer divide
7042 [(set (match_operand:SWI48 0 "register_operand" "")
7043 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7044 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7045 (set (match_operand:SWI48 1 "register_operand" "")
7046 (mod:SWI48 (match_dup 2) (match_dup 3)))
7047 (clobber (reg:CC FLAGS_REG))]
7048 "TARGET_USE_8BIT_IDIV
7049 && TARGET_QIMODE_MATH
7050 && can_create_pseudo_p ()
7051 && !optimize_insn_for_size_p ()"
7053 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7055 (define_insn_and_split "divmod<mode>4_1"
7056 [(set (match_operand:SWI48 0 "register_operand" "=a")
7057 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7058 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7059 (set (match_operand:SWI48 1 "register_operand" "=&d")
7060 (mod:SWI48 (match_dup 2) (match_dup 3)))
7061 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7062 (clobber (reg:CC FLAGS_REG))]
7066 [(parallel [(set (match_dup 1)
7067 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7068 (clobber (reg:CC FLAGS_REG))])
7069 (parallel [(set (match_dup 0)
7070 (div:SWI48 (match_dup 2) (match_dup 3)))
7072 (mod:SWI48 (match_dup 2) (match_dup 3)))
7074 (clobber (reg:CC FLAGS_REG))])]
7076 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7078 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7079 operands[4] = operands[2];
7082 /* Avoid use of cltd in favor of a mov+shift. */
7083 emit_move_insn (operands[1], operands[2]);
7084 operands[4] = operands[1];
7087 [(set_attr "type" "multi")
7088 (set_attr "mode" "<MODE>")])
7090 (define_insn_and_split "*divmod<mode>4"
7091 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7092 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7093 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7094 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7095 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7096 (clobber (reg:CC FLAGS_REG))]
7100 [(parallel [(set (match_dup 1)
7101 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7102 (clobber (reg:CC FLAGS_REG))])
7103 (parallel [(set (match_dup 0)
7104 (div:SWIM248 (match_dup 2) (match_dup 3)))
7106 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7108 (clobber (reg:CC FLAGS_REG))])]
7110 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7112 if (<MODE>mode != HImode
7113 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7114 operands[4] = operands[2];
7117 /* Avoid use of cltd in favor of a mov+shift. */
7118 emit_move_insn (operands[1], operands[2]);
7119 operands[4] = operands[1];
7122 [(set_attr "type" "multi")
7123 (set_attr "mode" "<MODE>")])
7125 (define_insn "*divmod<mode>4_noext"
7126 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7127 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7128 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7129 (set (match_operand:SWIM248 1 "register_operand" "=d")
7130 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7131 (use (match_operand:SWIM248 4 "register_operand" "1"))
7132 (clobber (reg:CC FLAGS_REG))]
7134 "idiv{<imodesuffix>}\t%3"
7135 [(set_attr "type" "idiv")
7136 (set_attr "mode" "<MODE>")])
7138 (define_expand "divmodqi4"
7139 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7141 (match_operand:QI 1 "register_operand" "")
7142 (match_operand:QI 2 "nonimmediate_operand" "")))
7143 (set (match_operand:QI 3 "register_operand" "")
7144 (mod:QI (match_dup 1) (match_dup 2)))
7145 (clobber (reg:CC FLAGS_REG))])]
7146 "TARGET_QIMODE_MATH"
7151 tmp0 = gen_reg_rtx (HImode);
7152 tmp1 = gen_reg_rtx (HImode);
7154 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7156 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7157 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7159 /* Extract remainder from AH. */
7160 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7161 insn = emit_move_insn (operands[3], tmp1);
7163 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7164 set_unique_reg_note (insn, REG_EQUAL, mod);
7166 /* Extract quotient from AL. */
7167 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7169 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7170 set_unique_reg_note (insn, REG_EQUAL, div);
7175 ;; Divide AX by r/m8, with result stored in
7178 ;; Change div/mod to HImode and extend the second argument to HImode
7179 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7180 ;; combine may fail.
7181 (define_insn "divmodhiqi3"
7182 [(set (match_operand:HI 0 "register_operand" "=a")
7187 (mod:HI (match_operand:HI 1 "register_operand" "0")
7189 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7193 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7194 (clobber (reg:CC FLAGS_REG))]
7195 "TARGET_QIMODE_MATH"
7197 [(set_attr "type" "idiv")
7198 (set_attr "mode" "QI")])
7200 (define_expand "udivmod<mode>4"
7201 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7203 (match_operand:SWIM248 1 "register_operand" "")
7204 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7205 (set (match_operand:SWIM248 3 "register_operand" "")
7206 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7207 (clobber (reg:CC FLAGS_REG))])])
7209 ;; Split with 8bit unsigned divide:
7210 ;; if (dividend an divisor are in [0-255])
7211 ;; use 8bit unsigned integer divide
7213 ;; use original integer divide
7215 [(set (match_operand:SWI48 0 "register_operand" "")
7216 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7217 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7218 (set (match_operand:SWI48 1 "register_operand" "")
7219 (umod:SWI48 (match_dup 2) (match_dup 3)))
7220 (clobber (reg:CC FLAGS_REG))]
7221 "TARGET_USE_8BIT_IDIV
7222 && TARGET_QIMODE_MATH
7223 && can_create_pseudo_p ()
7224 && !optimize_insn_for_size_p ()"
7226 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7228 (define_insn_and_split "udivmod<mode>4_1"
7229 [(set (match_operand:SWI48 0 "register_operand" "=a")
7230 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7231 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7232 (set (match_operand:SWI48 1 "register_operand" "=&d")
7233 (umod:SWI48 (match_dup 2) (match_dup 3)))
7234 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7235 (clobber (reg:CC FLAGS_REG))]
7239 [(set (match_dup 1) (const_int 0))
7240 (parallel [(set (match_dup 0)
7241 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7243 (umod:SWI48 (match_dup 2) (match_dup 3)))
7245 (clobber (reg:CC FLAGS_REG))])]
7247 [(set_attr "type" "multi")
7248 (set_attr "mode" "<MODE>")])
7250 (define_insn_and_split "*udivmod<mode>4"
7251 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7252 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7253 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7254 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7255 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7256 (clobber (reg:CC FLAGS_REG))]
7260 [(set (match_dup 1) (const_int 0))
7261 (parallel [(set (match_dup 0)
7262 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7264 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7266 (clobber (reg:CC FLAGS_REG))])]
7268 [(set_attr "type" "multi")
7269 (set_attr "mode" "<MODE>")])
7271 (define_insn "*udivmod<mode>4_noext"
7272 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7273 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7274 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7275 (set (match_operand:SWIM248 1 "register_operand" "=d")
7276 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7277 (use (match_operand:SWIM248 4 "register_operand" "1"))
7278 (clobber (reg:CC FLAGS_REG))]
7280 "div{<imodesuffix>}\t%3"
7281 [(set_attr "type" "idiv")
7282 (set_attr "mode" "<MODE>")])
7284 (define_expand "udivmodqi4"
7285 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7287 (match_operand:QI 1 "register_operand" "")
7288 (match_operand:QI 2 "nonimmediate_operand" "")))
7289 (set (match_operand:QI 3 "register_operand" "")
7290 (umod:QI (match_dup 1) (match_dup 2)))
7291 (clobber (reg:CC FLAGS_REG))])]
7292 "TARGET_QIMODE_MATH"
7297 tmp0 = gen_reg_rtx (HImode);
7298 tmp1 = gen_reg_rtx (HImode);
7300 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7302 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7303 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7305 /* Extract remainder from AH. */
7306 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7307 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7308 insn = emit_move_insn (operands[3], tmp1);
7310 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7311 set_unique_reg_note (insn, REG_EQUAL, mod);
7313 /* Extract quotient from AL. */
7314 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7316 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7317 set_unique_reg_note (insn, REG_EQUAL, div);
7322 (define_insn "udivmodhiqi3"
7323 [(set (match_operand:HI 0 "register_operand" "=a")
7328 (mod:HI (match_operand:HI 1 "register_operand" "0")
7330 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7334 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7335 (clobber (reg:CC FLAGS_REG))]
7336 "TARGET_QIMODE_MATH"
7338 [(set_attr "type" "idiv")
7339 (set_attr "mode" "QI")])
7341 ;; We cannot use div/idiv for double division, because it causes
7342 ;; "division by zero" on the overflow and that's not what we expect
7343 ;; from truncate. Because true (non truncating) double division is
7344 ;; never generated, we can't create this insn anyway.
7347 ; [(set (match_operand:SI 0 "register_operand" "=a")
7349 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7351 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7352 ; (set (match_operand:SI 3 "register_operand" "=d")
7354 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7355 ; (clobber (reg:CC FLAGS_REG))]
7357 ; "div{l}\t{%2, %0|%0, %2}"
7358 ; [(set_attr "type" "idiv")])
7360 ;;- Logical AND instructions
7362 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7363 ;; Note that this excludes ah.
7365 (define_expand "testsi_ccno_1"
7366 [(set (reg:CCNO FLAGS_REG)
7368 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7369 (match_operand:SI 1 "nonmemory_operand" ""))
7372 (define_expand "testqi_ccz_1"
7373 [(set (reg:CCZ FLAGS_REG)
7374 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7375 (match_operand:QI 1 "nonmemory_operand" ""))
7378 (define_expand "testdi_ccno_1"
7379 [(set (reg:CCNO FLAGS_REG)
7381 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7382 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7384 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7386 (define_insn "*testdi_1"
7387 [(set (reg FLAGS_REG)
7390 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7391 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7393 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7394 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7396 test{l}\t{%k1, %k0|%k0, %k1}
7397 test{l}\t{%k1, %k0|%k0, %k1}
7398 test{q}\t{%1, %0|%0, %1}
7399 test{q}\t{%1, %0|%0, %1}
7400 test{q}\t{%1, %0|%0, %1}"
7401 [(set_attr "type" "test")
7402 (set_attr "modrm" "0,1,0,1,1")
7403 (set_attr "mode" "SI,SI,DI,DI,DI")])
7405 (define_insn "*testqi_1_maybe_si"
7406 [(set (reg FLAGS_REG)
7409 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7410 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7412 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7413 && ix86_match_ccmode (insn,
7414 CONST_INT_P (operands[1])
7415 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7417 if (which_alternative == 3)
7419 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7420 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7421 return "test{l}\t{%1, %k0|%k0, %1}";
7423 return "test{b}\t{%1, %0|%0, %1}";
7425 [(set_attr "type" "test")
7426 (set_attr "modrm" "0,1,1,1")
7427 (set_attr "mode" "QI,QI,QI,SI")
7428 (set_attr "pent_pair" "uv,np,uv,np")])
7430 (define_insn "*test<mode>_1"
7431 [(set (reg FLAGS_REG)
7434 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7435 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7437 "ix86_match_ccmode (insn, CCNOmode)
7438 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7439 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7440 [(set_attr "type" "test")
7441 (set_attr "modrm" "0,1,1")
7442 (set_attr "mode" "<MODE>")
7443 (set_attr "pent_pair" "uv,np,uv")])
7445 (define_expand "testqi_ext_ccno_0"
7446 [(set (reg:CCNO FLAGS_REG)
7450 (match_operand 0 "ext_register_operand" "")
7453 (match_operand 1 "const_int_operand" ""))
7456 (define_insn "*testqi_ext_0"
7457 [(set (reg FLAGS_REG)
7461 (match_operand 0 "ext_register_operand" "Q")
7464 (match_operand 1 "const_int_operand" "n"))
7466 "ix86_match_ccmode (insn, CCNOmode)"
7467 "test{b}\t{%1, %h0|%h0, %1}"
7468 [(set_attr "type" "test")
7469 (set_attr "mode" "QI")
7470 (set_attr "length_immediate" "1")
7471 (set_attr "modrm" "1")
7472 (set_attr "pent_pair" "np")])
7474 (define_insn "*testqi_ext_1_rex64"
7475 [(set (reg FLAGS_REG)
7479 (match_operand 0 "ext_register_operand" "Q")
7483 (match_operand:QI 1 "register_operand" "Q")))
7485 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7486 "test{b}\t{%1, %h0|%h0, %1}"
7487 [(set_attr "type" "test")
7488 (set_attr "mode" "QI")])
7490 (define_insn "*testqi_ext_1"
7491 [(set (reg FLAGS_REG)
7495 (match_operand 0 "ext_register_operand" "Q")
7499 (match_operand:QI 1 "general_operand" "Qm")))
7501 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7502 "test{b}\t{%1, %h0|%h0, %1}"
7503 [(set_attr "type" "test")
7504 (set_attr "mode" "QI")])
7506 (define_insn "*testqi_ext_2"
7507 [(set (reg FLAGS_REG)
7511 (match_operand 0 "ext_register_operand" "Q")
7515 (match_operand 1 "ext_register_operand" "Q")
7519 "ix86_match_ccmode (insn, CCNOmode)"
7520 "test{b}\t{%h1, %h0|%h0, %h1}"
7521 [(set_attr "type" "test")
7522 (set_attr "mode" "QI")])
7524 (define_insn "*testqi_ext_3_rex64"
7525 [(set (reg FLAGS_REG)
7526 (compare (zero_extract:DI
7527 (match_operand 0 "nonimmediate_operand" "rm")
7528 (match_operand:DI 1 "const_int_operand" "")
7529 (match_operand:DI 2 "const_int_operand" ""))
7532 && ix86_match_ccmode (insn, CCNOmode)
7533 && INTVAL (operands[1]) > 0
7534 && INTVAL (operands[2]) >= 0
7535 /* Ensure that resulting mask is zero or sign extended operand. */
7536 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7537 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7538 && INTVAL (operands[1]) > 32))
7539 && (GET_MODE (operands[0]) == SImode
7540 || GET_MODE (operands[0]) == DImode
7541 || GET_MODE (operands[0]) == HImode
7542 || GET_MODE (operands[0]) == QImode)"
7545 ;; Combine likes to form bit extractions for some tests. Humor it.
7546 (define_insn "*testqi_ext_3"
7547 [(set (reg FLAGS_REG)
7548 (compare (zero_extract:SI
7549 (match_operand 0 "nonimmediate_operand" "rm")
7550 (match_operand:SI 1 "const_int_operand" "")
7551 (match_operand:SI 2 "const_int_operand" ""))
7553 "ix86_match_ccmode (insn, CCNOmode)
7554 && INTVAL (operands[1]) > 0
7555 && INTVAL (operands[2]) >= 0
7556 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7557 && (GET_MODE (operands[0]) == SImode
7558 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7559 || GET_MODE (operands[0]) == HImode
7560 || GET_MODE (operands[0]) == QImode)"
7564 [(set (match_operand 0 "flags_reg_operand" "")
7565 (match_operator 1 "compare_operator"
7567 (match_operand 2 "nonimmediate_operand" "")
7568 (match_operand 3 "const_int_operand" "")
7569 (match_operand 4 "const_int_operand" ""))
7571 "ix86_match_ccmode (insn, CCNOmode)"
7572 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7574 rtx val = operands[2];
7575 HOST_WIDE_INT len = INTVAL (operands[3]);
7576 HOST_WIDE_INT pos = INTVAL (operands[4]);
7578 enum machine_mode mode, submode;
7580 mode = GET_MODE (val);
7583 /* ??? Combine likes to put non-volatile mem extractions in QImode
7584 no matter the size of the test. So find a mode that works. */
7585 if (! MEM_VOLATILE_P (val))
7587 mode = smallest_mode_for_size (pos + len, MODE_INT);
7588 val = adjust_address (val, mode, 0);
7591 else if (GET_CODE (val) == SUBREG
7592 && (submode = GET_MODE (SUBREG_REG (val)),
7593 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7594 && pos + len <= GET_MODE_BITSIZE (submode)
7595 && GET_MODE_CLASS (submode) == MODE_INT)
7597 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7599 val = SUBREG_REG (val);
7601 else if (mode == HImode && pos + len <= 8)
7603 /* Small HImode tests can be converted to QImode. */
7605 val = gen_lowpart (QImode, val);
7608 if (len == HOST_BITS_PER_WIDE_INT)
7611 mask = ((HOST_WIDE_INT)1 << len) - 1;
7614 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7617 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7618 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7619 ;; this is relatively important trick.
7620 ;; Do the conversion only post-reload to avoid limiting of the register class
7623 [(set (match_operand 0 "flags_reg_operand" "")
7624 (match_operator 1 "compare_operator"
7625 [(and (match_operand 2 "register_operand" "")
7626 (match_operand 3 "const_int_operand" ""))
7629 && QI_REG_P (operands[2])
7630 && GET_MODE (operands[2]) != QImode
7631 && ((ix86_match_ccmode (insn, CCZmode)
7632 && !(INTVAL (operands[3]) & ~(255 << 8)))
7633 || (ix86_match_ccmode (insn, CCNOmode)
7634 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7637 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7640 "operands[2] = gen_lowpart (SImode, operands[2]);
7641 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7644 [(set (match_operand 0 "flags_reg_operand" "")
7645 (match_operator 1 "compare_operator"
7646 [(and (match_operand 2 "nonimmediate_operand" "")
7647 (match_operand 3 "const_int_operand" ""))
7650 && GET_MODE (operands[2]) != QImode
7651 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7652 && ((ix86_match_ccmode (insn, CCZmode)
7653 && !(INTVAL (operands[3]) & ~255))
7654 || (ix86_match_ccmode (insn, CCNOmode)
7655 && !(INTVAL (operands[3]) & ~127)))"
7657 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7659 "operands[2] = gen_lowpart (QImode, operands[2]);
7660 operands[3] = gen_lowpart (QImode, operands[3]);")
7662 ;; %%% This used to optimize known byte-wide and operations to memory,
7663 ;; and sometimes to QImode registers. If this is considered useful,
7664 ;; it should be done with splitters.
7666 (define_expand "and<mode>3"
7667 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7668 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7669 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7671 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7673 (define_insn "*anddi_1"
7674 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7676 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7677 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7678 (clobber (reg:CC FLAGS_REG))]
7679 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7681 switch (get_attr_type (insn))
7685 enum machine_mode mode;
7687 gcc_assert (CONST_INT_P (operands[2]));
7688 if (INTVAL (operands[2]) == 0xff)
7692 gcc_assert (INTVAL (operands[2]) == 0xffff);
7696 operands[1] = gen_lowpart (mode, operands[1]);
7698 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7700 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7704 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7705 if (get_attr_mode (insn) == MODE_SI)
7706 return "and{l}\t{%k2, %k0|%k0, %k2}";
7708 return "and{q}\t{%2, %0|%0, %2}";
7711 [(set_attr "type" "alu,alu,alu,imovx")
7712 (set_attr "length_immediate" "*,*,*,0")
7713 (set (attr "prefix_rex")
7715 (and (eq_attr "type" "imovx")
7716 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7717 (match_operand 1 "ext_QIreg_operand" "")))
7719 (const_string "*")))
7720 (set_attr "mode" "SI,DI,DI,SI")])
7722 (define_insn "*andsi_1"
7723 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7724 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7725 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7726 (clobber (reg:CC FLAGS_REG))]
7727 "ix86_binary_operator_ok (AND, SImode, operands)"
7729 switch (get_attr_type (insn))
7733 enum machine_mode mode;
7735 gcc_assert (CONST_INT_P (operands[2]));
7736 if (INTVAL (operands[2]) == 0xff)
7740 gcc_assert (INTVAL (operands[2]) == 0xffff);
7744 operands[1] = gen_lowpart (mode, operands[1]);
7746 return "movz{bl|x}\t{%1, %0|%0, %1}";
7748 return "movz{wl|x}\t{%1, %0|%0, %1}";
7752 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7753 return "and{l}\t{%2, %0|%0, %2}";
7756 [(set_attr "type" "alu,alu,imovx")
7757 (set (attr "prefix_rex")
7759 (and (eq_attr "type" "imovx")
7760 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7761 (match_operand 1 "ext_QIreg_operand" "")))
7763 (const_string "*")))
7764 (set_attr "length_immediate" "*,*,0")
7765 (set_attr "mode" "SI")])
7767 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7768 (define_insn "*andsi_1_zext"
7769 [(set (match_operand:DI 0 "register_operand" "=r")
7771 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7772 (match_operand:SI 2 "general_operand" "g"))))
7773 (clobber (reg:CC FLAGS_REG))]
7774 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7775 "and{l}\t{%2, %k0|%k0, %2}"
7776 [(set_attr "type" "alu")
7777 (set_attr "mode" "SI")])
7779 (define_insn "*andhi_1"
7780 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7781 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7782 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7783 (clobber (reg:CC FLAGS_REG))]
7784 "ix86_binary_operator_ok (AND, HImode, operands)"
7786 switch (get_attr_type (insn))
7789 gcc_assert (CONST_INT_P (operands[2]));
7790 gcc_assert (INTVAL (operands[2]) == 0xff);
7791 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7794 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7796 return "and{w}\t{%2, %0|%0, %2}";
7799 [(set_attr "type" "alu,alu,imovx")
7800 (set_attr "length_immediate" "*,*,0")
7801 (set (attr "prefix_rex")
7803 (and (eq_attr "type" "imovx")
7804 (match_operand 1 "ext_QIreg_operand" ""))
7806 (const_string "*")))
7807 (set_attr "mode" "HI,HI,SI")])
7809 ;; %%% Potential partial reg stall on alternative 2. What to do?
7810 (define_insn "*andqi_1"
7811 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7812 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7813 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7814 (clobber (reg:CC FLAGS_REG))]
7815 "ix86_binary_operator_ok (AND, QImode, operands)"
7817 and{b}\t{%2, %0|%0, %2}
7818 and{b}\t{%2, %0|%0, %2}
7819 and{l}\t{%k2, %k0|%k0, %k2}"
7820 [(set_attr "type" "alu")
7821 (set_attr "mode" "QI,QI,SI")])
7823 (define_insn "*andqi_1_slp"
7824 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7825 (and:QI (match_dup 0)
7826 (match_operand:QI 1 "general_operand" "qn,qmn")))
7827 (clobber (reg:CC FLAGS_REG))]
7828 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7829 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7830 "and{b}\t{%1, %0|%0, %1}"
7831 [(set_attr "type" "alu1")
7832 (set_attr "mode" "QI")])
7835 [(set (match_operand 0 "register_operand" "")
7837 (const_int -65536)))
7838 (clobber (reg:CC FLAGS_REG))]
7839 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7840 || optimize_function_for_size_p (cfun)"
7841 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7842 "operands[1] = gen_lowpart (HImode, operands[0]);")
7845 [(set (match_operand 0 "ext_register_operand" "")
7848 (clobber (reg:CC FLAGS_REG))]
7849 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7850 && reload_completed"
7851 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7852 "operands[1] = gen_lowpart (QImode, operands[0]);")
7855 [(set (match_operand 0 "ext_register_operand" "")
7857 (const_int -65281)))
7858 (clobber (reg:CC FLAGS_REG))]
7859 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7860 && reload_completed"
7861 [(parallel [(set (zero_extract:SI (match_dup 0)
7865 (zero_extract:SI (match_dup 0)
7868 (zero_extract:SI (match_dup 0)
7871 (clobber (reg:CC FLAGS_REG))])]
7872 "operands[0] = gen_lowpart (SImode, operands[0]);")
7874 (define_insn "*anddi_2"
7875 [(set (reg FLAGS_REG)
7878 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7879 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7881 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7882 (and:DI (match_dup 1) (match_dup 2)))]
7883 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7884 && ix86_binary_operator_ok (AND, DImode, operands)"
7886 and{l}\t{%k2, %k0|%k0, %k2}
7887 and{q}\t{%2, %0|%0, %2}
7888 and{q}\t{%2, %0|%0, %2}"
7889 [(set_attr "type" "alu")
7890 (set_attr "mode" "SI,DI,DI")])
7892 (define_insn "*andqi_2_maybe_si"
7893 [(set (reg FLAGS_REG)
7895 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7896 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7898 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7899 (and:QI (match_dup 1) (match_dup 2)))]
7900 "ix86_binary_operator_ok (AND, QImode, operands)
7901 && ix86_match_ccmode (insn,
7902 CONST_INT_P (operands[2])
7903 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7905 if (which_alternative == 2)
7907 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7908 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7909 return "and{l}\t{%2, %k0|%k0, %2}";
7911 return "and{b}\t{%2, %0|%0, %2}";
7913 [(set_attr "type" "alu")
7914 (set_attr "mode" "QI,QI,SI")])
7916 (define_insn "*and<mode>_2"
7917 [(set (reg FLAGS_REG)
7918 (compare (and:SWI124
7919 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7920 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7922 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7923 (and:SWI124 (match_dup 1) (match_dup 2)))]
7924 "ix86_match_ccmode (insn, CCNOmode)
7925 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7926 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7927 [(set_attr "type" "alu")
7928 (set_attr "mode" "<MODE>")])
7930 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7931 (define_insn "*andsi_2_zext"
7932 [(set (reg FLAGS_REG)
7934 (match_operand:SI 1 "nonimmediate_operand" "%0")
7935 (match_operand:SI 2 "general_operand" "g"))
7937 (set (match_operand:DI 0 "register_operand" "=r")
7938 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7939 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7940 && ix86_binary_operator_ok (AND, SImode, operands)"
7941 "and{l}\t{%2, %k0|%k0, %2}"
7942 [(set_attr "type" "alu")
7943 (set_attr "mode" "SI")])
7945 (define_insn "*andqi_2_slp"
7946 [(set (reg FLAGS_REG)
7948 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7949 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7951 (set (strict_low_part (match_dup 0))
7952 (and:QI (match_dup 0) (match_dup 1)))]
7953 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7954 && ix86_match_ccmode (insn, CCNOmode)
7955 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7956 "and{b}\t{%1, %0|%0, %1}"
7957 [(set_attr "type" "alu1")
7958 (set_attr "mode" "QI")])
7960 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7961 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7962 ;; for a QImode operand, which of course failed.
7963 (define_insn "andqi_ext_0"
7964 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7969 (match_operand 1 "ext_register_operand" "0")
7972 (match_operand 2 "const_int_operand" "n")))
7973 (clobber (reg:CC FLAGS_REG))]
7975 "and{b}\t{%2, %h0|%h0, %2}"
7976 [(set_attr "type" "alu")
7977 (set_attr "length_immediate" "1")
7978 (set_attr "modrm" "1")
7979 (set_attr "mode" "QI")])
7981 ;; Generated by peephole translating test to and. This shows up
7982 ;; often in fp comparisons.
7983 (define_insn "*andqi_ext_0_cc"
7984 [(set (reg FLAGS_REG)
7988 (match_operand 1 "ext_register_operand" "0")
7991 (match_operand 2 "const_int_operand" "n"))
7993 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8002 "ix86_match_ccmode (insn, CCNOmode)"
8003 "and{b}\t{%2, %h0|%h0, %2}"
8004 [(set_attr "type" "alu")
8005 (set_attr "length_immediate" "1")
8006 (set_attr "modrm" "1")
8007 (set_attr "mode" "QI")])
8009 (define_insn "*andqi_ext_1_rex64"
8010 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8015 (match_operand 1 "ext_register_operand" "0")
8019 (match_operand 2 "ext_register_operand" "Q"))))
8020 (clobber (reg:CC FLAGS_REG))]
8022 "and{b}\t{%2, %h0|%h0, %2}"
8023 [(set_attr "type" "alu")
8024 (set_attr "length_immediate" "0")
8025 (set_attr "mode" "QI")])
8027 (define_insn "*andqi_ext_1"
8028 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8033 (match_operand 1 "ext_register_operand" "0")
8037 (match_operand:QI 2 "general_operand" "Qm"))))
8038 (clobber (reg:CC FLAGS_REG))]
8040 "and{b}\t{%2, %h0|%h0, %2}"
8041 [(set_attr "type" "alu")
8042 (set_attr "length_immediate" "0")
8043 (set_attr "mode" "QI")])
8045 (define_insn "*andqi_ext_2"
8046 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8051 (match_operand 1 "ext_register_operand" "%0")
8055 (match_operand 2 "ext_register_operand" "Q")
8058 (clobber (reg:CC FLAGS_REG))]
8060 "and{b}\t{%h2, %h0|%h0, %h2}"
8061 [(set_attr "type" "alu")
8062 (set_attr "length_immediate" "0")
8063 (set_attr "mode" "QI")])
8065 ;; Convert wide AND instructions with immediate operand to shorter QImode
8066 ;; equivalents when possible.
8067 ;; Don't do the splitting with memory operands, since it introduces risk
8068 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8069 ;; for size, but that can (should?) be handled by generic code instead.
8071 [(set (match_operand 0 "register_operand" "")
8072 (and (match_operand 1 "register_operand" "")
8073 (match_operand 2 "const_int_operand" "")))
8074 (clobber (reg:CC FLAGS_REG))]
8076 && QI_REG_P (operands[0])
8077 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8078 && !(~INTVAL (operands[2]) & ~(255 << 8))
8079 && GET_MODE (operands[0]) != QImode"
8080 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8081 (and:SI (zero_extract:SI (match_dup 1)
8082 (const_int 8) (const_int 8))
8084 (clobber (reg:CC FLAGS_REG))])]
8085 "operands[0] = gen_lowpart (SImode, operands[0]);
8086 operands[1] = gen_lowpart (SImode, operands[1]);
8087 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8089 ;; Since AND can be encoded with sign extended immediate, this is only
8090 ;; profitable when 7th bit is not set.
8092 [(set (match_operand 0 "register_operand" "")
8093 (and (match_operand 1 "general_operand" "")
8094 (match_operand 2 "const_int_operand" "")))
8095 (clobber (reg:CC FLAGS_REG))]
8097 && ANY_QI_REG_P (operands[0])
8098 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8099 && !(~INTVAL (operands[2]) & ~255)
8100 && !(INTVAL (operands[2]) & 128)
8101 && GET_MODE (operands[0]) != QImode"
8102 [(parallel [(set (strict_low_part (match_dup 0))
8103 (and:QI (match_dup 1)
8105 (clobber (reg:CC FLAGS_REG))])]
8106 "operands[0] = gen_lowpart (QImode, operands[0]);
8107 operands[1] = gen_lowpart (QImode, operands[1]);
8108 operands[2] = gen_lowpart (QImode, operands[2]);")
8110 ;; Logical inclusive and exclusive OR instructions
8112 ;; %%% This used to optimize known byte-wide and operations to memory.
8113 ;; If this is considered useful, it should be done with splitters.
8115 (define_expand "<code><mode>3"
8116 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8117 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8118 (match_operand:SWIM 2 "<general_operand>" "")))]
8120 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8122 (define_insn "*<code><mode>_1"
8123 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8125 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8126 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8127 (clobber (reg:CC FLAGS_REG))]
8128 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8129 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8130 [(set_attr "type" "alu")
8131 (set_attr "mode" "<MODE>")])
8133 ;; %%% Potential partial reg stall on alternative 2. What to do?
8134 (define_insn "*<code>qi_1"
8135 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8136 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8137 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8138 (clobber (reg:CC FLAGS_REG))]
8139 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8141 <logic>{b}\t{%2, %0|%0, %2}
8142 <logic>{b}\t{%2, %0|%0, %2}
8143 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8144 [(set_attr "type" "alu")
8145 (set_attr "mode" "QI,QI,SI")])
8147 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8148 (define_insn "*<code>si_1_zext"
8149 [(set (match_operand:DI 0 "register_operand" "=r")
8151 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8152 (match_operand:SI 2 "general_operand" "g"))))
8153 (clobber (reg:CC FLAGS_REG))]
8154 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8155 "<logic>{l}\t{%2, %k0|%k0, %2}"
8156 [(set_attr "type" "alu")
8157 (set_attr "mode" "SI")])
8159 (define_insn "*<code>si_1_zext_imm"
8160 [(set (match_operand:DI 0 "register_operand" "=r")
8162 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8163 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8164 (clobber (reg:CC FLAGS_REG))]
8165 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8166 "<logic>{l}\t{%2, %k0|%k0, %2}"
8167 [(set_attr "type" "alu")
8168 (set_attr "mode" "SI")])
8170 (define_insn "*<code>qi_1_slp"
8171 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8172 (any_or:QI (match_dup 0)
8173 (match_operand:QI 1 "general_operand" "qmn,qn")))
8174 (clobber (reg:CC FLAGS_REG))]
8175 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8176 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8177 "<logic>{b}\t{%1, %0|%0, %1}"
8178 [(set_attr "type" "alu1")
8179 (set_attr "mode" "QI")])
8181 (define_insn "*<code><mode>_2"
8182 [(set (reg FLAGS_REG)
8183 (compare (any_or:SWI
8184 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8185 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8187 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8188 (any_or:SWI (match_dup 1) (match_dup 2)))]
8189 "ix86_match_ccmode (insn, CCNOmode)
8190 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8191 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8192 [(set_attr "type" "alu")
8193 (set_attr "mode" "<MODE>")])
8195 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8196 ;; ??? Special case for immediate operand is missing - it is tricky.
8197 (define_insn "*<code>si_2_zext"
8198 [(set (reg FLAGS_REG)
8199 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8200 (match_operand:SI 2 "general_operand" "g"))
8202 (set (match_operand:DI 0 "register_operand" "=r")
8203 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8204 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8205 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8206 "<logic>{l}\t{%2, %k0|%k0, %2}"
8207 [(set_attr "type" "alu")
8208 (set_attr "mode" "SI")])
8210 (define_insn "*<code>si_2_zext_imm"
8211 [(set (reg FLAGS_REG)
8213 (match_operand:SI 1 "nonimmediate_operand" "%0")
8214 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8216 (set (match_operand:DI 0 "register_operand" "=r")
8217 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8218 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8219 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8220 "<logic>{l}\t{%2, %k0|%k0, %2}"
8221 [(set_attr "type" "alu")
8222 (set_attr "mode" "SI")])
8224 (define_insn "*<code>qi_2_slp"
8225 [(set (reg FLAGS_REG)
8226 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8227 (match_operand:QI 1 "general_operand" "qmn,qn"))
8229 (set (strict_low_part (match_dup 0))
8230 (any_or:QI (match_dup 0) (match_dup 1)))]
8231 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232 && ix86_match_ccmode (insn, CCNOmode)
8233 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8234 "<logic>{b}\t{%1, %0|%0, %1}"
8235 [(set_attr "type" "alu1")
8236 (set_attr "mode" "QI")])
8238 (define_insn "*<code><mode>_3"
8239 [(set (reg FLAGS_REG)
8240 (compare (any_or:SWI
8241 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8242 (match_operand:SWI 2 "<general_operand>" "<g>"))
8244 (clobber (match_scratch:SWI 0 "=<r>"))]
8245 "ix86_match_ccmode (insn, CCNOmode)
8246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8247 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8248 [(set_attr "type" "alu")
8249 (set_attr "mode" "<MODE>")])
8251 (define_insn "*<code>qi_ext_0"
8252 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8257 (match_operand 1 "ext_register_operand" "0")
8260 (match_operand 2 "const_int_operand" "n")))
8261 (clobber (reg:CC FLAGS_REG))]
8262 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8263 "<logic>{b}\t{%2, %h0|%h0, %2}"
8264 [(set_attr "type" "alu")
8265 (set_attr "length_immediate" "1")
8266 (set_attr "modrm" "1")
8267 (set_attr "mode" "QI")])
8269 (define_insn "*<code>qi_ext_1_rex64"
8270 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8275 (match_operand 1 "ext_register_operand" "0")
8279 (match_operand 2 "ext_register_operand" "Q"))))
8280 (clobber (reg:CC FLAGS_REG))]
8282 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8283 "<logic>{b}\t{%2, %h0|%h0, %2}"
8284 [(set_attr "type" "alu")
8285 (set_attr "length_immediate" "0")
8286 (set_attr "mode" "QI")])
8288 (define_insn "*<code>qi_ext_1"
8289 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8294 (match_operand 1 "ext_register_operand" "0")
8298 (match_operand:QI 2 "general_operand" "Qm"))))
8299 (clobber (reg:CC FLAGS_REG))]
8301 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8302 "<logic>{b}\t{%2, %h0|%h0, %2}"
8303 [(set_attr "type" "alu")
8304 (set_attr "length_immediate" "0")
8305 (set_attr "mode" "QI")])
8307 (define_insn "*<code>qi_ext_2"
8308 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8312 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8315 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8318 (clobber (reg:CC FLAGS_REG))]
8319 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8320 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "length_immediate" "0")
8323 (set_attr "mode" "QI")])
8326 [(set (match_operand 0 "register_operand" "")
8327 (any_or (match_operand 1 "register_operand" "")
8328 (match_operand 2 "const_int_operand" "")))
8329 (clobber (reg:CC FLAGS_REG))]
8331 && QI_REG_P (operands[0])
8332 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8333 && !(INTVAL (operands[2]) & ~(255 << 8))
8334 && GET_MODE (operands[0]) != QImode"
8335 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8336 (any_or:SI (zero_extract:SI (match_dup 1)
8337 (const_int 8) (const_int 8))
8339 (clobber (reg:CC FLAGS_REG))])]
8340 "operands[0] = gen_lowpart (SImode, operands[0]);
8341 operands[1] = gen_lowpart (SImode, operands[1]);
8342 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8344 ;; Since OR can be encoded with sign extended immediate, this is only
8345 ;; profitable when 7th bit is set.
8347 [(set (match_operand 0 "register_operand" "")
8348 (any_or (match_operand 1 "general_operand" "")
8349 (match_operand 2 "const_int_operand" "")))
8350 (clobber (reg:CC FLAGS_REG))]
8352 && ANY_QI_REG_P (operands[0])
8353 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8354 && !(INTVAL (operands[2]) & ~255)
8355 && (INTVAL (operands[2]) & 128)
8356 && GET_MODE (operands[0]) != QImode"
8357 [(parallel [(set (strict_low_part (match_dup 0))
8358 (any_or:QI (match_dup 1)
8360 (clobber (reg:CC FLAGS_REG))])]
8361 "operands[0] = gen_lowpart (QImode, operands[0]);
8362 operands[1] = gen_lowpart (QImode, operands[1]);
8363 operands[2] = gen_lowpart (QImode, operands[2]);")
8365 (define_expand "xorqi_cc_ext_1"
8367 (set (reg:CCNO FLAGS_REG)
8371 (match_operand 1 "ext_register_operand" "")
8374 (match_operand:QI 2 "general_operand" ""))
8376 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8386 (define_insn "*xorqi_cc_ext_1_rex64"
8387 [(set (reg FLAGS_REG)
8391 (match_operand 1 "ext_register_operand" "0")
8394 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8396 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8405 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8406 "xor{b}\t{%2, %h0|%h0, %2}"
8407 [(set_attr "type" "alu")
8408 (set_attr "modrm" "1")
8409 (set_attr "mode" "QI")])
8411 (define_insn "*xorqi_cc_ext_1"
8412 [(set (reg FLAGS_REG)
8416 (match_operand 1 "ext_register_operand" "0")
8419 (match_operand:QI 2 "general_operand" "qmn"))
8421 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8430 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8431 "xor{b}\t{%2, %h0|%h0, %2}"
8432 [(set_attr "type" "alu")
8433 (set_attr "modrm" "1")
8434 (set_attr "mode" "QI")])
8436 ;; Negation instructions
8438 (define_expand "neg<mode>2"
8439 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8440 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8442 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8444 (define_insn_and_split "*neg<dwi>2_doubleword"
8445 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8446 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8447 (clobber (reg:CC FLAGS_REG))]
8448 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8452 [(set (reg:CCZ FLAGS_REG)
8453 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8454 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8457 (plus:DWIH (match_dup 3)
8458 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8460 (clobber (reg:CC FLAGS_REG))])
8463 (neg:DWIH (match_dup 2)))
8464 (clobber (reg:CC FLAGS_REG))])]
8465 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8467 (define_insn "*neg<mode>2_1"
8468 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8469 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8470 (clobber (reg:CC FLAGS_REG))]
8471 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8472 "neg{<imodesuffix>}\t%0"
8473 [(set_attr "type" "negnot")
8474 (set_attr "mode" "<MODE>")])
8476 ;; Combine is quite creative about this pattern.
8477 (define_insn "*negsi2_1_zext"
8478 [(set (match_operand:DI 0 "register_operand" "=r")
8480 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8483 (clobber (reg:CC FLAGS_REG))]
8484 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8486 [(set_attr "type" "negnot")
8487 (set_attr "mode" "SI")])
8489 ;; The problem with neg is that it does not perform (compare x 0),
8490 ;; it really performs (compare 0 x), which leaves us with the zero
8491 ;; flag being the only useful item.
8493 (define_insn "*neg<mode>2_cmpz"
8494 [(set (reg:CCZ FLAGS_REG)
8496 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8498 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8499 (neg:SWI (match_dup 1)))]
8500 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8501 "neg{<imodesuffix>}\t%0"
8502 [(set_attr "type" "negnot")
8503 (set_attr "mode" "<MODE>")])
8505 (define_insn "*negsi2_cmpz_zext"
8506 [(set (reg:CCZ FLAGS_REG)
8510 (match_operand:DI 1 "register_operand" "0")
8514 (set (match_operand:DI 0 "register_operand" "=r")
8515 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8518 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8520 [(set_attr "type" "negnot")
8521 (set_attr "mode" "SI")])
8523 ;; Changing of sign for FP values is doable using integer unit too.
8525 (define_expand "<code><mode>2"
8526 [(set (match_operand:X87MODEF 0 "register_operand" "")
8527 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8528 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8529 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8531 (define_insn "*absneg<mode>2_mixed"
8532 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8533 (match_operator:MODEF 3 "absneg_operator"
8534 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8535 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8540 (define_insn "*absneg<mode>2_sse"
8541 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8542 (match_operator:MODEF 3 "absneg_operator"
8543 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8544 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8549 (define_insn "*absneg<mode>2_i387"
8550 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8551 (match_operator:X87MODEF 3 "absneg_operator"
8552 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8553 (use (match_operand 2 "" ""))
8554 (clobber (reg:CC FLAGS_REG))]
8555 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8558 (define_expand "<code>tf2"
8559 [(set (match_operand:TF 0 "register_operand" "")
8560 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8562 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8564 (define_insn "*absnegtf2_sse"
8565 [(set (match_operand:TF 0 "register_operand" "=x,x")
8566 (match_operator:TF 3 "absneg_operator"
8567 [(match_operand:TF 1 "register_operand" "0,x")]))
8568 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8569 (clobber (reg:CC FLAGS_REG))]
8573 ;; Splitters for fp abs and neg.
8576 [(set (match_operand 0 "fp_register_operand" "")
8577 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8578 (use (match_operand 2 "" ""))
8579 (clobber (reg:CC FLAGS_REG))]
8581 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8584 [(set (match_operand 0 "register_operand" "")
8585 (match_operator 3 "absneg_operator"
8586 [(match_operand 1 "register_operand" "")]))
8587 (use (match_operand 2 "nonimmediate_operand" ""))
8588 (clobber (reg:CC FLAGS_REG))]
8589 "reload_completed && SSE_REG_P (operands[0])"
8590 [(set (match_dup 0) (match_dup 3))]
8592 enum machine_mode mode = GET_MODE (operands[0]);
8593 enum machine_mode vmode = GET_MODE (operands[2]);
8596 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8597 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8598 if (operands_match_p (operands[0], operands[2]))
8601 operands[1] = operands[2];
8604 if (GET_CODE (operands[3]) == ABS)
8605 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8607 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8612 [(set (match_operand:SF 0 "register_operand" "")
8613 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8614 (use (match_operand:V4SF 2 "" ""))
8615 (clobber (reg:CC FLAGS_REG))]
8617 [(parallel [(set (match_dup 0) (match_dup 1))
8618 (clobber (reg:CC FLAGS_REG))])]
8621 operands[0] = gen_lowpart (SImode, operands[0]);
8622 if (GET_CODE (operands[1]) == ABS)
8624 tmp = gen_int_mode (0x7fffffff, SImode);
8625 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8629 tmp = gen_int_mode (0x80000000, SImode);
8630 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8636 [(set (match_operand:DF 0 "register_operand" "")
8637 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8638 (use (match_operand 2 "" ""))
8639 (clobber (reg:CC FLAGS_REG))]
8641 [(parallel [(set (match_dup 0) (match_dup 1))
8642 (clobber (reg:CC FLAGS_REG))])]
8647 tmp = gen_lowpart (DImode, operands[0]);
8648 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8651 if (GET_CODE (operands[1]) == ABS)
8654 tmp = gen_rtx_NOT (DImode, tmp);
8658 operands[0] = gen_highpart (SImode, operands[0]);
8659 if (GET_CODE (operands[1]) == ABS)
8661 tmp = gen_int_mode (0x7fffffff, SImode);
8662 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8666 tmp = gen_int_mode (0x80000000, SImode);
8667 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8674 [(set (match_operand:XF 0 "register_operand" "")
8675 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8676 (use (match_operand 2 "" ""))
8677 (clobber (reg:CC FLAGS_REG))]
8679 [(parallel [(set (match_dup 0) (match_dup 1))
8680 (clobber (reg:CC FLAGS_REG))])]
8683 operands[0] = gen_rtx_REG (SImode,
8684 true_regnum (operands[0])
8685 + (TARGET_64BIT ? 1 : 2));
8686 if (GET_CODE (operands[1]) == ABS)
8688 tmp = GEN_INT (0x7fff);
8689 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8693 tmp = GEN_INT (0x8000);
8694 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8699 ;; Conditionalize these after reload. If they match before reload, we
8700 ;; lose the clobber and ability to use integer instructions.
8702 (define_insn "*<code><mode>2_1"
8703 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8704 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8706 && (reload_completed
8707 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8708 "f<absneg_mnemonic>"
8709 [(set_attr "type" "fsgn")
8710 (set_attr "mode" "<MODE>")])
8712 (define_insn "*<code>extendsfdf2"
8713 [(set (match_operand:DF 0 "register_operand" "=f")
8714 (absneg:DF (float_extend:DF
8715 (match_operand:SF 1 "register_operand" "0"))))]
8716 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8717 "f<absneg_mnemonic>"
8718 [(set_attr "type" "fsgn")
8719 (set_attr "mode" "DF")])
8721 (define_insn "*<code>extendsfxf2"
8722 [(set (match_operand:XF 0 "register_operand" "=f")
8723 (absneg:XF (float_extend:XF
8724 (match_operand:SF 1 "register_operand" "0"))))]
8726 "f<absneg_mnemonic>"
8727 [(set_attr "type" "fsgn")
8728 (set_attr "mode" "XF")])
8730 (define_insn "*<code>extenddfxf2"
8731 [(set (match_operand:XF 0 "register_operand" "=f")
8732 (absneg:XF (float_extend:XF
8733 (match_operand:DF 1 "register_operand" "0"))))]
8735 "f<absneg_mnemonic>"
8736 [(set_attr "type" "fsgn")
8737 (set_attr "mode" "XF")])
8739 ;; Copysign instructions
8741 (define_mode_iterator CSGNMODE [SF DF TF])
8742 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8744 (define_expand "copysign<mode>3"
8745 [(match_operand:CSGNMODE 0 "register_operand" "")
8746 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8747 (match_operand:CSGNMODE 2 "register_operand" "")]
8748 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8749 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8750 "ix86_expand_copysign (operands); DONE;")
8752 (define_insn_and_split "copysign<mode>3_const"
8753 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8755 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8756 (match_operand:CSGNMODE 2 "register_operand" "0")
8757 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8759 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8760 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8762 "&& reload_completed"
8764 "ix86_split_copysign_const (operands); DONE;")
8766 (define_insn "copysign<mode>3_var"
8767 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8769 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8770 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8771 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8772 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8774 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8775 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8776 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8780 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8782 [(match_operand:CSGNMODE 2 "register_operand" "")
8783 (match_operand:CSGNMODE 3 "register_operand" "")
8784 (match_operand:<CSGNVMODE> 4 "" "")
8785 (match_operand:<CSGNVMODE> 5 "" "")]
8787 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8788 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8789 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8790 && reload_completed"
8792 "ix86_split_copysign_var (operands); DONE;")
8794 ;; One complement instructions
8796 (define_expand "one_cmpl<mode>2"
8797 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8798 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8800 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8802 (define_insn "*one_cmpl<mode>2_1"
8803 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8804 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8805 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8806 "not{<imodesuffix>}\t%0"
8807 [(set_attr "type" "negnot")
8808 (set_attr "mode" "<MODE>")])
8810 ;; %%% Potential partial reg stall on alternative 1. What to do?
8811 (define_insn "*one_cmplqi2_1"
8812 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8813 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8814 "ix86_unary_operator_ok (NOT, QImode, operands)"
8818 [(set_attr "type" "negnot")
8819 (set_attr "mode" "QI,SI")])
8821 ;; ??? Currently never generated - xor is used instead.
8822 (define_insn "*one_cmplsi2_1_zext"
8823 [(set (match_operand:DI 0 "register_operand" "=r")
8825 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8826 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8828 [(set_attr "type" "negnot")
8829 (set_attr "mode" "SI")])
8831 (define_insn "*one_cmpl<mode>2_2"
8832 [(set (reg FLAGS_REG)
8833 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8835 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8836 (not:SWI (match_dup 1)))]
8837 "ix86_match_ccmode (insn, CCNOmode)
8838 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8840 [(set_attr "type" "alu1")
8841 (set_attr "mode" "<MODE>")])
8844 [(set (match_operand 0 "flags_reg_operand" "")
8845 (match_operator 2 "compare_operator"
8846 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8848 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8849 (not:SWI (match_dup 3)))]
8850 "ix86_match_ccmode (insn, CCNOmode)"
8851 [(parallel [(set (match_dup 0)
8852 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8855 (xor:SWI (match_dup 3) (const_int -1)))])])
8857 ;; ??? Currently never generated - xor is used instead.
8858 (define_insn "*one_cmplsi2_2_zext"
8859 [(set (reg FLAGS_REG)
8860 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8862 (set (match_operand:DI 0 "register_operand" "=r")
8863 (zero_extend:DI (not:SI (match_dup 1))))]
8864 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8865 && ix86_unary_operator_ok (NOT, SImode, operands)"
8867 [(set_attr "type" "alu1")
8868 (set_attr "mode" "SI")])
8871 [(set (match_operand 0 "flags_reg_operand" "")
8872 (match_operator 2 "compare_operator"
8873 [(not:SI (match_operand:SI 3 "register_operand" ""))
8875 (set (match_operand:DI 1 "register_operand" "")
8876 (zero_extend:DI (not:SI (match_dup 3))))]
8877 "ix86_match_ccmode (insn, CCNOmode)"
8878 [(parallel [(set (match_dup 0)
8879 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8882 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8884 ;; Shift instructions
8886 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8887 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8888 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8889 ;; from the assembler input.
8891 ;; This instruction shifts the target reg/mem as usual, but instead of
8892 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8893 ;; is a left shift double, bits are taken from the high order bits of
8894 ;; reg, else if the insn is a shift right double, bits are taken from the
8895 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8896 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8898 ;; Since sh[lr]d does not change the `reg' operand, that is done
8899 ;; separately, making all shifts emit pairs of shift double and normal
8900 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8901 ;; support a 63 bit shift, each shift where the count is in a reg expands
8902 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8904 ;; If the shift count is a constant, we need never emit more than one
8905 ;; shift pair, instead using moves and sign extension for counts greater
8908 (define_expand "ashl<mode>3"
8909 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8910 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8911 (match_operand:QI 2 "nonmemory_operand" "")))]
8913 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8915 (define_insn "*ashl<mode>3_doubleword"
8916 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8917 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8918 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8919 (clobber (reg:CC FLAGS_REG))]
8922 [(set_attr "type" "multi")])
8925 [(set (match_operand:DWI 0 "register_operand" "")
8926 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8927 (match_operand:QI 2 "nonmemory_operand" "")))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8931 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8933 ;; By default we don't ask for a scratch register, because when DWImode
8934 ;; values are manipulated, registers are already at a premium. But if
8935 ;; we have one handy, we won't turn it away.
8938 [(match_scratch:DWIH 3 "r")
8939 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8941 (match_operand:<DWI> 1 "nonmemory_operand" "")
8942 (match_operand:QI 2 "nonmemory_operand" "")))
8943 (clobber (reg:CC FLAGS_REG))])
8947 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8949 (define_insn "x86_64_shld"
8950 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8951 (ior:DI (ashift:DI (match_dup 0)
8952 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8953 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8954 (minus:QI (const_int 64) (match_dup 2)))))
8955 (clobber (reg:CC FLAGS_REG))]
8957 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8958 [(set_attr "type" "ishift")
8959 (set_attr "prefix_0f" "1")
8960 (set_attr "mode" "DI")
8961 (set_attr "athlon_decode" "vector")
8962 (set_attr "amdfam10_decode" "vector")
8963 (set_attr "bdver1_decode" "vector")])
8965 (define_insn "x86_shld"
8966 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8967 (ior:SI (ashift:SI (match_dup 0)
8968 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8969 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8970 (minus:QI (const_int 32) (match_dup 2)))))
8971 (clobber (reg:CC FLAGS_REG))]
8973 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8974 [(set_attr "type" "ishift")
8975 (set_attr "prefix_0f" "1")
8976 (set_attr "mode" "SI")
8977 (set_attr "pent_pair" "np")
8978 (set_attr "athlon_decode" "vector")
8979 (set_attr "amdfam10_decode" "vector")
8980 (set_attr "bdver1_decode" "vector")])
8982 (define_expand "x86_shift<mode>_adj_1"
8983 [(set (reg:CCZ FLAGS_REG)
8984 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8987 (set (match_operand:SWI48 0 "register_operand" "")
8988 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8989 (match_operand:SWI48 1 "register_operand" "")
8992 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8993 (match_operand:SWI48 3 "register_operand" "r")
8996 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8998 (define_expand "x86_shift<mode>_adj_2"
8999 [(use (match_operand:SWI48 0 "register_operand" ""))
9000 (use (match_operand:SWI48 1 "register_operand" ""))
9001 (use (match_operand:QI 2 "register_operand" ""))]
9004 rtx label = gen_label_rtx ();
9007 emit_insn (gen_testqi_ccz_1 (operands[2],
9008 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9010 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9011 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9012 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9013 gen_rtx_LABEL_REF (VOIDmode, label),
9015 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9016 JUMP_LABEL (tmp) = label;
9018 emit_move_insn (operands[0], operands[1]);
9019 ix86_expand_clear (operands[1]);
9022 LABEL_NUSES (label) = 1;
9027 ;; Avoid useless masking of count operand.
9028 (define_insn_and_split "*ashl<mode>3_mask"
9029 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9031 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9034 (match_operand:SI 2 "nonimmediate_operand" "c")
9035 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9036 (clobber (reg:CC FLAGS_REG))]
9037 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9038 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9039 == GET_MODE_BITSIZE (<MODE>mode)-1"
9042 [(parallel [(set (match_dup 0)
9043 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9044 (clobber (reg:CC FLAGS_REG))])]
9046 if (can_create_pseudo_p ())
9047 operands [2] = force_reg (SImode, operands[2]);
9049 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9051 [(set_attr "type" "ishift")
9052 (set_attr "mode" "<MODE>")])
9054 (define_insn "*ashl<mode>3_1"
9055 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9056 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9057 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9058 (clobber (reg:CC FLAGS_REG))]
9059 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9061 switch (get_attr_type (insn))
9067 gcc_assert (operands[2] == const1_rtx);
9068 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9069 return "add{<imodesuffix>}\t%0, %0";
9072 if (operands[2] == const1_rtx
9073 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9074 return "sal{<imodesuffix>}\t%0";
9076 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9080 (cond [(eq_attr "alternative" "1")
9081 (const_string "lea")
9082 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9084 (match_operand 0 "register_operand" ""))
9085 (match_operand 2 "const1_operand" ""))
9086 (const_string "alu")
9088 (const_string "ishift")))
9089 (set (attr "length_immediate")
9091 (ior (eq_attr "type" "alu")
9092 (and (eq_attr "type" "ishift")
9093 (and (match_operand 2 "const1_operand" "")
9094 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9097 (const_string "*")))
9098 (set_attr "mode" "<MODE>")])
9100 (define_insn "*ashlsi3_1_zext"
9101 [(set (match_operand:DI 0 "register_operand" "=r,r")
9103 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9104 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9105 (clobber (reg:CC FLAGS_REG))]
9106 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9108 switch (get_attr_type (insn))
9114 gcc_assert (operands[2] == const1_rtx);
9115 return "add{l}\t%k0, %k0";
9118 if (operands[2] == const1_rtx
9119 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9120 return "sal{l}\t%k0";
9122 return "sal{l}\t{%2, %k0|%k0, %2}";
9126 (cond [(eq_attr "alternative" "1")
9127 (const_string "lea")
9128 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9130 (match_operand 2 "const1_operand" ""))
9131 (const_string "alu")
9133 (const_string "ishift")))
9134 (set (attr "length_immediate")
9136 (ior (eq_attr "type" "alu")
9137 (and (eq_attr "type" "ishift")
9138 (and (match_operand 2 "const1_operand" "")
9139 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9142 (const_string "*")))
9143 (set_attr "mode" "SI")])
9145 (define_insn "*ashlhi3_1"
9146 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9147 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9148 (match_operand:QI 2 "nonmemory_operand" "cI")))
9149 (clobber (reg:CC FLAGS_REG))]
9150 "TARGET_PARTIAL_REG_STALL
9151 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9153 switch (get_attr_type (insn))
9156 gcc_assert (operands[2] == const1_rtx);
9157 return "add{w}\t%0, %0";
9160 if (operands[2] == const1_rtx
9161 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9162 return "sal{w}\t%0";
9164 return "sal{w}\t{%2, %0|%0, %2}";
9168 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9170 (match_operand 0 "register_operand" ""))
9171 (match_operand 2 "const1_operand" ""))
9172 (const_string "alu")
9174 (const_string "ishift")))
9175 (set (attr "length_immediate")
9177 (ior (eq_attr "type" "alu")
9178 (and (eq_attr "type" "ishift")
9179 (and (match_operand 2 "const1_operand" "")
9180 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9183 (const_string "*")))
9184 (set_attr "mode" "HI")])
9186 (define_insn "*ashlhi3_1_lea"
9187 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9188 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9189 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9190 (clobber (reg:CC FLAGS_REG))]
9191 "!TARGET_PARTIAL_REG_STALL
9192 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9194 switch (get_attr_type (insn))
9200 gcc_assert (operands[2] == const1_rtx);
9201 return "add{w}\t%0, %0";
9204 if (operands[2] == const1_rtx
9205 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9206 return "sal{w}\t%0";
9208 return "sal{w}\t{%2, %0|%0, %2}";
9212 (cond [(eq_attr "alternative" "1")
9213 (const_string "lea")
9214 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9216 (match_operand 0 "register_operand" ""))
9217 (match_operand 2 "const1_operand" ""))
9218 (const_string "alu")
9220 (const_string "ishift")))
9221 (set (attr "length_immediate")
9223 (ior (eq_attr "type" "alu")
9224 (and (eq_attr "type" "ishift")
9225 (and (match_operand 2 "const1_operand" "")
9226 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9229 (const_string "*")))
9230 (set_attr "mode" "HI,SI")])
9232 (define_insn "*ashlqi3_1"
9233 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9234 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9235 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9236 (clobber (reg:CC FLAGS_REG))]
9237 "TARGET_PARTIAL_REG_STALL
9238 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9240 switch (get_attr_type (insn))
9243 gcc_assert (operands[2] == const1_rtx);
9244 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9245 return "add{l}\t%k0, %k0";
9247 return "add{b}\t%0, %0";
9250 if (operands[2] == const1_rtx
9251 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9253 if (get_attr_mode (insn) == MODE_SI)
9254 return "sal{l}\t%k0";
9256 return "sal{b}\t%0";
9260 if (get_attr_mode (insn) == MODE_SI)
9261 return "sal{l}\t{%2, %k0|%k0, %2}";
9263 return "sal{b}\t{%2, %0|%0, %2}";
9268 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9270 (match_operand 0 "register_operand" ""))
9271 (match_operand 2 "const1_operand" ""))
9272 (const_string "alu")
9274 (const_string "ishift")))
9275 (set (attr "length_immediate")
9277 (ior (eq_attr "type" "alu")
9278 (and (eq_attr "type" "ishift")
9279 (and (match_operand 2 "const1_operand" "")
9280 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9283 (const_string "*")))
9284 (set_attr "mode" "QI,SI")])
9286 ;; %%% Potential partial reg stall on alternative 2. What to do?
9287 (define_insn "*ashlqi3_1_lea"
9288 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9289 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9290 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9291 (clobber (reg:CC FLAGS_REG))]
9292 "!TARGET_PARTIAL_REG_STALL
9293 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9295 switch (get_attr_type (insn))
9301 gcc_assert (operands[2] == const1_rtx);
9302 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9303 return "add{l}\t%k0, %k0";
9305 return "add{b}\t%0, %0";
9308 if (operands[2] == const1_rtx
9309 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9311 if (get_attr_mode (insn) == MODE_SI)
9312 return "sal{l}\t%k0";
9314 return "sal{b}\t%0";
9318 if (get_attr_mode (insn) == MODE_SI)
9319 return "sal{l}\t{%2, %k0|%k0, %2}";
9321 return "sal{b}\t{%2, %0|%0, %2}";
9326 (cond [(eq_attr "alternative" "2")
9327 (const_string "lea")
9328 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9330 (match_operand 0 "register_operand" ""))
9331 (match_operand 2 "const1_operand" ""))
9332 (const_string "alu")
9334 (const_string "ishift")))
9335 (set (attr "length_immediate")
9337 (ior (eq_attr "type" "alu")
9338 (and (eq_attr "type" "ishift")
9339 (and (match_operand 2 "const1_operand" "")
9340 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9343 (const_string "*")))
9344 (set_attr "mode" "QI,SI,SI")])
9346 (define_insn "*ashlqi3_1_slp"
9347 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9348 (ashift:QI (match_dup 0)
9349 (match_operand:QI 1 "nonmemory_operand" "cI")))
9350 (clobber (reg:CC FLAGS_REG))]
9351 "(optimize_function_for_size_p (cfun)
9352 || !TARGET_PARTIAL_FLAG_REG_STALL
9353 || (operands[1] == const1_rtx
9355 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9357 switch (get_attr_type (insn))
9360 gcc_assert (operands[1] == const1_rtx);
9361 return "add{b}\t%0, %0";
9364 if (operands[1] == const1_rtx
9365 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9366 return "sal{b}\t%0";
9368 return "sal{b}\t{%1, %0|%0, %1}";
9372 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9374 (match_operand 0 "register_operand" ""))
9375 (match_operand 1 "const1_operand" ""))
9376 (const_string "alu")
9378 (const_string "ishift1")))
9379 (set (attr "length_immediate")
9381 (ior (eq_attr "type" "alu")
9382 (and (eq_attr "type" "ishift1")
9383 (and (match_operand 1 "const1_operand" "")
9384 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9387 (const_string "*")))
9388 (set_attr "mode" "QI")])
9390 ;; Convert lea to the lea pattern to avoid flags dependency.
9392 [(set (match_operand 0 "register_operand" "")
9393 (ashift (match_operand 1 "index_register_operand" "")
9394 (match_operand:QI 2 "const_int_operand" "")))
9395 (clobber (reg:CC FLAGS_REG))]
9397 && true_regnum (operands[0]) != true_regnum (operands[1])"
9401 enum machine_mode mode = GET_MODE (operands[0]);
9404 operands[1] = gen_lowpart (Pmode, operands[1]);
9405 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9407 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9409 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9410 operands[0] = gen_lowpart (SImode, operands[0]);
9412 if (TARGET_64BIT && mode != Pmode)
9413 pat = gen_rtx_SUBREG (SImode, pat, 0);
9415 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9419 ;; Convert lea to the lea pattern to avoid flags dependency.
9421 [(set (match_operand:DI 0 "register_operand" "")
9423 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9424 (match_operand:QI 2 "const_int_operand" ""))))
9425 (clobber (reg:CC FLAGS_REG))]
9426 "TARGET_64BIT && reload_completed
9427 && true_regnum (operands[0]) != true_regnum (operands[1])"
9429 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9431 operands[1] = gen_lowpart (DImode, operands[1]);
9432 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9435 ;; This pattern can't accept a variable shift count, since shifts by
9436 ;; zero don't affect the flags. We assume that shifts by constant
9437 ;; zero are optimized away.
9438 (define_insn "*ashl<mode>3_cmp"
9439 [(set (reg FLAGS_REG)
9441 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9442 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9444 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9445 (ashift:SWI (match_dup 1) (match_dup 2)))]
9446 "(optimize_function_for_size_p (cfun)
9447 || !TARGET_PARTIAL_FLAG_REG_STALL
9448 || (operands[2] == const1_rtx
9450 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9451 && ix86_match_ccmode (insn, CCGOCmode)
9452 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9454 switch (get_attr_type (insn))
9457 gcc_assert (operands[2] == const1_rtx);
9458 return "add{<imodesuffix>}\t%0, %0";
9461 if (operands[2] == const1_rtx
9462 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9463 return "sal{<imodesuffix>}\t%0";
9465 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9469 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9471 (match_operand 0 "register_operand" ""))
9472 (match_operand 2 "const1_operand" ""))
9473 (const_string "alu")
9475 (const_string "ishift")))
9476 (set (attr "length_immediate")
9478 (ior (eq_attr "type" "alu")
9479 (and (eq_attr "type" "ishift")
9480 (and (match_operand 2 "const1_operand" "")
9481 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9484 (const_string "*")))
9485 (set_attr "mode" "<MODE>")])
9487 (define_insn "*ashlsi3_cmp_zext"
9488 [(set (reg FLAGS_REG)
9490 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9491 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9493 (set (match_operand:DI 0 "register_operand" "=r")
9494 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9496 && (optimize_function_for_size_p (cfun)
9497 || !TARGET_PARTIAL_FLAG_REG_STALL
9498 || (operands[2] == const1_rtx
9500 || TARGET_DOUBLE_WITH_ADD)))
9501 && ix86_match_ccmode (insn, CCGOCmode)
9502 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9504 switch (get_attr_type (insn))
9507 gcc_assert (operands[2] == const1_rtx);
9508 return "add{l}\t%k0, %k0";
9511 if (operands[2] == const1_rtx
9512 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513 return "sal{l}\t%k0";
9515 return "sal{l}\t{%2, %k0|%k0, %2}";
9519 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9521 (match_operand 2 "const1_operand" ""))
9522 (const_string "alu")
9524 (const_string "ishift")))
9525 (set (attr "length_immediate")
9527 (ior (eq_attr "type" "alu")
9528 (and (eq_attr "type" "ishift")
9529 (and (match_operand 2 "const1_operand" "")
9530 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9533 (const_string "*")))
9534 (set_attr "mode" "SI")])
9536 (define_insn "*ashl<mode>3_cconly"
9537 [(set (reg FLAGS_REG)
9539 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9540 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9542 (clobber (match_scratch:SWI 0 "=<r>"))]
9543 "(optimize_function_for_size_p (cfun)
9544 || !TARGET_PARTIAL_FLAG_REG_STALL
9545 || (operands[2] == const1_rtx
9547 || TARGET_DOUBLE_WITH_ADD)))
9548 && ix86_match_ccmode (insn, CCGOCmode)"
9550 switch (get_attr_type (insn))
9553 gcc_assert (operands[2] == const1_rtx);
9554 return "add{<imodesuffix>}\t%0, %0";
9557 if (operands[2] == const1_rtx
9558 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9559 return "sal{<imodesuffix>}\t%0";
9561 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9565 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9567 (match_operand 0 "register_operand" ""))
9568 (match_operand 2 "const1_operand" ""))
9569 (const_string "alu")
9571 (const_string "ishift")))
9572 (set (attr "length_immediate")
9574 (ior (eq_attr "type" "alu")
9575 (and (eq_attr "type" "ishift")
9576 (and (match_operand 2 "const1_operand" "")
9577 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9580 (const_string "*")))
9581 (set_attr "mode" "<MODE>")])
9583 ;; See comment above `ashl<mode>3' about how this works.
9585 (define_expand "<shiftrt_insn><mode>3"
9586 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9587 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9588 (match_operand:QI 2 "nonmemory_operand" "")))]
9590 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9592 ;; Avoid useless masking of count operand.
9593 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9594 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9596 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9599 (match_operand:SI 2 "nonimmediate_operand" "c")
9600 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9601 (clobber (reg:CC FLAGS_REG))]
9602 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9603 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9604 == GET_MODE_BITSIZE (<MODE>mode)-1"
9607 [(parallel [(set (match_dup 0)
9608 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9609 (clobber (reg:CC FLAGS_REG))])]
9611 if (can_create_pseudo_p ())
9612 operands [2] = force_reg (SImode, operands[2]);
9614 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9616 [(set_attr "type" "ishift")
9617 (set_attr "mode" "<MODE>")])
9619 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9620 [(set (match_operand:DWI 0 "register_operand" "=r")
9621 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9622 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9623 (clobber (reg:CC FLAGS_REG))]
9626 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9628 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9629 [(set_attr "type" "multi")])
9631 ;; By default we don't ask for a scratch register, because when DWImode
9632 ;; values are manipulated, registers are already at a premium. But if
9633 ;; we have one handy, we won't turn it away.
9636 [(match_scratch:DWIH 3 "r")
9637 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9639 (match_operand:<DWI> 1 "register_operand" "")
9640 (match_operand:QI 2 "nonmemory_operand" "")))
9641 (clobber (reg:CC FLAGS_REG))])
9645 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9647 (define_insn "x86_64_shrd"
9648 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9649 (ior:DI (ashiftrt:DI (match_dup 0)
9650 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9651 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9652 (minus:QI (const_int 64) (match_dup 2)))))
9653 (clobber (reg:CC FLAGS_REG))]
9655 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9656 [(set_attr "type" "ishift")
9657 (set_attr "prefix_0f" "1")
9658 (set_attr "mode" "DI")
9659 (set_attr "athlon_decode" "vector")
9660 (set_attr "amdfam10_decode" "vector")
9661 (set_attr "bdver1_decode" "vector")])
9663 (define_insn "x86_shrd"
9664 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9665 (ior:SI (ashiftrt:SI (match_dup 0)
9666 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9667 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9668 (minus:QI (const_int 32) (match_dup 2)))))
9669 (clobber (reg:CC FLAGS_REG))]
9671 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9672 [(set_attr "type" "ishift")
9673 (set_attr "prefix_0f" "1")
9674 (set_attr "mode" "SI")
9675 (set_attr "pent_pair" "np")
9676 (set_attr "athlon_decode" "vector")
9677 (set_attr "amdfam10_decode" "vector")
9678 (set_attr "bdver1_decode" "vector")])
9680 (define_insn "ashrdi3_cvt"
9681 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9682 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9683 (match_operand:QI 2 "const_int_operand" "")))
9684 (clobber (reg:CC FLAGS_REG))]
9685 "TARGET_64BIT && INTVAL (operands[2]) == 63
9686 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9687 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9690 sar{q}\t{%2, %0|%0, %2}"
9691 [(set_attr "type" "imovx,ishift")
9692 (set_attr "prefix_0f" "0,*")
9693 (set_attr "length_immediate" "0,*")
9694 (set_attr "modrm" "0,1")
9695 (set_attr "mode" "DI")])
9697 (define_insn "ashrsi3_cvt"
9698 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9699 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9700 (match_operand:QI 2 "const_int_operand" "")))
9701 (clobber (reg:CC FLAGS_REG))]
9702 "INTVAL (operands[2]) == 31
9703 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9704 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9707 sar{l}\t{%2, %0|%0, %2}"
9708 [(set_attr "type" "imovx,ishift")
9709 (set_attr "prefix_0f" "0,*")
9710 (set_attr "length_immediate" "0,*")
9711 (set_attr "modrm" "0,1")
9712 (set_attr "mode" "SI")])
9714 (define_insn "*ashrsi3_cvt_zext"
9715 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9717 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9718 (match_operand:QI 2 "const_int_operand" ""))))
9719 (clobber (reg:CC FLAGS_REG))]
9720 "TARGET_64BIT && INTVAL (operands[2]) == 31
9721 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9722 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9725 sar{l}\t{%2, %k0|%k0, %2}"
9726 [(set_attr "type" "imovx,ishift")
9727 (set_attr "prefix_0f" "0,*")
9728 (set_attr "length_immediate" "0,*")
9729 (set_attr "modrm" "0,1")
9730 (set_attr "mode" "SI")])
9732 (define_expand "x86_shift<mode>_adj_3"
9733 [(use (match_operand:SWI48 0 "register_operand" ""))
9734 (use (match_operand:SWI48 1 "register_operand" ""))
9735 (use (match_operand:QI 2 "register_operand" ""))]
9738 rtx label = gen_label_rtx ();
9741 emit_insn (gen_testqi_ccz_1 (operands[2],
9742 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9744 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9745 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9746 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9747 gen_rtx_LABEL_REF (VOIDmode, label),
9749 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9750 JUMP_LABEL (tmp) = label;
9752 emit_move_insn (operands[0], operands[1]);
9753 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9754 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9756 LABEL_NUSES (label) = 1;
9761 (define_insn "*<shiftrt_insn><mode>3_1"
9762 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9763 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9764 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9765 (clobber (reg:CC FLAGS_REG))]
9766 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9768 if (operands[2] == const1_rtx
9769 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9770 return "<shiftrt>{<imodesuffix>}\t%0";
9772 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9774 [(set_attr "type" "ishift")
9775 (set (attr "length_immediate")
9777 (and (match_operand 2 "const1_operand" "")
9778 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9781 (const_string "*")))
9782 (set_attr "mode" "<MODE>")])
9784 (define_insn "*<shiftrt_insn>si3_1_zext"
9785 [(set (match_operand:DI 0 "register_operand" "=r")
9787 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9788 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9789 (clobber (reg:CC FLAGS_REG))]
9790 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9792 if (operands[2] == const1_rtx
9793 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9794 return "<shiftrt>{l}\t%k0";
9796 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9798 [(set_attr "type" "ishift")
9799 (set (attr "length_immediate")
9801 (and (match_operand 2 "const1_operand" "")
9802 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9805 (const_string "*")))
9806 (set_attr "mode" "SI")])
9808 (define_insn "*<shiftrt_insn>qi3_1_slp"
9809 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9810 (any_shiftrt:QI (match_dup 0)
9811 (match_operand:QI 1 "nonmemory_operand" "cI")))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "(optimize_function_for_size_p (cfun)
9814 || !TARGET_PARTIAL_REG_STALL
9815 || (operands[1] == const1_rtx
9818 if (operands[1] == const1_rtx
9819 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9820 return "<shiftrt>{b}\t%0";
9822 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9824 [(set_attr "type" "ishift1")
9825 (set (attr "length_immediate")
9827 (and (match_operand 1 "const1_operand" "")
9828 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9831 (const_string "*")))
9832 (set_attr "mode" "QI")])
9834 ;; This pattern can't accept a variable shift count, since shifts by
9835 ;; zero don't affect the flags. We assume that shifts by constant
9836 ;; zero are optimized away.
9837 (define_insn "*<shiftrt_insn><mode>3_cmp"
9838 [(set (reg FLAGS_REG)
9841 (match_operand:SWI 1 "nonimmediate_operand" "0")
9842 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9844 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9845 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9846 "(optimize_function_for_size_p (cfun)
9847 || !TARGET_PARTIAL_FLAG_REG_STALL
9848 || (operands[2] == const1_rtx
9850 && ix86_match_ccmode (insn, CCGOCmode)
9851 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9853 if (operands[2] == const1_rtx
9854 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9855 return "<shiftrt>{<imodesuffix>}\t%0";
9857 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9859 [(set_attr "type" "ishift")
9860 (set (attr "length_immediate")
9862 (and (match_operand 2 "const1_operand" "")
9863 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9866 (const_string "*")))
9867 (set_attr "mode" "<MODE>")])
9869 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9870 [(set (reg FLAGS_REG)
9872 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9873 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9875 (set (match_operand:DI 0 "register_operand" "=r")
9876 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9878 && (optimize_function_for_size_p (cfun)
9879 || !TARGET_PARTIAL_FLAG_REG_STALL
9880 || (operands[2] == const1_rtx
9882 && ix86_match_ccmode (insn, CCGOCmode)
9883 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9885 if (operands[2] == const1_rtx
9886 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9887 return "<shiftrt>{l}\t%k0";
9889 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9891 [(set_attr "type" "ishift")
9892 (set (attr "length_immediate")
9894 (and (match_operand 2 "const1_operand" "")
9895 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9898 (const_string "*")))
9899 (set_attr "mode" "SI")])
9901 (define_insn "*<shiftrt_insn><mode>3_cconly"
9902 [(set (reg FLAGS_REG)
9905 (match_operand:SWI 1 "register_operand" "0")
9906 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9908 (clobber (match_scratch:SWI 0 "=<r>"))]
9909 "(optimize_function_for_size_p (cfun)
9910 || !TARGET_PARTIAL_FLAG_REG_STALL
9911 || (operands[2] == const1_rtx
9913 && ix86_match_ccmode (insn, CCGOCmode)"
9915 if (operands[2] == const1_rtx
9916 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9917 return "<shiftrt>{<imodesuffix>}\t%0";
9919 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9921 [(set_attr "type" "ishift")
9922 (set (attr "length_immediate")
9924 (and (match_operand 2 "const1_operand" "")
9925 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9928 (const_string "*")))
9929 (set_attr "mode" "<MODE>")])
9931 ;; Rotate instructions
9933 (define_expand "<rotate_insn>ti3"
9934 [(set (match_operand:TI 0 "register_operand" "")
9935 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9936 (match_operand:QI 2 "nonmemory_operand" "")))]
9939 if (const_1_to_63_operand (operands[2], VOIDmode))
9940 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9941 (operands[0], operands[1], operands[2]));
9948 (define_expand "<rotate_insn>di3"
9949 [(set (match_operand:DI 0 "shiftdi_operand" "")
9950 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9951 (match_operand:QI 2 "nonmemory_operand" "")))]
9955 ix86_expand_binary_operator (<CODE>, DImode, operands);
9956 else if (const_1_to_31_operand (operands[2], VOIDmode))
9957 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9958 (operands[0], operands[1], operands[2]));
9965 (define_expand "<rotate_insn><mode>3"
9966 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9967 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9968 (match_operand:QI 2 "nonmemory_operand" "")))]
9970 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9972 ;; Avoid useless masking of count operand.
9973 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9974 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9976 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9979 (match_operand:SI 2 "nonimmediate_operand" "c")
9980 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9981 (clobber (reg:CC FLAGS_REG))]
9982 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9983 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9984 == GET_MODE_BITSIZE (<MODE>mode)-1"
9987 [(parallel [(set (match_dup 0)
9988 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9989 (clobber (reg:CC FLAGS_REG))])]
9991 if (can_create_pseudo_p ())
9992 operands [2] = force_reg (SImode, operands[2]);
9994 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9996 [(set_attr "type" "rotate")
9997 (set_attr "mode" "<MODE>")])
9999 ;; Implement rotation using two double-precision
10000 ;; shift instructions and a scratch register.
10002 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10003 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10004 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10005 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10006 (clobber (reg:CC FLAGS_REG))
10007 (clobber (match_scratch:DWIH 3 "=&r"))]
10011 [(set (match_dup 3) (match_dup 4))
10013 [(set (match_dup 4)
10014 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10015 (lshiftrt:DWIH (match_dup 5)
10016 (minus:QI (match_dup 6) (match_dup 2)))))
10017 (clobber (reg:CC FLAGS_REG))])
10019 [(set (match_dup 5)
10020 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10021 (lshiftrt:DWIH (match_dup 3)
10022 (minus:QI (match_dup 6) (match_dup 2)))))
10023 (clobber (reg:CC FLAGS_REG))])]
10025 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10027 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10030 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10031 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10032 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10033 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10034 (clobber (reg:CC FLAGS_REG))
10035 (clobber (match_scratch:DWIH 3 "=&r"))]
10039 [(set (match_dup 3) (match_dup 4))
10041 [(set (match_dup 4)
10042 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10043 (ashift:DWIH (match_dup 5)
10044 (minus:QI (match_dup 6) (match_dup 2)))))
10045 (clobber (reg:CC FLAGS_REG))])
10047 [(set (match_dup 5)
10048 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10049 (ashift:DWIH (match_dup 3)
10050 (minus:QI (match_dup 6) (match_dup 2)))))
10051 (clobber (reg:CC FLAGS_REG))])]
10053 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10055 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10058 (define_insn "*<rotate_insn><mode>3_1"
10059 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10060 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10061 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10062 (clobber (reg:CC FLAGS_REG))]
10063 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10065 if (operands[2] == const1_rtx
10066 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10067 return "<rotate>{<imodesuffix>}\t%0";
10069 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10071 [(set_attr "type" "rotate")
10072 (set (attr "length_immediate")
10074 (and (match_operand 2 "const1_operand" "")
10075 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10078 (const_string "*")))
10079 (set_attr "mode" "<MODE>")])
10081 (define_insn "*<rotate_insn>si3_1_zext"
10082 [(set (match_operand:DI 0 "register_operand" "=r")
10084 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10085 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10086 (clobber (reg:CC FLAGS_REG))]
10087 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10089 if (operands[2] == const1_rtx
10090 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10091 return "<rotate>{l}\t%k0";
10093 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10095 [(set_attr "type" "rotate")
10096 (set (attr "length_immediate")
10098 (and (match_operand 2 "const1_operand" "")
10099 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10102 (const_string "*")))
10103 (set_attr "mode" "SI")])
10105 (define_insn "*<rotate_insn>qi3_1_slp"
10106 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10107 (any_rotate:QI (match_dup 0)
10108 (match_operand:QI 1 "nonmemory_operand" "cI")))
10109 (clobber (reg:CC FLAGS_REG))]
10110 "(optimize_function_for_size_p (cfun)
10111 || !TARGET_PARTIAL_REG_STALL
10112 || (operands[1] == const1_rtx
10113 && TARGET_SHIFT1))"
10115 if (operands[1] == const1_rtx
10116 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10117 return "<rotate>{b}\t%0";
10119 return "<rotate>{b}\t{%1, %0|%0, %1}";
10121 [(set_attr "type" "rotate1")
10122 (set (attr "length_immediate")
10124 (and (match_operand 1 "const1_operand" "")
10125 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10128 (const_string "*")))
10129 (set_attr "mode" "QI")])
10132 [(set (match_operand:HI 0 "register_operand" "")
10133 (any_rotate:HI (match_dup 0) (const_int 8)))
10134 (clobber (reg:CC FLAGS_REG))]
10136 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10137 [(parallel [(set (strict_low_part (match_dup 0))
10138 (bswap:HI (match_dup 0)))
10139 (clobber (reg:CC FLAGS_REG))])])
10141 ;; Bit set / bit test instructions
10143 (define_expand "extv"
10144 [(set (match_operand:SI 0 "register_operand" "")
10145 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10146 (match_operand:SI 2 "const8_operand" "")
10147 (match_operand:SI 3 "const8_operand" "")))]
10150 /* Handle extractions from %ah et al. */
10151 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10154 /* From mips.md: extract_bit_field doesn't verify that our source
10155 matches the predicate, so check it again here. */
10156 if (! ext_register_operand (operands[1], VOIDmode))
10160 (define_expand "extzv"
10161 [(set (match_operand:SI 0 "register_operand" "")
10162 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10163 (match_operand:SI 2 "const8_operand" "")
10164 (match_operand:SI 3 "const8_operand" "")))]
10167 /* Handle extractions from %ah et al. */
10168 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10171 /* From mips.md: extract_bit_field doesn't verify that our source
10172 matches the predicate, so check it again here. */
10173 if (! ext_register_operand (operands[1], VOIDmode))
10177 (define_expand "insv"
10178 [(set (zero_extract (match_operand 0 "register_operand" "")
10179 (match_operand 1 "const_int_operand" "")
10180 (match_operand 2 "const_int_operand" ""))
10181 (match_operand 3 "register_operand" ""))]
10184 rtx (*gen_mov_insv_1) (rtx, rtx);
10186 if (ix86_expand_pinsr (operands))
10189 /* Handle insertions to %ah et al. */
10190 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10193 /* From mips.md: insert_bit_field doesn't verify that our source
10194 matches the predicate, so check it again here. */
10195 if (! ext_register_operand (operands[0], VOIDmode))
10198 gen_mov_insv_1 = (TARGET_64BIT
10199 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10201 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10205 ;; %%% bts, btr, btc, bt.
10206 ;; In general these instructions are *slow* when applied to memory,
10207 ;; since they enforce atomic operation. When applied to registers,
10208 ;; it depends on the cpu implementation. They're never faster than
10209 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10210 ;; no point. But in 64-bit, we can't hold the relevant immediates
10211 ;; within the instruction itself, so operating on bits in the high
10212 ;; 32-bits of a register becomes easier.
10214 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10215 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10216 ;; negdf respectively, so they can never be disabled entirely.
10218 (define_insn "*btsq"
10219 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10221 (match_operand:DI 1 "const_0_to_63_operand" ""))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10225 "bts{q}\t{%1, %0|%0, %1}"
10226 [(set_attr "type" "alu1")
10227 (set_attr "prefix_0f" "1")
10228 (set_attr "mode" "DI")])
10230 (define_insn "*btrq"
10231 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10233 (match_operand:DI 1 "const_0_to_63_operand" ""))
10235 (clobber (reg:CC FLAGS_REG))]
10236 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10237 "btr{q}\t{%1, %0|%0, %1}"
10238 [(set_attr "type" "alu1")
10239 (set_attr "prefix_0f" "1")
10240 (set_attr "mode" "DI")])
10242 (define_insn "*btcq"
10243 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10245 (match_operand:DI 1 "const_0_to_63_operand" ""))
10246 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10247 (clobber (reg:CC FLAGS_REG))]
10248 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10249 "btc{q}\t{%1, %0|%0, %1}"
10250 [(set_attr "type" "alu1")
10251 (set_attr "prefix_0f" "1")
10252 (set_attr "mode" "DI")])
10254 ;; Allow Nocona to avoid these instructions if a register is available.
10257 [(match_scratch:DI 2 "r")
10258 (parallel [(set (zero_extract:DI
10259 (match_operand:DI 0 "register_operand" "")
10261 (match_operand:DI 1 "const_0_to_63_operand" ""))
10263 (clobber (reg:CC FLAGS_REG))])]
10264 "TARGET_64BIT && !TARGET_USE_BT"
10267 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10270 if (HOST_BITS_PER_WIDE_INT >= 64)
10271 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10272 else if (i < HOST_BITS_PER_WIDE_INT)
10273 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10275 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10277 op1 = immed_double_const (lo, hi, DImode);
10280 emit_move_insn (operands[2], op1);
10284 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10289 [(match_scratch:DI 2 "r")
10290 (parallel [(set (zero_extract:DI
10291 (match_operand:DI 0 "register_operand" "")
10293 (match_operand:DI 1 "const_0_to_63_operand" ""))
10295 (clobber (reg:CC FLAGS_REG))])]
10296 "TARGET_64BIT && !TARGET_USE_BT"
10299 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10302 if (HOST_BITS_PER_WIDE_INT >= 64)
10303 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10304 else if (i < HOST_BITS_PER_WIDE_INT)
10305 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10307 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10309 op1 = immed_double_const (~lo, ~hi, DImode);
10312 emit_move_insn (operands[2], op1);
10316 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10321 [(match_scratch:DI 2 "r")
10322 (parallel [(set (zero_extract:DI
10323 (match_operand:DI 0 "register_operand" "")
10325 (match_operand:DI 1 "const_0_to_63_operand" ""))
10326 (not:DI (zero_extract:DI
10327 (match_dup 0) (const_int 1) (match_dup 1))))
10328 (clobber (reg:CC FLAGS_REG))])]
10329 "TARGET_64BIT && !TARGET_USE_BT"
10332 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10335 if (HOST_BITS_PER_WIDE_INT >= 64)
10336 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10337 else if (i < HOST_BITS_PER_WIDE_INT)
10338 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10340 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10342 op1 = immed_double_const (lo, hi, DImode);
10345 emit_move_insn (operands[2], op1);
10349 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10353 (define_insn "*bt<mode>"
10354 [(set (reg:CCC FLAGS_REG)
10356 (zero_extract:SWI48
10357 (match_operand:SWI48 0 "register_operand" "r")
10359 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10361 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10362 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10363 [(set_attr "type" "alu1")
10364 (set_attr "prefix_0f" "1")
10365 (set_attr "mode" "<MODE>")])
10367 ;; Store-flag instructions.
10369 ;; For all sCOND expanders, also expand the compare or test insn that
10370 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10372 (define_insn_and_split "*setcc_di_1"
10373 [(set (match_operand:DI 0 "register_operand" "=q")
10374 (match_operator:DI 1 "ix86_comparison_operator"
10375 [(reg FLAGS_REG) (const_int 0)]))]
10376 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10378 "&& reload_completed"
10379 [(set (match_dup 2) (match_dup 1))
10380 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10382 PUT_MODE (operands[1], QImode);
10383 operands[2] = gen_lowpart (QImode, operands[0]);
10386 (define_insn_and_split "*setcc_si_1_and"
10387 [(set (match_operand:SI 0 "register_operand" "=q")
10388 (match_operator:SI 1 "ix86_comparison_operator"
10389 [(reg FLAGS_REG) (const_int 0)]))
10390 (clobber (reg:CC FLAGS_REG))]
10391 "!TARGET_PARTIAL_REG_STALL
10392 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10394 "&& reload_completed"
10395 [(set (match_dup 2) (match_dup 1))
10396 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10397 (clobber (reg:CC FLAGS_REG))])]
10399 PUT_MODE (operands[1], QImode);
10400 operands[2] = gen_lowpart (QImode, operands[0]);
10403 (define_insn_and_split "*setcc_si_1_movzbl"
10404 [(set (match_operand:SI 0 "register_operand" "=q")
10405 (match_operator:SI 1 "ix86_comparison_operator"
10406 [(reg FLAGS_REG) (const_int 0)]))]
10407 "!TARGET_PARTIAL_REG_STALL
10408 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10410 "&& reload_completed"
10411 [(set (match_dup 2) (match_dup 1))
10412 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10414 PUT_MODE (operands[1], QImode);
10415 operands[2] = gen_lowpart (QImode, operands[0]);
10418 (define_insn "*setcc_qi"
10419 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10420 (match_operator:QI 1 "ix86_comparison_operator"
10421 [(reg FLAGS_REG) (const_int 0)]))]
10424 [(set_attr "type" "setcc")
10425 (set_attr "mode" "QI")])
10427 (define_insn "*setcc_qi_slp"
10428 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10429 (match_operator:QI 1 "ix86_comparison_operator"
10430 [(reg FLAGS_REG) (const_int 0)]))]
10433 [(set_attr "type" "setcc")
10434 (set_attr "mode" "QI")])
10436 ;; In general it is not safe to assume too much about CCmode registers,
10437 ;; so simplify-rtx stops when it sees a second one. Under certain
10438 ;; conditions this is safe on x86, so help combine not create
10445 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10446 (ne:QI (match_operator 1 "ix86_comparison_operator"
10447 [(reg FLAGS_REG) (const_int 0)])
10450 [(set (match_dup 0) (match_dup 1))]
10451 "PUT_MODE (operands[1], QImode);")
10454 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10455 (ne:QI (match_operator 1 "ix86_comparison_operator"
10456 [(reg FLAGS_REG) (const_int 0)])
10459 [(set (match_dup 0) (match_dup 1))]
10460 "PUT_MODE (operands[1], QImode);")
10463 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10464 (eq:QI (match_operator 1 "ix86_comparison_operator"
10465 [(reg FLAGS_REG) (const_int 0)])
10468 [(set (match_dup 0) (match_dup 1))]
10470 rtx new_op1 = copy_rtx (operands[1]);
10471 operands[1] = new_op1;
10472 PUT_MODE (new_op1, QImode);
10473 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10474 GET_MODE (XEXP (new_op1, 0))));
10476 /* Make sure that (a) the CCmode we have for the flags is strong
10477 enough for the reversed compare or (b) we have a valid FP compare. */
10478 if (! ix86_comparison_operator (new_op1, VOIDmode))
10483 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10484 (eq:QI (match_operator 1 "ix86_comparison_operator"
10485 [(reg FLAGS_REG) (const_int 0)])
10488 [(set (match_dup 0) (match_dup 1))]
10490 rtx new_op1 = copy_rtx (operands[1]);
10491 operands[1] = new_op1;
10492 PUT_MODE (new_op1, QImode);
10493 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10494 GET_MODE (XEXP (new_op1, 0))));
10496 /* Make sure that (a) the CCmode we have for the flags is strong
10497 enough for the reversed compare or (b) we have a valid FP compare. */
10498 if (! ix86_comparison_operator (new_op1, VOIDmode))
10502 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10503 ;; subsequent logical operations are used to imitate conditional moves.
10504 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10507 (define_insn "setcc_<mode>_sse"
10508 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10509 (match_operator:MODEF 3 "sse_comparison_operator"
10510 [(match_operand:MODEF 1 "register_operand" "0,x")
10511 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10512 "SSE_FLOAT_MODE_P (<MODE>mode)"
10514 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10515 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10516 [(set_attr "isa" "noavx,avx")
10517 (set_attr "type" "ssecmp")
10518 (set_attr "length_immediate" "1")
10519 (set_attr "prefix" "orig,vex")
10520 (set_attr "mode" "<MODE>")])
10522 ;; Basic conditional jump instructions.
10523 ;; We ignore the overflow flag for signed branch instructions.
10525 (define_insn "*jcc_1"
10527 (if_then_else (match_operator 1 "ix86_comparison_operator"
10528 [(reg FLAGS_REG) (const_int 0)])
10529 (label_ref (match_operand 0 "" ""))
10533 [(set_attr "type" "ibr")
10534 (set_attr "modrm" "0")
10535 (set (attr "length")
10536 (if_then_else (and (ge (minus (match_dup 0) (pc))
10538 (lt (minus (match_dup 0) (pc))
10543 (define_insn "*jcc_2"
10545 (if_then_else (match_operator 1 "ix86_comparison_operator"
10546 [(reg FLAGS_REG) (const_int 0)])
10548 (label_ref (match_operand 0 "" ""))))]
10551 [(set_attr "type" "ibr")
10552 (set_attr "modrm" "0")
10553 (set (attr "length")
10554 (if_then_else (and (ge (minus (match_dup 0) (pc))
10556 (lt (minus (match_dup 0) (pc))
10561 ;; In general it is not safe to assume too much about CCmode registers,
10562 ;; so simplify-rtx stops when it sees a second one. Under certain
10563 ;; conditions this is safe on x86, so help combine not create
10571 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10572 [(reg FLAGS_REG) (const_int 0)])
10574 (label_ref (match_operand 1 "" ""))
10578 (if_then_else (match_dup 0)
10579 (label_ref (match_dup 1))
10581 "PUT_MODE (operands[0], VOIDmode);")
10585 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10586 [(reg FLAGS_REG) (const_int 0)])
10588 (label_ref (match_operand 1 "" ""))
10592 (if_then_else (match_dup 0)
10593 (label_ref (match_dup 1))
10596 rtx new_op0 = copy_rtx (operands[0]);
10597 operands[0] = new_op0;
10598 PUT_MODE (new_op0, VOIDmode);
10599 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10600 GET_MODE (XEXP (new_op0, 0))));
10602 /* Make sure that (a) the CCmode we have for the flags is strong
10603 enough for the reversed compare or (b) we have a valid FP compare. */
10604 if (! ix86_comparison_operator (new_op0, VOIDmode))
10608 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10609 ;; pass generates from shift insn with QImode operand. Actually, the mode
10610 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10611 ;; appropriate modulo of the bit offset value.
10613 (define_insn_and_split "*jcc_bt<mode>"
10615 (if_then_else (match_operator 0 "bt_comparison_operator"
10616 [(zero_extract:SWI48
10617 (match_operand:SWI48 1 "register_operand" "r")
10620 (match_operand:QI 2 "register_operand" "r")))
10622 (label_ref (match_operand 3 "" ""))
10624 (clobber (reg:CC FLAGS_REG))]
10625 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10628 [(set (reg:CCC FLAGS_REG)
10630 (zero_extract:SWI48
10636 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10637 (label_ref (match_dup 3))
10640 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10642 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10645 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10646 ;; also for DImode, this is what combine produces.
10647 (define_insn_and_split "*jcc_bt<mode>_mask"
10649 (if_then_else (match_operator 0 "bt_comparison_operator"
10650 [(zero_extract:SWI48
10651 (match_operand:SWI48 1 "register_operand" "r")
10654 (match_operand:SI 2 "register_operand" "r")
10655 (match_operand:SI 3 "const_int_operand" "n")))])
10656 (label_ref (match_operand 4 "" ""))
10658 (clobber (reg:CC FLAGS_REG))]
10659 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10660 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10661 == GET_MODE_BITSIZE (<MODE>mode)-1"
10664 [(set (reg:CCC FLAGS_REG)
10666 (zero_extract:SWI48
10672 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10673 (label_ref (match_dup 4))
10676 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10678 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10681 (define_insn_and_split "*jcc_btsi_1"
10683 (if_then_else (match_operator 0 "bt_comparison_operator"
10686 (match_operand:SI 1 "register_operand" "r")
10687 (match_operand:QI 2 "register_operand" "r"))
10690 (label_ref (match_operand 3 "" ""))
10692 (clobber (reg:CC FLAGS_REG))]
10693 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10696 [(set (reg:CCC FLAGS_REG)
10704 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10705 (label_ref (match_dup 3))
10708 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10710 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10713 ;; avoid useless masking of bit offset operand
10714 (define_insn_and_split "*jcc_btsi_mask_1"
10717 (match_operator 0 "bt_comparison_operator"
10720 (match_operand:SI 1 "register_operand" "r")
10723 (match_operand:SI 2 "register_operand" "r")
10724 (match_operand:SI 3 "const_int_operand" "n")) 0))
10727 (label_ref (match_operand 4 "" ""))
10729 (clobber (reg:CC FLAGS_REG))]
10730 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10731 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10734 [(set (reg:CCC FLAGS_REG)
10742 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10743 (label_ref (match_dup 4))
10745 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10747 ;; Define combination compare-and-branch fp compare instructions to help
10750 (define_insn "*fp_jcc_1_387"
10752 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10753 [(match_operand 1 "register_operand" "f")
10754 (match_operand 2 "nonimmediate_operand" "fm")])
10755 (label_ref (match_operand 3 "" ""))
10757 (clobber (reg:CCFP FPSR_REG))
10758 (clobber (reg:CCFP FLAGS_REG))
10759 (clobber (match_scratch:HI 4 "=a"))]
10761 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10762 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10763 && SELECT_CC_MODE (GET_CODE (operands[0]),
10764 operands[1], operands[2]) == CCFPmode
10768 (define_insn "*fp_jcc_1r_387"
10770 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10771 [(match_operand 1 "register_operand" "f")
10772 (match_operand 2 "nonimmediate_operand" "fm")])
10774 (label_ref (match_operand 3 "" ""))))
10775 (clobber (reg:CCFP FPSR_REG))
10776 (clobber (reg:CCFP FLAGS_REG))
10777 (clobber (match_scratch:HI 4 "=a"))]
10779 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10780 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10781 && SELECT_CC_MODE (GET_CODE (operands[0]),
10782 operands[1], operands[2]) == CCFPmode
10786 (define_insn "*fp_jcc_2_387"
10788 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10789 [(match_operand 1 "register_operand" "f")
10790 (match_operand 2 "register_operand" "f")])
10791 (label_ref (match_operand 3 "" ""))
10793 (clobber (reg:CCFP FPSR_REG))
10794 (clobber (reg:CCFP FLAGS_REG))
10795 (clobber (match_scratch:HI 4 "=a"))]
10796 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10797 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10801 (define_insn "*fp_jcc_2r_387"
10803 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10804 [(match_operand 1 "register_operand" "f")
10805 (match_operand 2 "register_operand" "f")])
10807 (label_ref (match_operand 3 "" ""))))
10808 (clobber (reg:CCFP FPSR_REG))
10809 (clobber (reg:CCFP FLAGS_REG))
10810 (clobber (match_scratch:HI 4 "=a"))]
10811 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10812 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10816 (define_insn "*fp_jcc_3_387"
10818 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10819 [(match_operand 1 "register_operand" "f")
10820 (match_operand 2 "const0_operand" "")])
10821 (label_ref (match_operand 3 "" ""))
10823 (clobber (reg:CCFP FPSR_REG))
10824 (clobber (reg:CCFP FLAGS_REG))
10825 (clobber (match_scratch:HI 4 "=a"))]
10826 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10827 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10828 && SELECT_CC_MODE (GET_CODE (operands[0]),
10829 operands[1], operands[2]) == CCFPmode
10835 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10836 [(match_operand 1 "register_operand" "")
10837 (match_operand 2 "nonimmediate_operand" "")])
10838 (match_operand 3 "" "")
10839 (match_operand 4 "" "")))
10840 (clobber (reg:CCFP FPSR_REG))
10841 (clobber (reg:CCFP FLAGS_REG))]
10845 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10846 operands[3], operands[4], NULL_RTX, NULL_RTX);
10852 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10853 [(match_operand 1 "register_operand" "")
10854 (match_operand 2 "general_operand" "")])
10855 (match_operand 3 "" "")
10856 (match_operand 4 "" "")))
10857 (clobber (reg:CCFP FPSR_REG))
10858 (clobber (reg:CCFP FLAGS_REG))
10859 (clobber (match_scratch:HI 5 "=a"))]
10863 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10864 operands[3], operands[4], operands[5], NULL_RTX);
10868 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10869 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10870 ;; with a precedence over other operators and is always put in the first
10871 ;; place. Swap condition and operands to match ficom instruction.
10873 (define_insn "*fp_jcc_4_<mode>_387"
10876 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10877 [(match_operator 1 "float_operator"
10878 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10879 (match_operand 3 "register_operand" "f,f")])
10880 (label_ref (match_operand 4 "" ""))
10882 (clobber (reg:CCFP FPSR_REG))
10883 (clobber (reg:CCFP FLAGS_REG))
10884 (clobber (match_scratch:HI 5 "=a,a"))]
10885 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10886 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10887 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10888 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10895 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10896 [(match_operator 1 "float_operator"
10897 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10898 (match_operand 3 "register_operand" "")])
10899 (match_operand 4 "" "")
10900 (match_operand 5 "" "")))
10901 (clobber (reg:CCFP FPSR_REG))
10902 (clobber (reg:CCFP FLAGS_REG))
10903 (clobber (match_scratch:HI 6 "=a"))]
10907 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10909 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10910 operands[3], operands[7],
10911 operands[4], operands[5], operands[6], NULL_RTX);
10915 ;; %%% Kill this when reload knows how to do it.
10919 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10920 [(match_operator 1 "float_operator"
10921 [(match_operand:X87MODEI12 2 "register_operand" "")])
10922 (match_operand 3 "register_operand" "")])
10923 (match_operand 4 "" "")
10924 (match_operand 5 "" "")))
10925 (clobber (reg:CCFP FPSR_REG))
10926 (clobber (reg:CCFP FLAGS_REG))
10927 (clobber (match_scratch:HI 6 "=a"))]
10931 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10932 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10934 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10935 operands[3], operands[7],
10936 operands[4], operands[5], operands[6], operands[2]);
10940 ;; Unconditional and other jump instructions
10942 (define_insn "jump"
10944 (label_ref (match_operand 0 "" "")))]
10947 [(set_attr "type" "ibr")
10948 (set (attr "length")
10949 (if_then_else (and (ge (minus (match_dup 0) (pc))
10951 (lt (minus (match_dup 0) (pc))
10955 (set_attr "modrm" "0")])
10957 (define_expand "indirect_jump"
10958 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10962 (define_insn "*indirect_jump"
10963 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10966 [(set_attr "type" "ibr")
10967 (set_attr "length_immediate" "0")])
10969 (define_expand "tablejump"
10970 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10971 (use (label_ref (match_operand 1 "" "")))])]
10974 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10975 relative. Convert the relative address to an absolute address. */
10979 enum rtx_code code;
10981 /* We can't use @GOTOFF for text labels on VxWorks;
10982 see gotoff_operand. */
10983 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10987 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10989 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10993 op1 = pic_offset_table_rtx;
10998 op0 = pic_offset_table_rtx;
11002 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11007 (define_insn "*tablejump_1"
11008 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11009 (use (label_ref (match_operand 1 "" "")))]
11012 [(set_attr "type" "ibr")
11013 (set_attr "length_immediate" "0")])
11015 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11018 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11019 (set (match_operand:QI 1 "register_operand" "")
11020 (match_operator:QI 2 "ix86_comparison_operator"
11021 [(reg FLAGS_REG) (const_int 0)]))
11022 (set (match_operand 3 "q_regs_operand" "")
11023 (zero_extend (match_dup 1)))]
11024 "(peep2_reg_dead_p (3, operands[1])
11025 || operands_match_p (operands[1], operands[3]))
11026 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11027 [(set (match_dup 4) (match_dup 0))
11028 (set (strict_low_part (match_dup 5))
11031 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11032 operands[5] = gen_lowpart (QImode, operands[3]);
11033 ix86_expand_clear (operands[3]);
11036 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11039 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11040 (set (match_operand:QI 1 "register_operand" "")
11041 (match_operator:QI 2 "ix86_comparison_operator"
11042 [(reg FLAGS_REG) (const_int 0)]))
11043 (parallel [(set (match_operand 3 "q_regs_operand" "")
11044 (zero_extend (match_dup 1)))
11045 (clobber (reg:CC FLAGS_REG))])]
11046 "(peep2_reg_dead_p (3, operands[1])
11047 || operands_match_p (operands[1], operands[3]))
11048 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11049 [(set (match_dup 4) (match_dup 0))
11050 (set (strict_low_part (match_dup 5))
11053 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11054 operands[5] = gen_lowpart (QImode, operands[3]);
11055 ix86_expand_clear (operands[3]);
11058 ;; Call instructions.
11060 ;; The predicates normally associated with named expanders are not properly
11061 ;; checked for calls. This is a bug in the generic code, but it isn't that
11062 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11064 ;; P6 processors will jump to the address after the decrement when %esp
11065 ;; is used as a call operand, so they will execute return address as a code.
11066 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11068 ;; Register constraint for call instruction.
11069 (define_mode_attr c [(SI "l") (DI "r")])
11071 ;; Call subroutine returning no value.
11073 (define_expand "call"
11074 [(call (match_operand:QI 0 "" "")
11075 (match_operand 1 "" ""))
11076 (use (match_operand 2 "" ""))]
11079 ix86_expand_call (NULL, operands[0], operands[1],
11080 operands[2], NULL, 0);
11084 (define_expand "sibcall"
11085 [(call (match_operand:QI 0 "" "")
11086 (match_operand 1 "" ""))
11087 (use (match_operand 2 "" ""))]
11090 ix86_expand_call (NULL, operands[0], operands[1],
11091 operands[2], NULL, 1);
11095 (define_insn_and_split "*call_vzeroupper"
11096 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11097 (match_operand 1 "" ""))
11098 (unspec [(match_operand 2 "const_int_operand" "")]
11099 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11100 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11102 "&& reload_completed"
11104 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11105 [(set_attr "type" "call")])
11107 (define_insn "*call"
11108 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11109 (match_operand 1 "" ""))]
11110 "!SIBLING_CALL_P (insn)"
11111 "* return ix86_output_call_insn (insn, operands[0]);"
11112 [(set_attr "type" "call")])
11114 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11116 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11117 (match_operand 1 "" ""))
11118 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11119 (clobber (reg:TI XMM6_REG))
11120 (clobber (reg:TI XMM7_REG))
11121 (clobber (reg:TI XMM8_REG))
11122 (clobber (reg:TI XMM9_REG))
11123 (clobber (reg:TI XMM10_REG))
11124 (clobber (reg:TI XMM11_REG))
11125 (clobber (reg:TI XMM12_REG))
11126 (clobber (reg:TI XMM13_REG))
11127 (clobber (reg:TI XMM14_REG))
11128 (clobber (reg:TI XMM15_REG))
11129 (clobber (reg:DI SI_REG))
11130 (clobber (reg:DI DI_REG))])
11131 (unspec [(match_operand 2 "const_int_operand" "")]
11132 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11133 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11135 "&& reload_completed"
11137 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11138 [(set_attr "type" "call")])
11140 (define_insn "*call_rex64_ms_sysv"
11141 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11142 (match_operand 1 "" ""))
11143 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11144 (clobber (reg:TI XMM6_REG))
11145 (clobber (reg:TI XMM7_REG))
11146 (clobber (reg:TI XMM8_REG))
11147 (clobber (reg:TI XMM9_REG))
11148 (clobber (reg:TI XMM10_REG))
11149 (clobber (reg:TI XMM11_REG))
11150 (clobber (reg:TI XMM12_REG))
11151 (clobber (reg:TI XMM13_REG))
11152 (clobber (reg:TI XMM14_REG))
11153 (clobber (reg:TI XMM15_REG))
11154 (clobber (reg:DI SI_REG))
11155 (clobber (reg:DI DI_REG))]
11156 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11157 "* return ix86_output_call_insn (insn, operands[0]);"
11158 [(set_attr "type" "call")])
11160 (define_insn_and_split "*sibcall_vzeroupper"
11161 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11162 (match_operand 1 "" ""))
11163 (unspec [(match_operand 2 "const_int_operand" "")]
11164 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11165 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11167 "&& reload_completed"
11169 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11170 [(set_attr "type" "call")])
11172 (define_insn "*sibcall"
11173 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11174 (match_operand 1 "" ""))]
11175 "SIBLING_CALL_P (insn)"
11176 "* return ix86_output_call_insn (insn, operands[0]);"
11177 [(set_attr "type" "call")])
11179 (define_expand "call_pop"
11180 [(parallel [(call (match_operand:QI 0 "" "")
11181 (match_operand:SI 1 "" ""))
11182 (set (reg:SI SP_REG)
11183 (plus:SI (reg:SI SP_REG)
11184 (match_operand:SI 3 "" "")))])]
11187 ix86_expand_call (NULL, operands[0], operands[1],
11188 operands[2], operands[3], 0);
11192 (define_insn_and_split "*call_pop_vzeroupper"
11194 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11195 (match_operand:SI 1 "" ""))
11196 (set (reg:SI SP_REG)
11197 (plus:SI (reg:SI SP_REG)
11198 (match_operand:SI 2 "immediate_operand" "i")))])
11199 (unspec [(match_operand 3 "const_int_operand" "")]
11200 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11201 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11203 "&& reload_completed"
11205 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11206 [(set_attr "type" "call")])
11208 (define_insn "*call_pop"
11209 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11210 (match_operand 1 "" ""))
11211 (set (reg:SI SP_REG)
11212 (plus:SI (reg:SI SP_REG)
11213 (match_operand:SI 2 "immediate_operand" "i")))]
11214 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11215 "* return ix86_output_call_insn (insn, operands[0]);"
11216 [(set_attr "type" "call")])
11218 (define_insn_and_split "*sibcall_pop_vzeroupper"
11220 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11221 (match_operand 1 "" ""))
11222 (set (reg:SI SP_REG)
11223 (plus:SI (reg:SI SP_REG)
11224 (match_operand:SI 2 "immediate_operand" "i")))])
11225 (unspec [(match_operand 3 "const_int_operand" "")]
11226 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11227 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11229 "&& reload_completed"
11231 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11232 [(set_attr "type" "call")])
11234 (define_insn "*sibcall_pop"
11235 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11236 (match_operand 1 "" ""))
11237 (set (reg:SI SP_REG)
11238 (plus:SI (reg:SI SP_REG)
11239 (match_operand:SI 2 "immediate_operand" "i")))]
11240 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11241 "* return ix86_output_call_insn (insn, operands[0]);"
11242 [(set_attr "type" "call")])
11244 ;; Call subroutine, returning value in operand 0
11246 (define_expand "call_value"
11247 [(set (match_operand 0 "" "")
11248 (call (match_operand:QI 1 "" "")
11249 (match_operand 2 "" "")))
11250 (use (match_operand 3 "" ""))]
11253 ix86_expand_call (operands[0], operands[1], operands[2],
11254 operands[3], NULL, 0);
11258 (define_expand "sibcall_value"
11259 [(set (match_operand 0 "" "")
11260 (call (match_operand:QI 1 "" "")
11261 (match_operand 2 "" "")))
11262 (use (match_operand 3 "" ""))]
11265 ix86_expand_call (operands[0], operands[1], operands[2],
11266 operands[3], NULL, 1);
11270 (define_insn_and_split "*call_value_vzeroupper"
11271 [(set (match_operand 0 "" "")
11272 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11273 (match_operand 2 "" "")))
11274 (unspec [(match_operand 3 "const_int_operand" "")]
11275 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11276 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11278 "&& reload_completed"
11280 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11281 [(set_attr "type" "callv")])
11283 (define_insn "*call_value"
11284 [(set (match_operand 0 "" "")
11285 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11286 (match_operand 2 "" "")))]
11287 "!SIBLING_CALL_P (insn)"
11288 "* return ix86_output_call_insn (insn, operands[1]);"
11289 [(set_attr "type" "callv")])
11291 (define_insn_and_split "*sibcall_value_vzeroupper"
11292 [(set (match_operand 0 "" "")
11293 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11294 (match_operand 2 "" "")))
11295 (unspec [(match_operand 3 "const_int_operand" "")]
11296 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11297 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11299 "&& reload_completed"
11301 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11302 [(set_attr "type" "callv")])
11304 (define_insn "*sibcall_value"
11305 [(set (match_operand 0 "" "")
11306 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11307 (match_operand 2 "" "")))]
11308 "SIBLING_CALL_P (insn)"
11309 "* return ix86_output_call_insn (insn, operands[1]);"
11310 [(set_attr "type" "callv")])
11312 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11314 [(set (match_operand 0 "" "")
11315 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11316 (match_operand 2 "" "")))
11317 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11318 (clobber (reg:TI XMM6_REG))
11319 (clobber (reg:TI XMM7_REG))
11320 (clobber (reg:TI XMM8_REG))
11321 (clobber (reg:TI XMM9_REG))
11322 (clobber (reg:TI XMM10_REG))
11323 (clobber (reg:TI XMM11_REG))
11324 (clobber (reg:TI XMM12_REG))
11325 (clobber (reg:TI XMM13_REG))
11326 (clobber (reg:TI XMM14_REG))
11327 (clobber (reg:TI XMM15_REG))
11328 (clobber (reg:DI SI_REG))
11329 (clobber (reg:DI DI_REG))])
11330 (unspec [(match_operand 3 "const_int_operand" "")]
11331 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11332 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11334 "&& reload_completed"
11336 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11337 [(set_attr "type" "callv")])
11339 (define_insn "*call_value_rex64_ms_sysv"
11340 [(set (match_operand 0 "" "")
11341 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11342 (match_operand 2 "" "")))
11343 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11344 (clobber (reg:TI XMM6_REG))
11345 (clobber (reg:TI XMM7_REG))
11346 (clobber (reg:TI XMM8_REG))
11347 (clobber (reg:TI XMM9_REG))
11348 (clobber (reg:TI XMM10_REG))
11349 (clobber (reg:TI XMM11_REG))
11350 (clobber (reg:TI XMM12_REG))
11351 (clobber (reg:TI XMM13_REG))
11352 (clobber (reg:TI XMM14_REG))
11353 (clobber (reg:TI XMM15_REG))
11354 (clobber (reg:DI SI_REG))
11355 (clobber (reg:DI DI_REG))]
11356 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11357 "* return ix86_output_call_insn (insn, operands[1]);"
11358 [(set_attr "type" "callv")])
11360 (define_expand "call_value_pop"
11361 [(parallel [(set (match_operand 0 "" "")
11362 (call (match_operand:QI 1 "" "")
11363 (match_operand:SI 2 "" "")))
11364 (set (reg:SI SP_REG)
11365 (plus:SI (reg:SI SP_REG)
11366 (match_operand:SI 4 "" "")))])]
11369 ix86_expand_call (operands[0], operands[1], operands[2],
11370 operands[3], operands[4], 0);
11374 (define_insn_and_split "*call_value_pop_vzeroupper"
11376 [(set (match_operand 0 "" "")
11377 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11378 (match_operand 2 "" "")))
11379 (set (reg:SI SP_REG)
11380 (plus:SI (reg:SI SP_REG)
11381 (match_operand:SI 3 "immediate_operand" "i")))])
11382 (unspec [(match_operand 4 "const_int_operand" "")]
11383 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11384 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11386 "&& reload_completed"
11388 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11389 [(set_attr "type" "callv")])
11391 (define_insn "*call_value_pop"
11392 [(set (match_operand 0 "" "")
11393 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11394 (match_operand 2 "" "")))
11395 (set (reg:SI SP_REG)
11396 (plus:SI (reg:SI SP_REG)
11397 (match_operand:SI 3 "immediate_operand" "i")))]
11398 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11399 "* return ix86_output_call_insn (insn, operands[1]);"
11400 [(set_attr "type" "callv")])
11402 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11404 [(set (match_operand 0 "" "")
11405 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11406 (match_operand 2 "" "")))
11407 (set (reg:SI SP_REG)
11408 (plus:SI (reg:SI SP_REG)
11409 (match_operand:SI 3 "immediate_operand" "i")))])
11410 (unspec [(match_operand 4 "const_int_operand" "")]
11411 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11412 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11414 "&& reload_completed"
11416 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11417 [(set_attr "type" "callv")])
11419 (define_insn "*sibcall_value_pop"
11420 [(set (match_operand 0 "" "")
11421 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11422 (match_operand 2 "" "")))
11423 (set (reg:SI SP_REG)
11424 (plus:SI (reg:SI SP_REG)
11425 (match_operand:SI 3 "immediate_operand" "i")))]
11426 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11427 "* return ix86_output_call_insn (insn, operands[1]);"
11428 [(set_attr "type" "callv")])
11430 ;; Call subroutine returning any type.
11432 (define_expand "untyped_call"
11433 [(parallel [(call (match_operand 0 "" "")
11435 (match_operand 1 "" "")
11436 (match_operand 2 "" "")])]
11441 /* In order to give reg-stack an easier job in validating two
11442 coprocessor registers as containing a possible return value,
11443 simply pretend the untyped call returns a complex long double
11446 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11447 and should have the default ABI. */
11449 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11450 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11451 operands[0], const0_rtx,
11452 GEN_INT ((TARGET_64BIT
11453 ? (ix86_abi == SYSV_ABI
11454 ? X86_64_SSE_REGPARM_MAX
11455 : X86_64_MS_SSE_REGPARM_MAX)
11456 : X86_32_SSE_REGPARM_MAX)
11460 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11462 rtx set = XVECEXP (operands[2], 0, i);
11463 emit_move_insn (SET_DEST (set), SET_SRC (set));
11466 /* The optimizer does not know that the call sets the function value
11467 registers we stored in the result block. We avoid problems by
11468 claiming that all hard registers are used and clobbered at this
11470 emit_insn (gen_blockage ());
11475 ;; Prologue and epilogue instructions
11477 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11478 ;; all of memory. This blocks insns from being moved across this point.
11480 (define_insn "blockage"
11481 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11484 [(set_attr "length" "0")])
11486 ;; Do not schedule instructions accessing memory across this point.
11488 (define_expand "memory_blockage"
11489 [(set (match_dup 0)
11490 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11493 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11494 MEM_VOLATILE_P (operands[0]) = 1;
11497 (define_insn "*memory_blockage"
11498 [(set (match_operand:BLK 0 "" "")
11499 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11502 [(set_attr "length" "0")])
11504 ;; As USE insns aren't meaningful after reload, this is used instead
11505 ;; to prevent deleting instructions setting registers for PIC code
11506 (define_insn "prologue_use"
11507 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11510 [(set_attr "length" "0")])
11512 ;; Insn emitted into the body of a function to return from a function.
11513 ;; This is only done if the function's epilogue is known to be simple.
11514 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11516 (define_expand "return"
11518 "ix86_can_use_return_insn_p ()"
11520 if (crtl->args.pops_args)
11522 rtx popc = GEN_INT (crtl->args.pops_args);
11523 emit_jump_insn (gen_return_pop_internal (popc));
11528 (define_insn "return_internal"
11532 [(set_attr "length" "1")
11533 (set_attr "atom_unit" "jeu")
11534 (set_attr "length_immediate" "0")
11535 (set_attr "modrm" "0")])
11537 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11538 ;; instruction Athlon and K8 have.
11540 (define_insn "return_internal_long"
11542 (unspec [(const_int 0)] UNSPEC_REP)]
11545 [(set_attr "length" "2")
11546 (set_attr "atom_unit" "jeu")
11547 (set_attr "length_immediate" "0")
11548 (set_attr "prefix_rep" "1")
11549 (set_attr "modrm" "0")])
11551 (define_insn "return_pop_internal"
11553 (use (match_operand:SI 0 "const_int_operand" ""))]
11556 [(set_attr "length" "3")
11557 (set_attr "atom_unit" "jeu")
11558 (set_attr "length_immediate" "2")
11559 (set_attr "modrm" "0")])
11561 (define_insn "return_indirect_internal"
11563 (use (match_operand:SI 0 "register_operand" "r"))]
11566 [(set_attr "type" "ibr")
11567 (set_attr "length_immediate" "0")])
11573 [(set_attr "length" "1")
11574 (set_attr "length_immediate" "0")
11575 (set_attr "modrm" "0")])
11577 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11578 (define_insn "nops"
11579 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11583 int num = INTVAL (operands[0]);
11585 gcc_assert (num >= 1 && num <= 8);
11588 fputs ("\tnop\n", asm_out_file);
11592 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11593 (set_attr "length_immediate" "0")
11594 (set_attr "modrm" "0")])
11596 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11597 ;; branch prediction penalty for the third jump in a 16-byte
11601 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11604 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11605 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11607 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11608 The align insn is used to avoid 3 jump instructions in the row to improve
11609 branch prediction and the benefits hardly outweigh the cost of extra 8
11610 nops on the average inserted by full alignment pseudo operation. */
11614 [(set_attr "length" "16")])
11616 (define_expand "prologue"
11619 "ix86_expand_prologue (); DONE;")
11621 (define_insn "set_got"
11622 [(set (match_operand:SI 0 "register_operand" "=r")
11623 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11624 (clobber (reg:CC FLAGS_REG))]
11626 "* return output_set_got (operands[0], NULL_RTX);"
11627 [(set_attr "type" "multi")
11628 (set_attr "length" "12")])
11630 (define_insn "set_got_labelled"
11631 [(set (match_operand:SI 0 "register_operand" "=r")
11632 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11634 (clobber (reg:CC FLAGS_REG))]
11636 "* return output_set_got (operands[0], operands[1]);"
11637 [(set_attr "type" "multi")
11638 (set_attr "length" "12")])
11640 (define_insn "set_got_rex64"
11641 [(set (match_operand:DI 0 "register_operand" "=r")
11642 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11644 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11645 [(set_attr "type" "lea")
11646 (set_attr "length_address" "4")
11647 (set_attr "mode" "DI")])
11649 (define_insn "set_rip_rex64"
11650 [(set (match_operand:DI 0 "register_operand" "=r")
11651 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11653 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11654 [(set_attr "type" "lea")
11655 (set_attr "length_address" "4")
11656 (set_attr "mode" "DI")])
11658 (define_insn "set_got_offset_rex64"
11659 [(set (match_operand:DI 0 "register_operand" "=r")
11661 [(label_ref (match_operand 1 "" ""))]
11662 UNSPEC_SET_GOT_OFFSET))]
11664 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11665 [(set_attr "type" "imov")
11666 (set_attr "length_immediate" "0")
11667 (set_attr "length_address" "8")
11668 (set_attr "mode" "DI")])
11670 (define_expand "epilogue"
11673 "ix86_expand_epilogue (1); DONE;")
11675 (define_expand "sibcall_epilogue"
11678 "ix86_expand_epilogue (0); DONE;")
11680 (define_expand "eh_return"
11681 [(use (match_operand 0 "register_operand" ""))]
11684 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11686 /* Tricky bit: we write the address of the handler to which we will
11687 be returning into someone else's stack frame, one word below the
11688 stack address we wish to restore. */
11689 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11690 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11691 tmp = gen_rtx_MEM (Pmode, tmp);
11692 emit_move_insn (tmp, ra);
11694 emit_jump_insn (gen_eh_return_internal ());
11699 (define_insn_and_split "eh_return_internal"
11703 "epilogue_completed"
11705 "ix86_expand_epilogue (2); DONE;")
11707 (define_insn "leave"
11708 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11709 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11710 (clobber (mem:BLK (scratch)))]
11713 [(set_attr "type" "leave")])
11715 (define_insn "leave_rex64"
11716 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11717 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11718 (clobber (mem:BLK (scratch)))]
11721 [(set_attr "type" "leave")])
11723 ;; Handle -fsplit-stack.
11725 (define_expand "split_stack_prologue"
11729 ix86_expand_split_stack_prologue ();
11733 ;; In order to support the call/return predictor, we use a return
11734 ;; instruction which the middle-end doesn't see.
11735 (define_insn "split_stack_return"
11736 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11737 UNSPECV_SPLIT_STACK_RETURN)]
11740 if (operands[0] == const0_rtx)
11745 [(set_attr "atom_unit" "jeu")
11746 (set_attr "modrm" "0")
11747 (set (attr "length")
11748 (if_then_else (match_operand:SI 0 "const0_operand" "")
11751 (set (attr "length_immediate")
11752 (if_then_else (match_operand:SI 0 "const0_operand" "")
11756 ;; If there are operand 0 bytes available on the stack, jump to
11759 (define_expand "split_stack_space_check"
11760 [(set (pc) (if_then_else
11761 (ltu (minus (reg SP_REG)
11762 (match_operand 0 "register_operand" ""))
11763 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11764 (label_ref (match_operand 1 "" ""))
11768 rtx reg, size, limit;
11770 reg = gen_reg_rtx (Pmode);
11771 size = force_reg (Pmode, operands[0]);
11772 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11773 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11774 UNSPEC_STACK_CHECK);
11775 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11776 ix86_expand_branch (GEU, reg, limit, operands[1]);
11781 ;; Bit manipulation instructions.
11783 (define_expand "ffs<mode>2"
11784 [(set (match_dup 2) (const_int -1))
11785 (parallel [(set (reg:CCZ FLAGS_REG)
11787 (match_operand:SWI48 1 "nonimmediate_operand" "")
11789 (set (match_operand:SWI48 0 "register_operand" "")
11790 (ctz:SWI48 (match_dup 1)))])
11791 (set (match_dup 0) (if_then_else:SWI48
11792 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11795 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11796 (clobber (reg:CC FLAGS_REG))])]
11799 if (<MODE>mode == SImode && !TARGET_CMOVE)
11801 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11804 operands[2] = gen_reg_rtx (<MODE>mode);
11807 (define_insn_and_split "ffssi2_no_cmove"
11808 [(set (match_operand:SI 0 "register_operand" "=r")
11809 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11810 (clobber (match_scratch:SI 2 "=&q"))
11811 (clobber (reg:CC FLAGS_REG))]
11814 "&& reload_completed"
11815 [(parallel [(set (reg:CCZ FLAGS_REG)
11816 (compare:CCZ (match_dup 1) (const_int 0)))
11817 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11818 (set (strict_low_part (match_dup 3))
11819 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11820 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11821 (clobber (reg:CC FLAGS_REG))])
11822 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11823 (clobber (reg:CC FLAGS_REG))])
11824 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11825 (clobber (reg:CC FLAGS_REG))])]
11827 operands[3] = gen_lowpart (QImode, operands[2]);
11828 ix86_expand_clear (operands[2]);
11831 (define_insn "*ffs<mode>_1"
11832 [(set (reg:CCZ FLAGS_REG)
11833 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11835 (set (match_operand:SWI48 0 "register_operand" "=r")
11836 (ctz:SWI48 (match_dup 1)))]
11838 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11839 [(set_attr "type" "alu1")
11840 (set_attr "prefix_0f" "1")
11841 (set_attr "mode" "<MODE>")])
11843 (define_insn "ctz<mode>2"
11844 [(set (match_operand:SWI248 0 "register_operand" "=r")
11845 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11846 (clobber (reg:CC FLAGS_REG))]
11850 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11852 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11854 [(set_attr "type" "alu1")
11855 (set_attr "prefix_0f" "1")
11856 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11857 (set_attr "mode" "<MODE>")])
11859 (define_expand "clz<mode>2"
11861 [(set (match_operand:SWI248 0 "register_operand" "")
11864 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11865 (clobber (reg:CC FLAGS_REG))])
11867 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11868 (clobber (reg:CC FLAGS_REG))])]
11873 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11876 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11879 (define_insn "clz<mode>2_abm"
11880 [(set (match_operand:SWI248 0 "register_operand" "=r")
11881 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11882 (clobber (reg:CC FLAGS_REG))]
11883 "TARGET_ABM || TARGET_BMI"
11884 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11885 [(set_attr "prefix_rep" "1")
11886 (set_attr "type" "bitmanip")
11887 (set_attr "mode" "<MODE>")])
11889 ;; BMI instructions.
11890 (define_insn "*bmi_andn_<mode>"
11891 [(set (match_operand:SWI48 0 "register_operand" "=r")
11894 (match_operand:SWI48 1 "register_operand" "r"))
11895 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11896 (clobber (reg:CC FLAGS_REG))]
11898 "andn\t{%2, %1, %0|%0, %1, %2}"
11899 [(set_attr "type" "bitmanip")
11900 (set_attr "mode" "<MODE>")])
11902 (define_insn "bmi_bextr_<mode>"
11903 [(set (match_operand:SWI48 0 "register_operand" "=r")
11904 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11905 (match_operand:SWI48 2 "register_operand" "r")]
11907 (clobber (reg:CC FLAGS_REG))]
11909 "bextr\t{%2, %1, %0|%0, %1, %2}"
11910 [(set_attr "type" "bitmanip")
11911 (set_attr "mode" "<MODE>")])
11913 (define_insn "*bmi_blsi_<mode>"
11914 [(set (match_operand:SWI48 0 "register_operand" "=r")
11917 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11919 (clobber (reg:CC FLAGS_REG))]
11921 "blsi\t{%1, %0|%0, %1}"
11922 [(set_attr "type" "bitmanip")
11923 (set_attr "mode" "<MODE>")])
11925 (define_insn "*bmi_blsmsk_<mode>"
11926 [(set (match_operand:SWI48 0 "register_operand" "=r")
11929 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11932 (clobber (reg:CC FLAGS_REG))]
11934 "blsmsk\t{%1, %0|%0, %1}"
11935 [(set_attr "type" "bitmanip")
11936 (set_attr "mode" "<MODE>")])
11938 (define_insn "*bmi_blsr_<mode>"
11939 [(set (match_operand:SWI48 0 "register_operand" "=r")
11942 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11945 (clobber (reg:CC FLAGS_REG))]
11947 "blsr\t{%1, %0|%0, %1}"
11948 [(set_attr "type" "bitmanip")
11949 (set_attr "mode" "<MODE>")])
11951 ;; TBM instructions.
11952 (define_insn "tbm_bextri_<mode>"
11953 [(set (match_operand:SWI48 0 "register_operand" "=r")
11954 (zero_extract:SWI48
11955 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11956 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11957 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11958 (clobber (reg:CC FLAGS_REG))]
11961 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11962 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11964 [(set_attr "type" "bitmanip")
11965 (set_attr "mode" "<MODE>")])
11967 (define_insn "*tbm_blcfill_<mode>"
11968 [(set (match_operand:SWI48 0 "register_operand" "=r")
11971 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11974 (clobber (reg:CC FLAGS_REG))]
11976 "blcfill\t{%1, %0|%0, %1}"
11977 [(set_attr "type" "bitmanip")
11978 (set_attr "mode" "<MODE>")])
11980 (define_insn "*tbm_blci_<mode>"
11981 [(set (match_operand:SWI48 0 "register_operand" "=r")
11985 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11988 (clobber (reg:CC FLAGS_REG))]
11990 "blci\t{%1, %0|%0, %1}"
11991 [(set_attr "type" "bitmanip")
11992 (set_attr "mode" "<MODE>")])
11994 (define_insn "*tbm_blcic_<mode>"
11995 [(set (match_operand:SWI48 0 "register_operand" "=r")
11998 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12002 (clobber (reg:CC FLAGS_REG))]
12004 "blcic\t{%1, %0|%0, %1}"
12005 [(set_attr "type" "bitmanip")
12006 (set_attr "mode" "<MODE>")])
12008 (define_insn "*tbm_blcmsk_<mode>"
12009 [(set (match_operand:SWI48 0 "register_operand" "=r")
12012 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12015 (clobber (reg:CC FLAGS_REG))]
12017 "blcmsk\t{%1, %0|%0, %1}"
12018 [(set_attr "type" "bitmanip")
12019 (set_attr "mode" "<MODE>")])
12021 (define_insn "*tbm_blcs_<mode>"
12022 [(set (match_operand:SWI48 0 "register_operand" "=r")
12025 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12028 (clobber (reg:CC FLAGS_REG))]
12030 "blcs\t{%1, %0|%0, %1}"
12031 [(set_attr "type" "bitmanip")
12032 (set_attr "mode" "<MODE>")])
12034 (define_insn "*tbm_blsfill_<mode>"
12035 [(set (match_operand:SWI48 0 "register_operand" "=r")
12038 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12041 (clobber (reg:CC FLAGS_REG))]
12043 "blsfill\t{%1, %0|%0, %1}"
12044 [(set_attr "type" "bitmanip")
12045 (set_attr "mode" "<MODE>")])
12047 (define_insn "*tbm_blsic_<mode>"
12048 [(set (match_operand:SWI48 0 "register_operand" "=r")
12051 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12055 (clobber (reg:CC FLAGS_REG))]
12057 "blsic\t{%1, %0|%0, %1}"
12058 [(set_attr "type" "bitmanip")
12059 (set_attr "mode" "<MODE>")])
12061 (define_insn "*tbm_t1mskc_<mode>"
12062 [(set (match_operand:SWI48 0 "register_operand" "=r")
12065 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12069 (clobber (reg:CC FLAGS_REG))]
12071 "t1mskc\t{%1, %0|%0, %1}"
12072 [(set_attr "type" "bitmanip")
12073 (set_attr "mode" "<MODE>")])
12075 (define_insn "*tbm_tzmsk_<mode>"
12076 [(set (match_operand:SWI48 0 "register_operand" "=r")
12079 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12083 (clobber (reg:CC FLAGS_REG))]
12085 "tzmsk\t{%1, %0|%0, %1}"
12086 [(set_attr "type" "bitmanip")
12087 (set_attr "mode" "<MODE>")])
12089 (define_insn "bsr_rex64"
12090 [(set (match_operand:DI 0 "register_operand" "=r")
12091 (minus:DI (const_int 63)
12092 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12093 (clobber (reg:CC FLAGS_REG))]
12095 "bsr{q}\t{%1, %0|%0, %1}"
12096 [(set_attr "type" "alu1")
12097 (set_attr "prefix_0f" "1")
12098 (set_attr "mode" "DI")])
12101 [(set (match_operand:SI 0 "register_operand" "=r")
12102 (minus:SI (const_int 31)
12103 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12104 (clobber (reg:CC FLAGS_REG))]
12106 "bsr{l}\t{%1, %0|%0, %1}"
12107 [(set_attr "type" "alu1")
12108 (set_attr "prefix_0f" "1")
12109 (set_attr "mode" "SI")])
12111 (define_insn "*bsrhi"
12112 [(set (match_operand:HI 0 "register_operand" "=r")
12113 (minus:HI (const_int 15)
12114 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12115 (clobber (reg:CC FLAGS_REG))]
12117 "bsr{w}\t{%1, %0|%0, %1}"
12118 [(set_attr "type" "alu1")
12119 (set_attr "prefix_0f" "1")
12120 (set_attr "mode" "HI")])
12122 (define_insn "popcount<mode>2"
12123 [(set (match_operand:SWI248 0 "register_operand" "=r")
12125 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12126 (clobber (reg:CC FLAGS_REG))]
12130 return "popcnt\t{%1, %0|%0, %1}";
12132 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12135 [(set_attr "prefix_rep" "1")
12136 (set_attr "type" "bitmanip")
12137 (set_attr "mode" "<MODE>")])
12139 (define_insn "*popcount<mode>2_cmp"
12140 [(set (reg FLAGS_REG)
12143 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12145 (set (match_operand:SWI248 0 "register_operand" "=r")
12146 (popcount:SWI248 (match_dup 1)))]
12147 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12150 return "popcnt\t{%1, %0|%0, %1}";
12152 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12155 [(set_attr "prefix_rep" "1")
12156 (set_attr "type" "bitmanip")
12157 (set_attr "mode" "<MODE>")])
12159 (define_insn "*popcountsi2_cmp_zext"
12160 [(set (reg FLAGS_REG)
12162 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12164 (set (match_operand:DI 0 "register_operand" "=r")
12165 (zero_extend:DI(popcount:SI (match_dup 1))))]
12166 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12169 return "popcnt\t{%1, %0|%0, %1}";
12171 return "popcnt{l}\t{%1, %0|%0, %1}";
12174 [(set_attr "prefix_rep" "1")
12175 (set_attr "type" "bitmanip")
12176 (set_attr "mode" "SI")])
12178 (define_expand "bswap<mode>2"
12179 [(set (match_operand:SWI48 0 "register_operand" "")
12180 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12183 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12185 rtx x = operands[0];
12187 emit_move_insn (x, operands[1]);
12188 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12189 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12190 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12195 (define_insn "*bswap<mode>2_movbe"
12196 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12197 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12199 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12202 movbe\t{%1, %0|%0, %1}
12203 movbe\t{%1, %0|%0, %1}"
12204 [(set_attr "type" "bitmanip,imov,imov")
12205 (set_attr "modrm" "0,1,1")
12206 (set_attr "prefix_0f" "*,1,1")
12207 (set_attr "prefix_extra" "*,1,1")
12208 (set_attr "mode" "<MODE>")])
12210 (define_insn "*bswap<mode>2_1"
12211 [(set (match_operand:SWI48 0 "register_operand" "=r")
12212 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12215 [(set_attr "type" "bitmanip")
12216 (set_attr "modrm" "0")
12217 (set_attr "mode" "<MODE>")])
12219 (define_insn "*bswaphi_lowpart_1"
12220 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12221 (bswap:HI (match_dup 0)))
12222 (clobber (reg:CC FLAGS_REG))]
12223 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12225 xchg{b}\t{%h0, %b0|%b0, %h0}
12226 rol{w}\t{$8, %0|%0, 8}"
12227 [(set_attr "length" "2,4")
12228 (set_attr "mode" "QI,HI")])
12230 (define_insn "bswaphi_lowpart"
12231 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12232 (bswap:HI (match_dup 0)))
12233 (clobber (reg:CC FLAGS_REG))]
12235 "rol{w}\t{$8, %0|%0, 8}"
12236 [(set_attr "length" "4")
12237 (set_attr "mode" "HI")])
12239 (define_expand "paritydi2"
12240 [(set (match_operand:DI 0 "register_operand" "")
12241 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12244 rtx scratch = gen_reg_rtx (QImode);
12247 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12248 NULL_RTX, operands[1]));
12250 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12251 gen_rtx_REG (CCmode, FLAGS_REG),
12253 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12256 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12259 rtx tmp = gen_reg_rtx (SImode);
12261 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12262 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12267 (define_expand "paritysi2"
12268 [(set (match_operand:SI 0 "register_operand" "")
12269 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12272 rtx scratch = gen_reg_rtx (QImode);
12275 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12277 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12278 gen_rtx_REG (CCmode, FLAGS_REG),
12280 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12282 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12286 (define_insn_and_split "paritydi2_cmp"
12287 [(set (reg:CC FLAGS_REG)
12288 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12290 (clobber (match_scratch:DI 0 "=r"))
12291 (clobber (match_scratch:SI 1 "=&r"))
12292 (clobber (match_scratch:HI 2 "=Q"))]
12295 "&& reload_completed"
12297 [(set (match_dup 1)
12298 (xor:SI (match_dup 1) (match_dup 4)))
12299 (clobber (reg:CC FLAGS_REG))])
12301 [(set (reg:CC FLAGS_REG)
12302 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12303 (clobber (match_dup 1))
12304 (clobber (match_dup 2))])]
12306 operands[4] = gen_lowpart (SImode, operands[3]);
12310 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12311 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12314 operands[1] = gen_highpart (SImode, operands[3]);
12317 (define_insn_and_split "paritysi2_cmp"
12318 [(set (reg:CC FLAGS_REG)
12319 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12321 (clobber (match_scratch:SI 0 "=r"))
12322 (clobber (match_scratch:HI 1 "=&Q"))]
12325 "&& reload_completed"
12327 [(set (match_dup 1)
12328 (xor:HI (match_dup 1) (match_dup 3)))
12329 (clobber (reg:CC FLAGS_REG))])
12331 [(set (reg:CC FLAGS_REG)
12332 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12333 (clobber (match_dup 1))])]
12335 operands[3] = gen_lowpart (HImode, operands[2]);
12337 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12338 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12341 (define_insn "*parityhi2_cmp"
12342 [(set (reg:CC FLAGS_REG)
12343 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12345 (clobber (match_scratch:HI 0 "=Q"))]
12347 "xor{b}\t{%h0, %b0|%b0, %h0}"
12348 [(set_attr "length" "2")
12349 (set_attr "mode" "HI")])
12351 ;; Thread-local storage patterns for ELF.
12353 ;; Note that these code sequences must appear exactly as shown
12354 ;; in order to allow linker relaxation.
12356 (define_insn "*tls_global_dynamic_32_gnu"
12357 [(set (match_operand:SI 0 "register_operand" "=a")
12358 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12359 (match_operand:SI 2 "tls_symbolic_operand" "")
12360 (match_operand:SI 3 "constant_call_address_operand" "z")]
12362 (clobber (match_scratch:SI 4 "=d"))
12363 (clobber (match_scratch:SI 5 "=c"))
12364 (clobber (reg:CC FLAGS_REG))]
12365 "!TARGET_64BIT && TARGET_GNU_TLS"
12366 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12367 [(set_attr "type" "multi")
12368 (set_attr "length" "12")])
12370 (define_expand "tls_global_dynamic_32"
12371 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12373 [(match_operand:SI 2 "register_operand" "")
12374 (match_operand:SI 1 "tls_symbolic_operand" "")
12375 (match_operand:SI 3 "constant_call_address_operand" "")]
12377 (clobber (match_scratch:SI 4 ""))
12378 (clobber (match_scratch:SI 5 ""))
12379 (clobber (reg:CC FLAGS_REG))])])
12381 (define_insn "*tls_global_dynamic_64"
12382 [(set (match_operand:DI 0 "register_operand" "=a")
12384 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12385 (match_operand:DI 3 "" "")))
12386 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12389 { 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"; }
12390 [(set_attr "type" "multi")
12391 (set_attr "length" "16")])
12393 (define_expand "tls_global_dynamic_64"
12394 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12396 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12398 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12401 (define_insn "*tls_local_dynamic_base_32_gnu"
12402 [(set (match_operand:SI 0 "register_operand" "=a")
12403 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12404 (match_operand:SI 2 "constant_call_address_operand" "z")]
12405 UNSPEC_TLS_LD_BASE))
12406 (clobber (match_scratch:SI 3 "=d"))
12407 (clobber (match_scratch:SI 4 "=c"))
12408 (clobber (reg:CC FLAGS_REG))]
12409 "!TARGET_64BIT && TARGET_GNU_TLS"
12410 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12411 [(set_attr "type" "multi")
12412 (set_attr "length" "11")])
12414 (define_expand "tls_local_dynamic_base_32"
12415 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12416 (unspec:SI [(match_operand:SI 1 "register_operand" "")
12417 (match_operand:SI 2 "constant_call_address_operand" "")]
12418 UNSPEC_TLS_LD_BASE))
12419 (clobber (match_scratch:SI 3 ""))
12420 (clobber (match_scratch:SI 4 ""))
12421 (clobber (reg:CC FLAGS_REG))])])
12423 (define_insn "*tls_local_dynamic_base_64"
12424 [(set (match_operand:DI 0 "register_operand" "=a")
12425 (call:DI (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12426 (match_operand:DI 2 "" "")))
12427 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12429 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12430 [(set_attr "type" "multi")
12431 (set_attr "length" "12")])
12433 (define_expand "tls_local_dynamic_base_64"
12434 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12436 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12438 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12440 ;; Local dynamic of a single variable is a lose. Show combine how
12441 ;; to convert that back to global dynamic.
12443 (define_insn_and_split "*tls_local_dynamic_32_once"
12444 [(set (match_operand:SI 0 "register_operand" "=a")
12445 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12446 (match_operand:SI 2 "constant_call_address_operand" "z")]
12447 UNSPEC_TLS_LD_BASE)
12448 (const:SI (unspec:SI
12449 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12451 (clobber (match_scratch:SI 4 "=d"))
12452 (clobber (match_scratch:SI 5 "=c"))
12453 (clobber (reg:CC FLAGS_REG))]
12457 [(parallel [(set (match_dup 0)
12458 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12460 (clobber (match_dup 4))
12461 (clobber (match_dup 5))
12462 (clobber (reg:CC FLAGS_REG))])])
12464 ;; Segment register for the thread base ptr load
12465 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12467 ;; Load and add the thread base pointer from %gs:0.
12468 (define_insn "*load_tp_<mode>"
12469 [(set (match_operand:P 0 "register_operand" "=r")
12470 (unspec:P [(const_int 0)] UNSPEC_TP))]
12472 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12473 [(set_attr "type" "imov")
12474 (set_attr "modrm" "0")
12475 (set_attr "length" "7")
12476 (set_attr "memory" "load")
12477 (set_attr "imm_disp" "false")])
12479 (define_insn "*add_tp_<mode>"
12480 [(set (match_operand:P 0 "register_operand" "=r")
12481 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12482 (match_operand:P 1 "register_operand" "0")))
12483 (clobber (reg:CC FLAGS_REG))]
12485 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12486 [(set_attr "type" "alu")
12487 (set_attr "modrm" "0")
12488 (set_attr "length" "7")
12489 (set_attr "memory" "load")
12490 (set_attr "imm_disp" "false")])
12492 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12493 ;; %rax as destination of the initial executable code sequence.
12494 (define_insn "tls_initial_exec_64_sun"
12495 [(set (match_operand:DI 0 "register_operand" "=a")
12497 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12498 UNSPEC_TLS_IE_SUN))
12499 (clobber (reg:CC FLAGS_REG))]
12500 "TARGET_64BIT && TARGET_SUN_TLS"
12501 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12502 [(set_attr "type" "multi")])
12504 ;; GNU2 TLS patterns can be split.
12506 (define_expand "tls_dynamic_gnu2_32"
12507 [(set (match_dup 3)
12508 (plus:SI (match_operand:SI 2 "register_operand" "")
12510 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12513 [(set (match_operand:SI 0 "register_operand" "")
12514 (unspec:SI [(match_dup 1) (match_dup 3)
12515 (match_dup 2) (reg:SI SP_REG)]
12517 (clobber (reg:CC FLAGS_REG))])]
12518 "!TARGET_64BIT && TARGET_GNU2_TLS"
12520 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12521 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12524 (define_insn "*tls_dynamic_lea_32"
12525 [(set (match_operand:SI 0 "register_operand" "=r")
12526 (plus:SI (match_operand:SI 1 "register_operand" "b")
12528 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12529 UNSPEC_TLSDESC))))]
12530 "!TARGET_64BIT && TARGET_GNU2_TLS"
12531 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12532 [(set_attr "type" "lea")
12533 (set_attr "mode" "SI")
12534 (set_attr "length" "6")
12535 (set_attr "length_address" "4")])
12537 (define_insn "*tls_dynamic_call_32"
12538 [(set (match_operand:SI 0 "register_operand" "=a")
12539 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12540 (match_operand:SI 2 "register_operand" "0")
12541 ;; we have to make sure %ebx still points to the GOT
12542 (match_operand:SI 3 "register_operand" "b")
12545 (clobber (reg:CC FLAGS_REG))]
12546 "!TARGET_64BIT && TARGET_GNU2_TLS"
12547 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12548 [(set_attr "type" "call")
12549 (set_attr "length" "2")
12550 (set_attr "length_address" "0")])
12552 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12553 [(set (match_operand:SI 0 "register_operand" "=&a")
12555 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12556 (match_operand:SI 4 "" "")
12557 (match_operand:SI 2 "register_operand" "b")
12560 (const:SI (unspec:SI
12561 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12563 (clobber (reg:CC FLAGS_REG))]
12564 "!TARGET_64BIT && TARGET_GNU2_TLS"
12567 [(set (match_dup 0) (match_dup 5))]
12569 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12570 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12573 (define_expand "tls_dynamic_gnu2_64"
12574 [(set (match_dup 2)
12575 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12578 [(set (match_operand:DI 0 "register_operand" "")
12579 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12581 (clobber (reg:CC FLAGS_REG))])]
12582 "TARGET_64BIT && TARGET_GNU2_TLS"
12584 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12585 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12588 (define_insn "*tls_dynamic_lea_64"
12589 [(set (match_operand:DI 0 "register_operand" "=r")
12590 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12592 "TARGET_64BIT && TARGET_GNU2_TLS"
12593 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12594 [(set_attr "type" "lea")
12595 (set_attr "mode" "DI")
12596 (set_attr "length" "7")
12597 (set_attr "length_address" "4")])
12599 (define_insn "*tls_dynamic_call_64"
12600 [(set (match_operand:DI 0 "register_operand" "=a")
12601 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12602 (match_operand:DI 2 "register_operand" "0")
12605 (clobber (reg:CC FLAGS_REG))]
12606 "TARGET_64BIT && TARGET_GNU2_TLS"
12607 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12608 [(set_attr "type" "call")
12609 (set_attr "length" "2")
12610 (set_attr "length_address" "0")])
12612 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12613 [(set (match_operand:DI 0 "register_operand" "=&a")
12615 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12616 (match_operand:DI 3 "" "")
12619 (const:DI (unspec:DI
12620 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12622 (clobber (reg:CC FLAGS_REG))]
12623 "TARGET_64BIT && TARGET_GNU2_TLS"
12626 [(set (match_dup 0) (match_dup 4))]
12628 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12629 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12632 ;; These patterns match the binary 387 instructions for addM3, subM3,
12633 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12634 ;; SFmode. The first is the normal insn, the second the same insn but
12635 ;; with one operand a conversion, and the third the same insn but with
12636 ;; the other operand a conversion. The conversion may be SFmode or
12637 ;; SImode if the target mode DFmode, but only SImode if the target mode
12640 ;; Gcc is slightly more smart about handling normal two address instructions
12641 ;; so use special patterns for add and mull.
12643 (define_insn "*fop_<mode>_comm_mixed"
12644 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12645 (match_operator:MODEF 3 "binary_fp_operator"
12646 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12647 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12648 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12649 && COMMUTATIVE_ARITH_P (operands[3])
12650 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12651 "* return output_387_binary_op (insn, operands);"
12652 [(set (attr "type")
12653 (if_then_else (eq_attr "alternative" "1,2")
12654 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12655 (const_string "ssemul")
12656 (const_string "sseadd"))
12657 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12658 (const_string "fmul")
12659 (const_string "fop"))))
12660 (set_attr "isa" "base,noavx,avx")
12661 (set_attr "prefix" "orig,orig,vex")
12662 (set_attr "mode" "<MODE>")])
12664 (define_insn "*fop_<mode>_comm_sse"
12665 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12666 (match_operator:MODEF 3 "binary_fp_operator"
12667 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12668 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12669 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12670 && COMMUTATIVE_ARITH_P (operands[3])
12671 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12672 "* return output_387_binary_op (insn, operands);"
12673 [(set (attr "type")
12674 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12675 (const_string "ssemul")
12676 (const_string "sseadd")))
12677 (set_attr "isa" "noavx,avx")
12678 (set_attr "prefix" "orig,vex")
12679 (set_attr "mode" "<MODE>")])
12681 (define_insn "*fop_<mode>_comm_i387"
12682 [(set (match_operand:MODEF 0 "register_operand" "=f")
12683 (match_operator:MODEF 3 "binary_fp_operator"
12684 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12685 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12686 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12687 && COMMUTATIVE_ARITH_P (operands[3])
12688 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12689 "* return output_387_binary_op (insn, operands);"
12690 [(set (attr "type")
12691 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12692 (const_string "fmul")
12693 (const_string "fop")))
12694 (set_attr "mode" "<MODE>")])
12696 (define_insn "*fop_<mode>_1_mixed"
12697 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12698 (match_operator:MODEF 3 "binary_fp_operator"
12699 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12700 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12701 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12702 && !COMMUTATIVE_ARITH_P (operands[3])
12703 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12704 "* return output_387_binary_op (insn, operands);"
12705 [(set (attr "type")
12706 (cond [(and (eq_attr "alternative" "2,3")
12707 (match_operand:MODEF 3 "mult_operator" ""))
12708 (const_string "ssemul")
12709 (and (eq_attr "alternative" "2,3")
12710 (match_operand:MODEF 3 "div_operator" ""))
12711 (const_string "ssediv")
12712 (eq_attr "alternative" "2,3")
12713 (const_string "sseadd")
12714 (match_operand:MODEF 3 "mult_operator" "")
12715 (const_string "fmul")
12716 (match_operand:MODEF 3 "div_operator" "")
12717 (const_string "fdiv")
12719 (const_string "fop")))
12720 (set_attr "isa" "base,base,noavx,avx")
12721 (set_attr "prefix" "orig,orig,orig,vex")
12722 (set_attr "mode" "<MODE>")])
12724 (define_insn "*rcpsf2_sse"
12725 [(set (match_operand:SF 0 "register_operand" "=x")
12726 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12729 "%vrcpss\t{%1, %d0|%d0, %1}"
12730 [(set_attr "type" "sse")
12731 (set_attr "atom_sse_attr" "rcp")
12732 (set_attr "prefix" "maybe_vex")
12733 (set_attr "mode" "SF")])
12735 (define_insn "*fop_<mode>_1_sse"
12736 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12737 (match_operator:MODEF 3 "binary_fp_operator"
12738 [(match_operand:MODEF 1 "register_operand" "0,x")
12739 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12740 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12741 && !COMMUTATIVE_ARITH_P (operands[3])"
12742 "* return output_387_binary_op (insn, operands);"
12743 [(set (attr "type")
12744 (cond [(match_operand:MODEF 3 "mult_operator" "")
12745 (const_string "ssemul")
12746 (match_operand:MODEF 3 "div_operator" "")
12747 (const_string "ssediv")
12749 (const_string "sseadd")))
12750 (set_attr "isa" "noavx,avx")
12751 (set_attr "prefix" "orig,vex")
12752 (set_attr "mode" "<MODE>")])
12754 ;; This pattern is not fully shadowed by the pattern above.
12755 (define_insn "*fop_<mode>_1_i387"
12756 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12757 (match_operator:MODEF 3 "binary_fp_operator"
12758 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12759 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12760 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12761 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12762 && !COMMUTATIVE_ARITH_P (operands[3])
12763 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12764 "* return output_387_binary_op (insn, operands);"
12765 [(set (attr "type")
12766 (cond [(match_operand:MODEF 3 "mult_operator" "")
12767 (const_string "fmul")
12768 (match_operand:MODEF 3 "div_operator" "")
12769 (const_string "fdiv")
12771 (const_string "fop")))
12772 (set_attr "mode" "<MODE>")])
12774 ;; ??? Add SSE splitters for these!
12775 (define_insn "*fop_<MODEF:mode>_2_i387"
12776 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12777 (match_operator:MODEF 3 "binary_fp_operator"
12779 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12780 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12781 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12782 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12783 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12784 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12785 [(set (attr "type")
12786 (cond [(match_operand:MODEF 3 "mult_operator" "")
12787 (const_string "fmul")
12788 (match_operand:MODEF 3 "div_operator" "")
12789 (const_string "fdiv")
12791 (const_string "fop")))
12792 (set_attr "fp_int_src" "true")
12793 (set_attr "mode" "<X87MODEI12:MODE>")])
12795 (define_insn "*fop_<MODEF:mode>_3_i387"
12796 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12797 (match_operator:MODEF 3 "binary_fp_operator"
12798 [(match_operand:MODEF 1 "register_operand" "0,0")
12800 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12801 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12802 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12803 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12804 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12805 [(set (attr "type")
12806 (cond [(match_operand:MODEF 3 "mult_operator" "")
12807 (const_string "fmul")
12808 (match_operand:MODEF 3 "div_operator" "")
12809 (const_string "fdiv")
12811 (const_string "fop")))
12812 (set_attr "fp_int_src" "true")
12813 (set_attr "mode" "<MODE>")])
12815 (define_insn "*fop_df_4_i387"
12816 [(set (match_operand:DF 0 "register_operand" "=f,f")
12817 (match_operator:DF 3 "binary_fp_operator"
12819 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12820 (match_operand:DF 2 "register_operand" "0,f")]))]
12821 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12822 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12824 "* return output_387_binary_op (insn, operands);"
12825 [(set (attr "type")
12826 (cond [(match_operand:DF 3 "mult_operator" "")
12827 (const_string "fmul")
12828 (match_operand:DF 3 "div_operator" "")
12829 (const_string "fdiv")
12831 (const_string "fop")))
12832 (set_attr "mode" "SF")])
12834 (define_insn "*fop_df_5_i387"
12835 [(set (match_operand:DF 0 "register_operand" "=f,f")
12836 (match_operator:DF 3 "binary_fp_operator"
12837 [(match_operand:DF 1 "register_operand" "0,f")
12839 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12840 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12841 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12842 "* return output_387_binary_op (insn, operands);"
12843 [(set (attr "type")
12844 (cond [(match_operand:DF 3 "mult_operator" "")
12845 (const_string "fmul")
12846 (match_operand:DF 3 "div_operator" "")
12847 (const_string "fdiv")
12849 (const_string "fop")))
12850 (set_attr "mode" "SF")])
12852 (define_insn "*fop_df_6_i387"
12853 [(set (match_operand:DF 0 "register_operand" "=f,f")
12854 (match_operator:DF 3 "binary_fp_operator"
12856 (match_operand:SF 1 "register_operand" "0,f"))
12858 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12859 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12860 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12861 "* return output_387_binary_op (insn, operands);"
12862 [(set (attr "type")
12863 (cond [(match_operand:DF 3 "mult_operator" "")
12864 (const_string "fmul")
12865 (match_operand:DF 3 "div_operator" "")
12866 (const_string "fdiv")
12868 (const_string "fop")))
12869 (set_attr "mode" "SF")])
12871 (define_insn "*fop_xf_comm_i387"
12872 [(set (match_operand:XF 0 "register_operand" "=f")
12873 (match_operator:XF 3 "binary_fp_operator"
12874 [(match_operand:XF 1 "register_operand" "%0")
12875 (match_operand:XF 2 "register_operand" "f")]))]
12877 && COMMUTATIVE_ARITH_P (operands[3])"
12878 "* return output_387_binary_op (insn, operands);"
12879 [(set (attr "type")
12880 (if_then_else (match_operand:XF 3 "mult_operator" "")
12881 (const_string "fmul")
12882 (const_string "fop")))
12883 (set_attr "mode" "XF")])
12885 (define_insn "*fop_xf_1_i387"
12886 [(set (match_operand:XF 0 "register_operand" "=f,f")
12887 (match_operator:XF 3 "binary_fp_operator"
12888 [(match_operand:XF 1 "register_operand" "0,f")
12889 (match_operand:XF 2 "register_operand" "f,0")]))]
12891 && !COMMUTATIVE_ARITH_P (operands[3])"
12892 "* return output_387_binary_op (insn, operands);"
12893 [(set (attr "type")
12894 (cond [(match_operand:XF 3 "mult_operator" "")
12895 (const_string "fmul")
12896 (match_operand:XF 3 "div_operator" "")
12897 (const_string "fdiv")
12899 (const_string "fop")))
12900 (set_attr "mode" "XF")])
12902 (define_insn "*fop_xf_2_i387"
12903 [(set (match_operand:XF 0 "register_operand" "=f,f")
12904 (match_operator:XF 3 "binary_fp_operator"
12906 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12907 (match_operand:XF 2 "register_operand" "0,0")]))]
12908 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12909 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12910 [(set (attr "type")
12911 (cond [(match_operand:XF 3 "mult_operator" "")
12912 (const_string "fmul")
12913 (match_operand:XF 3 "div_operator" "")
12914 (const_string "fdiv")
12916 (const_string "fop")))
12917 (set_attr "fp_int_src" "true")
12918 (set_attr "mode" "<MODE>")])
12920 (define_insn "*fop_xf_3_i387"
12921 [(set (match_operand:XF 0 "register_operand" "=f,f")
12922 (match_operator:XF 3 "binary_fp_operator"
12923 [(match_operand:XF 1 "register_operand" "0,0")
12925 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12926 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12927 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12928 [(set (attr "type")
12929 (cond [(match_operand:XF 3 "mult_operator" "")
12930 (const_string "fmul")
12931 (match_operand:XF 3 "div_operator" "")
12932 (const_string "fdiv")
12934 (const_string "fop")))
12935 (set_attr "fp_int_src" "true")
12936 (set_attr "mode" "<MODE>")])
12938 (define_insn "*fop_xf_4_i387"
12939 [(set (match_operand:XF 0 "register_operand" "=f,f")
12940 (match_operator:XF 3 "binary_fp_operator"
12942 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12943 (match_operand:XF 2 "register_operand" "0,f")]))]
12945 "* return output_387_binary_op (insn, operands);"
12946 [(set (attr "type")
12947 (cond [(match_operand:XF 3 "mult_operator" "")
12948 (const_string "fmul")
12949 (match_operand:XF 3 "div_operator" "")
12950 (const_string "fdiv")
12952 (const_string "fop")))
12953 (set_attr "mode" "<MODE>")])
12955 (define_insn "*fop_xf_5_i387"
12956 [(set (match_operand:XF 0 "register_operand" "=f,f")
12957 (match_operator:XF 3 "binary_fp_operator"
12958 [(match_operand:XF 1 "register_operand" "0,f")
12960 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12962 "* return output_387_binary_op (insn, operands);"
12963 [(set (attr "type")
12964 (cond [(match_operand:XF 3 "mult_operator" "")
12965 (const_string "fmul")
12966 (match_operand:XF 3 "div_operator" "")
12967 (const_string "fdiv")
12969 (const_string "fop")))
12970 (set_attr "mode" "<MODE>")])
12972 (define_insn "*fop_xf_6_i387"
12973 [(set (match_operand:XF 0 "register_operand" "=f,f")
12974 (match_operator:XF 3 "binary_fp_operator"
12976 (match_operand:MODEF 1 "register_operand" "0,f"))
12978 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12980 "* return output_387_binary_op (insn, operands);"
12981 [(set (attr "type")
12982 (cond [(match_operand:XF 3 "mult_operator" "")
12983 (const_string "fmul")
12984 (match_operand:XF 3 "div_operator" "")
12985 (const_string "fdiv")
12987 (const_string "fop")))
12988 (set_attr "mode" "<MODE>")])
12991 [(set (match_operand 0 "register_operand" "")
12992 (match_operator 3 "binary_fp_operator"
12993 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12994 (match_operand 2 "register_operand" "")]))]
12996 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12997 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13000 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13001 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13002 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13003 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13004 GET_MODE (operands[3]),
13007 ix86_free_from_memory (GET_MODE (operands[1]));
13012 [(set (match_operand 0 "register_operand" "")
13013 (match_operator 3 "binary_fp_operator"
13014 [(match_operand 1 "register_operand" "")
13015 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13017 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13018 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13021 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13022 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13023 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13024 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13025 GET_MODE (operands[3]),
13028 ix86_free_from_memory (GET_MODE (operands[2]));
13032 ;; FPU special functions.
13034 ;; This pattern implements a no-op XFmode truncation for
13035 ;; all fancy i386 XFmode math functions.
13037 (define_insn "truncxf<mode>2_i387_noop_unspec"
13038 [(set (match_operand:MODEF 0 "register_operand" "=f")
13039 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13040 UNSPEC_TRUNC_NOOP))]
13041 "TARGET_USE_FANCY_MATH_387"
13042 "* return output_387_reg_move (insn, operands);"
13043 [(set_attr "type" "fmov")
13044 (set_attr "mode" "<MODE>")])
13046 (define_insn "sqrtxf2"
13047 [(set (match_operand:XF 0 "register_operand" "=f")
13048 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13049 "TARGET_USE_FANCY_MATH_387"
13051 [(set_attr "type" "fpspc")
13052 (set_attr "mode" "XF")
13053 (set_attr "athlon_decode" "direct")
13054 (set_attr "amdfam10_decode" "direct")
13055 (set_attr "bdver1_decode" "direct")])
13057 (define_insn "sqrt_extend<mode>xf2_i387"
13058 [(set (match_operand:XF 0 "register_operand" "=f")
13061 (match_operand:MODEF 1 "register_operand" "0"))))]
13062 "TARGET_USE_FANCY_MATH_387"
13064 [(set_attr "type" "fpspc")
13065 (set_attr "mode" "XF")
13066 (set_attr "athlon_decode" "direct")
13067 (set_attr "amdfam10_decode" "direct")
13068 (set_attr "bdver1_decode" "direct")])
13070 (define_insn "*rsqrtsf2_sse"
13071 [(set (match_operand:SF 0 "register_operand" "=x")
13072 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13075 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13076 [(set_attr "type" "sse")
13077 (set_attr "atom_sse_attr" "rcp")
13078 (set_attr "prefix" "maybe_vex")
13079 (set_attr "mode" "SF")])
13081 (define_expand "rsqrtsf2"
13082 [(set (match_operand:SF 0 "register_operand" "")
13083 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13087 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13091 (define_insn "*sqrt<mode>2_sse"
13092 [(set (match_operand:MODEF 0 "register_operand" "=x")
13094 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13095 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13096 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13097 [(set_attr "type" "sse")
13098 (set_attr "atom_sse_attr" "sqrt")
13099 (set_attr "prefix" "maybe_vex")
13100 (set_attr "mode" "<MODE>")
13101 (set_attr "athlon_decode" "*")
13102 (set_attr "amdfam10_decode" "*")
13103 (set_attr "bdver1_decode" "*")])
13105 (define_expand "sqrt<mode>2"
13106 [(set (match_operand:MODEF 0 "register_operand" "")
13108 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13109 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13110 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13112 if (<MODE>mode == SFmode
13113 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13114 && flag_finite_math_only && !flag_trapping_math
13115 && flag_unsafe_math_optimizations)
13117 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13121 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13123 rtx op0 = gen_reg_rtx (XFmode);
13124 rtx op1 = force_reg (<MODE>mode, operands[1]);
13126 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13127 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13132 (define_insn "fpremxf4_i387"
13133 [(set (match_operand:XF 0 "register_operand" "=f")
13134 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13135 (match_operand:XF 3 "register_operand" "1")]
13137 (set (match_operand:XF 1 "register_operand" "=u")
13138 (unspec:XF [(match_dup 2) (match_dup 3)]
13140 (set (reg:CCFP FPSR_REG)
13141 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13143 "TARGET_USE_FANCY_MATH_387"
13145 [(set_attr "type" "fpspc")
13146 (set_attr "mode" "XF")])
13148 (define_expand "fmodxf3"
13149 [(use (match_operand:XF 0 "register_operand" ""))
13150 (use (match_operand:XF 1 "general_operand" ""))
13151 (use (match_operand:XF 2 "general_operand" ""))]
13152 "TARGET_USE_FANCY_MATH_387"
13154 rtx label = gen_label_rtx ();
13156 rtx op1 = gen_reg_rtx (XFmode);
13157 rtx op2 = gen_reg_rtx (XFmode);
13159 emit_move_insn (op2, operands[2]);
13160 emit_move_insn (op1, operands[1]);
13162 emit_label (label);
13163 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13164 ix86_emit_fp_unordered_jump (label);
13165 LABEL_NUSES (label) = 1;
13167 emit_move_insn (operands[0], op1);
13171 (define_expand "fmod<mode>3"
13172 [(use (match_operand:MODEF 0 "register_operand" ""))
13173 (use (match_operand:MODEF 1 "general_operand" ""))
13174 (use (match_operand:MODEF 2 "general_operand" ""))]
13175 "TARGET_USE_FANCY_MATH_387"
13177 rtx (*gen_truncxf) (rtx, rtx);
13179 rtx label = gen_label_rtx ();
13181 rtx op1 = gen_reg_rtx (XFmode);
13182 rtx op2 = gen_reg_rtx (XFmode);
13184 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13185 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13187 emit_label (label);
13188 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13189 ix86_emit_fp_unordered_jump (label);
13190 LABEL_NUSES (label) = 1;
13192 /* Truncate the result properly for strict SSE math. */
13193 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13194 && !TARGET_MIX_SSE_I387)
13195 gen_truncxf = gen_truncxf<mode>2;
13197 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13199 emit_insn (gen_truncxf (operands[0], op1));
13203 (define_insn "fprem1xf4_i387"
13204 [(set (match_operand:XF 0 "register_operand" "=f")
13205 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13206 (match_operand:XF 3 "register_operand" "1")]
13208 (set (match_operand:XF 1 "register_operand" "=u")
13209 (unspec:XF [(match_dup 2) (match_dup 3)]
13211 (set (reg:CCFP FPSR_REG)
13212 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13214 "TARGET_USE_FANCY_MATH_387"
13216 [(set_attr "type" "fpspc")
13217 (set_attr "mode" "XF")])
13219 (define_expand "remainderxf3"
13220 [(use (match_operand:XF 0 "register_operand" ""))
13221 (use (match_operand:XF 1 "general_operand" ""))
13222 (use (match_operand:XF 2 "general_operand" ""))]
13223 "TARGET_USE_FANCY_MATH_387"
13225 rtx label = gen_label_rtx ();
13227 rtx op1 = gen_reg_rtx (XFmode);
13228 rtx op2 = gen_reg_rtx (XFmode);
13230 emit_move_insn (op2, operands[2]);
13231 emit_move_insn (op1, operands[1]);
13233 emit_label (label);
13234 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13235 ix86_emit_fp_unordered_jump (label);
13236 LABEL_NUSES (label) = 1;
13238 emit_move_insn (operands[0], op1);
13242 (define_expand "remainder<mode>3"
13243 [(use (match_operand:MODEF 0 "register_operand" ""))
13244 (use (match_operand:MODEF 1 "general_operand" ""))
13245 (use (match_operand:MODEF 2 "general_operand" ""))]
13246 "TARGET_USE_FANCY_MATH_387"
13248 rtx (*gen_truncxf) (rtx, rtx);
13250 rtx label = gen_label_rtx ();
13252 rtx op1 = gen_reg_rtx (XFmode);
13253 rtx op2 = gen_reg_rtx (XFmode);
13255 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13256 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13258 emit_label (label);
13260 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13261 ix86_emit_fp_unordered_jump (label);
13262 LABEL_NUSES (label) = 1;
13264 /* Truncate the result properly for strict SSE math. */
13265 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13266 && !TARGET_MIX_SSE_I387)
13267 gen_truncxf = gen_truncxf<mode>2;
13269 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13271 emit_insn (gen_truncxf (operands[0], op1));
13275 (define_insn "*sinxf2_i387"
13276 [(set (match_operand:XF 0 "register_operand" "=f")
13277 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13278 "TARGET_USE_FANCY_MATH_387
13279 && flag_unsafe_math_optimizations"
13281 [(set_attr "type" "fpspc")
13282 (set_attr "mode" "XF")])
13284 (define_insn "*sin_extend<mode>xf2_i387"
13285 [(set (match_operand:XF 0 "register_operand" "=f")
13286 (unspec:XF [(float_extend:XF
13287 (match_operand:MODEF 1 "register_operand" "0"))]
13289 "TARGET_USE_FANCY_MATH_387
13290 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13291 || TARGET_MIX_SSE_I387)
13292 && flag_unsafe_math_optimizations"
13294 [(set_attr "type" "fpspc")
13295 (set_attr "mode" "XF")])
13297 (define_insn "*cosxf2_i387"
13298 [(set (match_operand:XF 0 "register_operand" "=f")
13299 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13300 "TARGET_USE_FANCY_MATH_387
13301 && flag_unsafe_math_optimizations"
13303 [(set_attr "type" "fpspc")
13304 (set_attr "mode" "XF")])
13306 (define_insn "*cos_extend<mode>xf2_i387"
13307 [(set (match_operand:XF 0 "register_operand" "=f")
13308 (unspec:XF [(float_extend:XF
13309 (match_operand:MODEF 1 "register_operand" "0"))]
13311 "TARGET_USE_FANCY_MATH_387
13312 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13313 || TARGET_MIX_SSE_I387)
13314 && flag_unsafe_math_optimizations"
13316 [(set_attr "type" "fpspc")
13317 (set_attr "mode" "XF")])
13319 ;; When sincos pattern is defined, sin and cos builtin functions will be
13320 ;; expanded to sincos pattern with one of its outputs left unused.
13321 ;; CSE pass will figure out if two sincos patterns can be combined,
13322 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13323 ;; depending on the unused output.
13325 (define_insn "sincosxf3"
13326 [(set (match_operand:XF 0 "register_operand" "=f")
13327 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13328 UNSPEC_SINCOS_COS))
13329 (set (match_operand:XF 1 "register_operand" "=u")
13330 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13331 "TARGET_USE_FANCY_MATH_387
13332 && flag_unsafe_math_optimizations"
13334 [(set_attr "type" "fpspc")
13335 (set_attr "mode" "XF")])
13338 [(set (match_operand:XF 0 "register_operand" "")
13339 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13340 UNSPEC_SINCOS_COS))
13341 (set (match_operand:XF 1 "register_operand" "")
13342 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13343 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13344 && can_create_pseudo_p ()"
13345 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13348 [(set (match_operand:XF 0 "register_operand" "")
13349 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13350 UNSPEC_SINCOS_COS))
13351 (set (match_operand:XF 1 "register_operand" "")
13352 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13353 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13354 && can_create_pseudo_p ()"
13355 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13357 (define_insn "sincos_extend<mode>xf3_i387"
13358 [(set (match_operand:XF 0 "register_operand" "=f")
13359 (unspec:XF [(float_extend:XF
13360 (match_operand:MODEF 2 "register_operand" "0"))]
13361 UNSPEC_SINCOS_COS))
13362 (set (match_operand:XF 1 "register_operand" "=u")
13363 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13364 "TARGET_USE_FANCY_MATH_387
13365 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13366 || TARGET_MIX_SSE_I387)
13367 && flag_unsafe_math_optimizations"
13369 [(set_attr "type" "fpspc")
13370 (set_attr "mode" "XF")])
13373 [(set (match_operand:XF 0 "register_operand" "")
13374 (unspec:XF [(float_extend:XF
13375 (match_operand:MODEF 2 "register_operand" ""))]
13376 UNSPEC_SINCOS_COS))
13377 (set (match_operand:XF 1 "register_operand" "")
13378 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13379 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13380 && can_create_pseudo_p ()"
13381 [(set (match_dup 1)
13382 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13385 [(set (match_operand:XF 0 "register_operand" "")
13386 (unspec:XF [(float_extend:XF
13387 (match_operand:MODEF 2 "register_operand" ""))]
13388 UNSPEC_SINCOS_COS))
13389 (set (match_operand:XF 1 "register_operand" "")
13390 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13391 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13392 && can_create_pseudo_p ()"
13393 [(set (match_dup 0)
13394 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13396 (define_expand "sincos<mode>3"
13397 [(use (match_operand:MODEF 0 "register_operand" ""))
13398 (use (match_operand:MODEF 1 "register_operand" ""))
13399 (use (match_operand:MODEF 2 "register_operand" ""))]
13400 "TARGET_USE_FANCY_MATH_387
13401 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13402 || TARGET_MIX_SSE_I387)
13403 && flag_unsafe_math_optimizations"
13405 rtx op0 = gen_reg_rtx (XFmode);
13406 rtx op1 = gen_reg_rtx (XFmode);
13408 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13409 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13410 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13414 (define_insn "fptanxf4_i387"
13415 [(set (match_operand:XF 0 "register_operand" "=f")
13416 (match_operand:XF 3 "const_double_operand" "F"))
13417 (set (match_operand:XF 1 "register_operand" "=u")
13418 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13420 "TARGET_USE_FANCY_MATH_387
13421 && flag_unsafe_math_optimizations
13422 && standard_80387_constant_p (operands[3]) == 2"
13424 [(set_attr "type" "fpspc")
13425 (set_attr "mode" "XF")])
13427 (define_insn "fptan_extend<mode>xf4_i387"
13428 [(set (match_operand:MODEF 0 "register_operand" "=f")
13429 (match_operand:MODEF 3 "const_double_operand" "F"))
13430 (set (match_operand:XF 1 "register_operand" "=u")
13431 (unspec:XF [(float_extend:XF
13432 (match_operand:MODEF 2 "register_operand" "0"))]
13434 "TARGET_USE_FANCY_MATH_387
13435 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13436 || TARGET_MIX_SSE_I387)
13437 && flag_unsafe_math_optimizations
13438 && standard_80387_constant_p (operands[3]) == 2"
13440 [(set_attr "type" "fpspc")
13441 (set_attr "mode" "XF")])
13443 (define_expand "tanxf2"
13444 [(use (match_operand:XF 0 "register_operand" ""))
13445 (use (match_operand:XF 1 "register_operand" ""))]
13446 "TARGET_USE_FANCY_MATH_387
13447 && flag_unsafe_math_optimizations"
13449 rtx one = gen_reg_rtx (XFmode);
13450 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13452 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13456 (define_expand "tan<mode>2"
13457 [(use (match_operand:MODEF 0 "register_operand" ""))
13458 (use (match_operand:MODEF 1 "register_operand" ""))]
13459 "TARGET_USE_FANCY_MATH_387
13460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13461 || TARGET_MIX_SSE_I387)
13462 && flag_unsafe_math_optimizations"
13464 rtx op0 = gen_reg_rtx (XFmode);
13466 rtx one = gen_reg_rtx (<MODE>mode);
13467 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13469 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13470 operands[1], op2));
13471 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13475 (define_insn "*fpatanxf3_i387"
13476 [(set (match_operand:XF 0 "register_operand" "=f")
13477 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13478 (match_operand:XF 2 "register_operand" "u")]
13480 (clobber (match_scratch:XF 3 "=2"))]
13481 "TARGET_USE_FANCY_MATH_387
13482 && flag_unsafe_math_optimizations"
13484 [(set_attr "type" "fpspc")
13485 (set_attr "mode" "XF")])
13487 (define_insn "fpatan_extend<mode>xf3_i387"
13488 [(set (match_operand:XF 0 "register_operand" "=f")
13489 (unspec:XF [(float_extend:XF
13490 (match_operand:MODEF 1 "register_operand" "0"))
13492 (match_operand:MODEF 2 "register_operand" "u"))]
13494 (clobber (match_scratch:XF 3 "=2"))]
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 (define_expand "atan2xf3"
13504 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13505 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13506 (match_operand:XF 1 "register_operand" "")]
13508 (clobber (match_scratch:XF 3 ""))])]
13509 "TARGET_USE_FANCY_MATH_387
13510 && flag_unsafe_math_optimizations")
13512 (define_expand "atan2<mode>3"
13513 [(use (match_operand:MODEF 0 "register_operand" ""))
13514 (use (match_operand:MODEF 1 "register_operand" ""))
13515 (use (match_operand:MODEF 2 "register_operand" ""))]
13516 "TARGET_USE_FANCY_MATH_387
13517 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13518 || TARGET_MIX_SSE_I387)
13519 && flag_unsafe_math_optimizations"
13521 rtx op0 = gen_reg_rtx (XFmode);
13523 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13524 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13528 (define_expand "atanxf2"
13529 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13530 (unspec:XF [(match_dup 2)
13531 (match_operand:XF 1 "register_operand" "")]
13533 (clobber (match_scratch:XF 3 ""))])]
13534 "TARGET_USE_FANCY_MATH_387
13535 && flag_unsafe_math_optimizations"
13537 operands[2] = gen_reg_rtx (XFmode);
13538 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13541 (define_expand "atan<mode>2"
13542 [(use (match_operand:MODEF 0 "register_operand" ""))
13543 (use (match_operand:MODEF 1 "register_operand" ""))]
13544 "TARGET_USE_FANCY_MATH_387
13545 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13546 || TARGET_MIX_SSE_I387)
13547 && flag_unsafe_math_optimizations"
13549 rtx op0 = gen_reg_rtx (XFmode);
13551 rtx op2 = gen_reg_rtx (<MODE>mode);
13552 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13554 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13555 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13559 (define_expand "asinxf2"
13560 [(set (match_dup 2)
13561 (mult:XF (match_operand:XF 1 "register_operand" "")
13563 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13564 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13565 (parallel [(set (match_operand:XF 0 "register_operand" "")
13566 (unspec:XF [(match_dup 5) (match_dup 1)]
13568 (clobber (match_scratch:XF 6 ""))])]
13569 "TARGET_USE_FANCY_MATH_387
13570 && flag_unsafe_math_optimizations"
13574 if (optimize_insn_for_size_p ())
13577 for (i = 2; i < 6; i++)
13578 operands[i] = gen_reg_rtx (XFmode);
13580 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13583 (define_expand "asin<mode>2"
13584 [(use (match_operand:MODEF 0 "register_operand" ""))
13585 (use (match_operand:MODEF 1 "general_operand" ""))]
13586 "TARGET_USE_FANCY_MATH_387
13587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13588 || TARGET_MIX_SSE_I387)
13589 && flag_unsafe_math_optimizations"
13591 rtx op0 = gen_reg_rtx (XFmode);
13592 rtx op1 = gen_reg_rtx (XFmode);
13594 if (optimize_insn_for_size_p ())
13597 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13598 emit_insn (gen_asinxf2 (op0, op1));
13599 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13603 (define_expand "acosxf2"
13604 [(set (match_dup 2)
13605 (mult:XF (match_operand:XF 1 "register_operand" "")
13607 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13608 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13609 (parallel [(set (match_operand:XF 0 "register_operand" "")
13610 (unspec:XF [(match_dup 1) (match_dup 5)]
13612 (clobber (match_scratch:XF 6 ""))])]
13613 "TARGET_USE_FANCY_MATH_387
13614 && flag_unsafe_math_optimizations"
13618 if (optimize_insn_for_size_p ())
13621 for (i = 2; i < 6; i++)
13622 operands[i] = gen_reg_rtx (XFmode);
13624 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13627 (define_expand "acos<mode>2"
13628 [(use (match_operand:MODEF 0 "register_operand" ""))
13629 (use (match_operand:MODEF 1 "general_operand" ""))]
13630 "TARGET_USE_FANCY_MATH_387
13631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13632 || TARGET_MIX_SSE_I387)
13633 && flag_unsafe_math_optimizations"
13635 rtx op0 = gen_reg_rtx (XFmode);
13636 rtx op1 = gen_reg_rtx (XFmode);
13638 if (optimize_insn_for_size_p ())
13641 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13642 emit_insn (gen_acosxf2 (op0, op1));
13643 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13647 (define_insn "fyl2xxf3_i387"
13648 [(set (match_operand:XF 0 "register_operand" "=f")
13649 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13650 (match_operand:XF 2 "register_operand" "u")]
13652 (clobber (match_scratch:XF 3 "=2"))]
13653 "TARGET_USE_FANCY_MATH_387
13654 && flag_unsafe_math_optimizations"
13656 [(set_attr "type" "fpspc")
13657 (set_attr "mode" "XF")])
13659 (define_insn "fyl2x_extend<mode>xf3_i387"
13660 [(set (match_operand:XF 0 "register_operand" "=f")
13661 (unspec:XF [(float_extend:XF
13662 (match_operand:MODEF 1 "register_operand" "0"))
13663 (match_operand:XF 2 "register_operand" "u")]
13665 (clobber (match_scratch:XF 3 "=2"))]
13666 "TARGET_USE_FANCY_MATH_387
13667 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13668 || TARGET_MIX_SSE_I387)
13669 && flag_unsafe_math_optimizations"
13671 [(set_attr "type" "fpspc")
13672 (set_attr "mode" "XF")])
13674 (define_expand "logxf2"
13675 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13676 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13677 (match_dup 2)] UNSPEC_FYL2X))
13678 (clobber (match_scratch:XF 3 ""))])]
13679 "TARGET_USE_FANCY_MATH_387
13680 && flag_unsafe_math_optimizations"
13682 operands[2] = gen_reg_rtx (XFmode);
13683 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13686 (define_expand "log<mode>2"
13687 [(use (match_operand:MODEF 0 "register_operand" ""))
13688 (use (match_operand:MODEF 1 "register_operand" ""))]
13689 "TARGET_USE_FANCY_MATH_387
13690 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13691 || TARGET_MIX_SSE_I387)
13692 && flag_unsafe_math_optimizations"
13694 rtx op0 = gen_reg_rtx (XFmode);
13696 rtx op2 = gen_reg_rtx (XFmode);
13697 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13699 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13700 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13704 (define_expand "log10xf2"
13705 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13706 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13707 (match_dup 2)] UNSPEC_FYL2X))
13708 (clobber (match_scratch:XF 3 ""))])]
13709 "TARGET_USE_FANCY_MATH_387
13710 && flag_unsafe_math_optimizations"
13712 operands[2] = gen_reg_rtx (XFmode);
13713 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13716 (define_expand "log10<mode>2"
13717 [(use (match_operand:MODEF 0 "register_operand" ""))
13718 (use (match_operand:MODEF 1 "register_operand" ""))]
13719 "TARGET_USE_FANCY_MATH_387
13720 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13721 || TARGET_MIX_SSE_I387)
13722 && flag_unsafe_math_optimizations"
13724 rtx op0 = gen_reg_rtx (XFmode);
13726 rtx op2 = gen_reg_rtx (XFmode);
13727 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13729 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13730 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13734 (define_expand "log2xf2"
13735 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13736 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13737 (match_dup 2)] UNSPEC_FYL2X))
13738 (clobber (match_scratch:XF 3 ""))])]
13739 "TARGET_USE_FANCY_MATH_387
13740 && flag_unsafe_math_optimizations"
13742 operands[2] = gen_reg_rtx (XFmode);
13743 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13746 (define_expand "log2<mode>2"
13747 [(use (match_operand:MODEF 0 "register_operand" ""))
13748 (use (match_operand:MODEF 1 "register_operand" ""))]
13749 "TARGET_USE_FANCY_MATH_387
13750 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13751 || TARGET_MIX_SSE_I387)
13752 && flag_unsafe_math_optimizations"
13754 rtx op0 = gen_reg_rtx (XFmode);
13756 rtx op2 = gen_reg_rtx (XFmode);
13757 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13759 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13760 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13764 (define_insn "fyl2xp1xf3_i387"
13765 [(set (match_operand:XF 0 "register_operand" "=f")
13766 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13767 (match_operand:XF 2 "register_operand" "u")]
13769 (clobber (match_scratch:XF 3 "=2"))]
13770 "TARGET_USE_FANCY_MATH_387
13771 && flag_unsafe_math_optimizations"
13773 [(set_attr "type" "fpspc")
13774 (set_attr "mode" "XF")])
13776 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13777 [(set (match_operand:XF 0 "register_operand" "=f")
13778 (unspec:XF [(float_extend:XF
13779 (match_operand:MODEF 1 "register_operand" "0"))
13780 (match_operand:XF 2 "register_operand" "u")]
13782 (clobber (match_scratch:XF 3 "=2"))]
13783 "TARGET_USE_FANCY_MATH_387
13784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13785 || TARGET_MIX_SSE_I387)
13786 && flag_unsafe_math_optimizations"
13788 [(set_attr "type" "fpspc")
13789 (set_attr "mode" "XF")])
13791 (define_expand "log1pxf2"
13792 [(use (match_operand:XF 0 "register_operand" ""))
13793 (use (match_operand:XF 1 "register_operand" ""))]
13794 "TARGET_USE_FANCY_MATH_387
13795 && flag_unsafe_math_optimizations"
13797 if (optimize_insn_for_size_p ())
13800 ix86_emit_i387_log1p (operands[0], operands[1]);
13804 (define_expand "log1p<mode>2"
13805 [(use (match_operand:MODEF 0 "register_operand" ""))
13806 (use (match_operand:MODEF 1 "register_operand" ""))]
13807 "TARGET_USE_FANCY_MATH_387
13808 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13809 || TARGET_MIX_SSE_I387)
13810 && flag_unsafe_math_optimizations"
13814 if (optimize_insn_for_size_p ())
13817 op0 = gen_reg_rtx (XFmode);
13819 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13821 ix86_emit_i387_log1p (op0, operands[1]);
13822 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13826 (define_insn "fxtractxf3_i387"
13827 [(set (match_operand:XF 0 "register_operand" "=f")
13828 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13829 UNSPEC_XTRACT_FRACT))
13830 (set (match_operand:XF 1 "register_operand" "=u")
13831 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13832 "TARGET_USE_FANCY_MATH_387
13833 && flag_unsafe_math_optimizations"
13835 [(set_attr "type" "fpspc")
13836 (set_attr "mode" "XF")])
13838 (define_insn "fxtract_extend<mode>xf3_i387"
13839 [(set (match_operand:XF 0 "register_operand" "=f")
13840 (unspec:XF [(float_extend:XF
13841 (match_operand:MODEF 2 "register_operand" "0"))]
13842 UNSPEC_XTRACT_FRACT))
13843 (set (match_operand:XF 1 "register_operand" "=u")
13844 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13845 "TARGET_USE_FANCY_MATH_387
13846 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13847 || TARGET_MIX_SSE_I387)
13848 && flag_unsafe_math_optimizations"
13850 [(set_attr "type" "fpspc")
13851 (set_attr "mode" "XF")])
13853 (define_expand "logbxf2"
13854 [(parallel [(set (match_dup 2)
13855 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13856 UNSPEC_XTRACT_FRACT))
13857 (set (match_operand:XF 0 "register_operand" "")
13858 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13859 "TARGET_USE_FANCY_MATH_387
13860 && flag_unsafe_math_optimizations"
13861 "operands[2] = gen_reg_rtx (XFmode);")
13863 (define_expand "logb<mode>2"
13864 [(use (match_operand:MODEF 0 "register_operand" ""))
13865 (use (match_operand:MODEF 1 "register_operand" ""))]
13866 "TARGET_USE_FANCY_MATH_387
13867 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13868 || TARGET_MIX_SSE_I387)
13869 && flag_unsafe_math_optimizations"
13871 rtx op0 = gen_reg_rtx (XFmode);
13872 rtx op1 = gen_reg_rtx (XFmode);
13874 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13875 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13879 (define_expand "ilogbxf2"
13880 [(use (match_operand:SI 0 "register_operand" ""))
13881 (use (match_operand:XF 1 "register_operand" ""))]
13882 "TARGET_USE_FANCY_MATH_387
13883 && flag_unsafe_math_optimizations"
13887 if (optimize_insn_for_size_p ())
13890 op0 = gen_reg_rtx (XFmode);
13891 op1 = gen_reg_rtx (XFmode);
13893 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13894 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13898 (define_expand "ilogb<mode>2"
13899 [(use (match_operand:SI 0 "register_operand" ""))
13900 (use (match_operand:MODEF 1 "register_operand" ""))]
13901 "TARGET_USE_FANCY_MATH_387
13902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13903 || TARGET_MIX_SSE_I387)
13904 && flag_unsafe_math_optimizations"
13908 if (optimize_insn_for_size_p ())
13911 op0 = gen_reg_rtx (XFmode);
13912 op1 = gen_reg_rtx (XFmode);
13914 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13915 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13919 (define_insn "*f2xm1xf2_i387"
13920 [(set (match_operand:XF 0 "register_operand" "=f")
13921 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13923 "TARGET_USE_FANCY_MATH_387
13924 && flag_unsafe_math_optimizations"
13926 [(set_attr "type" "fpspc")
13927 (set_attr "mode" "XF")])
13929 (define_insn "*fscalexf4_i387"
13930 [(set (match_operand:XF 0 "register_operand" "=f")
13931 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13932 (match_operand:XF 3 "register_operand" "1")]
13933 UNSPEC_FSCALE_FRACT))
13934 (set (match_operand:XF 1 "register_operand" "=u")
13935 (unspec:XF [(match_dup 2) (match_dup 3)]
13936 UNSPEC_FSCALE_EXP))]
13937 "TARGET_USE_FANCY_MATH_387
13938 && flag_unsafe_math_optimizations"
13940 [(set_attr "type" "fpspc")
13941 (set_attr "mode" "XF")])
13943 (define_expand "expNcorexf3"
13944 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13945 (match_operand:XF 2 "register_operand" "")))
13946 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13947 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13948 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13949 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13950 (parallel [(set (match_operand:XF 0 "register_operand" "")
13951 (unspec:XF [(match_dup 8) (match_dup 4)]
13952 UNSPEC_FSCALE_FRACT))
13954 (unspec:XF [(match_dup 8) (match_dup 4)]
13955 UNSPEC_FSCALE_EXP))])]
13956 "TARGET_USE_FANCY_MATH_387
13957 && flag_unsafe_math_optimizations"
13961 if (optimize_insn_for_size_p ())
13964 for (i = 3; i < 10; i++)
13965 operands[i] = gen_reg_rtx (XFmode);
13967 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13970 (define_expand "expxf2"
13971 [(use (match_operand:XF 0 "register_operand" ""))
13972 (use (match_operand:XF 1 "register_operand" ""))]
13973 "TARGET_USE_FANCY_MATH_387
13974 && flag_unsafe_math_optimizations"
13978 if (optimize_insn_for_size_p ())
13981 op2 = gen_reg_rtx (XFmode);
13982 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13984 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13988 (define_expand "exp<mode>2"
13989 [(use (match_operand:MODEF 0 "register_operand" ""))
13990 (use (match_operand:MODEF 1 "general_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);
14002 op1 = gen_reg_rtx (XFmode);
14004 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14005 emit_insn (gen_expxf2 (op0, op1));
14006 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14010 (define_expand "exp10xf2"
14011 [(use (match_operand:XF 0 "register_operand" ""))
14012 (use (match_operand:XF 1 "register_operand" ""))]
14013 "TARGET_USE_FANCY_MATH_387
14014 && flag_unsafe_math_optimizations"
14018 if (optimize_insn_for_size_p ())
14021 op2 = gen_reg_rtx (XFmode);
14022 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14024 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14028 (define_expand "exp10<mode>2"
14029 [(use (match_operand:MODEF 0 "register_operand" ""))
14030 (use (match_operand:MODEF 1 "general_operand" ""))]
14031 "TARGET_USE_FANCY_MATH_387
14032 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14033 || TARGET_MIX_SSE_I387)
14034 && flag_unsafe_math_optimizations"
14038 if (optimize_insn_for_size_p ())
14041 op0 = gen_reg_rtx (XFmode);
14042 op1 = gen_reg_rtx (XFmode);
14044 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14045 emit_insn (gen_exp10xf2 (op0, op1));
14046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14050 (define_expand "exp2xf2"
14051 [(use (match_operand:XF 0 "register_operand" ""))
14052 (use (match_operand:XF 1 "register_operand" ""))]
14053 "TARGET_USE_FANCY_MATH_387
14054 && flag_unsafe_math_optimizations"
14058 if (optimize_insn_for_size_p ())
14061 op2 = gen_reg_rtx (XFmode);
14062 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14064 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14068 (define_expand "exp2<mode>2"
14069 [(use (match_operand:MODEF 0 "register_operand" ""))
14070 (use (match_operand:MODEF 1 "general_operand" ""))]
14071 "TARGET_USE_FANCY_MATH_387
14072 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14073 || TARGET_MIX_SSE_I387)
14074 && flag_unsafe_math_optimizations"
14078 if (optimize_insn_for_size_p ())
14081 op0 = gen_reg_rtx (XFmode);
14082 op1 = gen_reg_rtx (XFmode);
14084 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14085 emit_insn (gen_exp2xf2 (op0, op1));
14086 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14090 (define_expand "expm1xf2"
14091 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14093 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14094 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14095 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14096 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14097 (parallel [(set (match_dup 7)
14098 (unspec:XF [(match_dup 6) (match_dup 4)]
14099 UNSPEC_FSCALE_FRACT))
14101 (unspec:XF [(match_dup 6) (match_dup 4)]
14102 UNSPEC_FSCALE_EXP))])
14103 (parallel [(set (match_dup 10)
14104 (unspec:XF [(match_dup 9) (match_dup 8)]
14105 UNSPEC_FSCALE_FRACT))
14106 (set (match_dup 11)
14107 (unspec:XF [(match_dup 9) (match_dup 8)]
14108 UNSPEC_FSCALE_EXP))])
14109 (set (match_dup 12) (minus:XF (match_dup 10)
14110 (float_extend:XF (match_dup 13))))
14111 (set (match_operand:XF 0 "register_operand" "")
14112 (plus:XF (match_dup 12) (match_dup 7)))]
14113 "TARGET_USE_FANCY_MATH_387
14114 && flag_unsafe_math_optimizations"
14118 if (optimize_insn_for_size_p ())
14121 for (i = 2; i < 13; i++)
14122 operands[i] = gen_reg_rtx (XFmode);
14125 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14127 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14130 (define_expand "expm1<mode>2"
14131 [(use (match_operand:MODEF 0 "register_operand" ""))
14132 (use (match_operand:MODEF 1 "general_operand" ""))]
14133 "TARGET_USE_FANCY_MATH_387
14134 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14135 || TARGET_MIX_SSE_I387)
14136 && flag_unsafe_math_optimizations"
14140 if (optimize_insn_for_size_p ())
14143 op0 = gen_reg_rtx (XFmode);
14144 op1 = gen_reg_rtx (XFmode);
14146 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14147 emit_insn (gen_expm1xf2 (op0, op1));
14148 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14152 (define_expand "ldexpxf3"
14153 [(set (match_dup 3)
14154 (float:XF (match_operand:SI 2 "register_operand" "")))
14155 (parallel [(set (match_operand:XF 0 " register_operand" "")
14156 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14158 UNSPEC_FSCALE_FRACT))
14160 (unspec:XF [(match_dup 1) (match_dup 3)]
14161 UNSPEC_FSCALE_EXP))])]
14162 "TARGET_USE_FANCY_MATH_387
14163 && flag_unsafe_math_optimizations"
14165 if (optimize_insn_for_size_p ())
14168 operands[3] = gen_reg_rtx (XFmode);
14169 operands[4] = gen_reg_rtx (XFmode);
14172 (define_expand "ldexp<mode>3"
14173 [(use (match_operand:MODEF 0 "register_operand" ""))
14174 (use (match_operand:MODEF 1 "general_operand" ""))
14175 (use (match_operand:SI 2 "register_operand" ""))]
14176 "TARGET_USE_FANCY_MATH_387
14177 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14178 || TARGET_MIX_SSE_I387)
14179 && flag_unsafe_math_optimizations"
14183 if (optimize_insn_for_size_p ())
14186 op0 = gen_reg_rtx (XFmode);
14187 op1 = gen_reg_rtx (XFmode);
14189 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14190 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14191 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14195 (define_expand "scalbxf3"
14196 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14197 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14198 (match_operand:XF 2 "register_operand" "")]
14199 UNSPEC_FSCALE_FRACT))
14201 (unspec:XF [(match_dup 1) (match_dup 2)]
14202 UNSPEC_FSCALE_EXP))])]
14203 "TARGET_USE_FANCY_MATH_387
14204 && flag_unsafe_math_optimizations"
14206 if (optimize_insn_for_size_p ())
14209 operands[3] = gen_reg_rtx (XFmode);
14212 (define_expand "scalb<mode>3"
14213 [(use (match_operand:MODEF 0 "register_operand" ""))
14214 (use (match_operand:MODEF 1 "general_operand" ""))
14215 (use (match_operand:MODEF 2 "general_operand" ""))]
14216 "TARGET_USE_FANCY_MATH_387
14217 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14218 || TARGET_MIX_SSE_I387)
14219 && flag_unsafe_math_optimizations"
14223 if (optimize_insn_for_size_p ())
14226 op0 = gen_reg_rtx (XFmode);
14227 op1 = gen_reg_rtx (XFmode);
14228 op2 = gen_reg_rtx (XFmode);
14230 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14231 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14232 emit_insn (gen_scalbxf3 (op0, op1, op2));
14233 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14237 (define_expand "significandxf2"
14238 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14239 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14240 UNSPEC_XTRACT_FRACT))
14242 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14243 "TARGET_USE_FANCY_MATH_387
14244 && flag_unsafe_math_optimizations"
14245 "operands[2] = gen_reg_rtx (XFmode);")
14247 (define_expand "significand<mode>2"
14248 [(use (match_operand:MODEF 0 "register_operand" ""))
14249 (use (match_operand:MODEF 1 "register_operand" ""))]
14250 "TARGET_USE_FANCY_MATH_387
14251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14252 || TARGET_MIX_SSE_I387)
14253 && flag_unsafe_math_optimizations"
14255 rtx op0 = gen_reg_rtx (XFmode);
14256 rtx op1 = gen_reg_rtx (XFmode);
14258 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14259 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14264 (define_insn "sse4_1_round<mode>2"
14265 [(set (match_operand:MODEF 0 "register_operand" "=x")
14266 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14267 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14270 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14271 [(set_attr "type" "ssecvt")
14272 (set_attr "prefix_extra" "1")
14273 (set_attr "prefix" "maybe_vex")
14274 (set_attr "mode" "<MODE>")])
14276 (define_insn "rintxf2"
14277 [(set (match_operand:XF 0 "register_operand" "=f")
14278 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14280 "TARGET_USE_FANCY_MATH_387
14281 && flag_unsafe_math_optimizations"
14283 [(set_attr "type" "fpspc")
14284 (set_attr "mode" "XF")])
14286 (define_expand "rint<mode>2"
14287 [(use (match_operand:MODEF 0 "register_operand" ""))
14288 (use (match_operand:MODEF 1 "register_operand" ""))]
14289 "(TARGET_USE_FANCY_MATH_387
14290 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14291 || TARGET_MIX_SSE_I387)
14292 && flag_unsafe_math_optimizations)
14293 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14294 && !flag_trapping_math)"
14296 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14297 && !flag_trapping_math)
14299 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14302 emit_insn (gen_sse4_1_round<mode>2
14303 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14305 ix86_expand_rint (operand0, operand1);
14309 rtx op0 = gen_reg_rtx (XFmode);
14310 rtx op1 = gen_reg_rtx (XFmode);
14312 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14313 emit_insn (gen_rintxf2 (op0, op1));
14315 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14320 (define_expand "round<mode>2"
14321 [(match_operand:MODEF 0 "register_operand" "")
14322 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14323 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14324 && !flag_trapping_math && !flag_rounding_math"
14326 if (optimize_insn_for_size_p ())
14328 if (TARGET_64BIT || (<MODE>mode != DFmode))
14329 ix86_expand_round (operand0, operand1);
14331 ix86_expand_rounddf_32 (operand0, operand1);
14335 (define_insn_and_split "*fistdi2_1"
14336 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14337 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14339 "TARGET_USE_FANCY_MATH_387
14340 && can_create_pseudo_p ()"
14345 if (memory_operand (operands[0], VOIDmode))
14346 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14349 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14350 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14355 [(set_attr "type" "fpspc")
14356 (set_attr "mode" "DI")])
14358 (define_insn "fistdi2"
14359 [(set (match_operand:DI 0 "memory_operand" "=m")
14360 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14362 (clobber (match_scratch:XF 2 "=&1f"))]
14363 "TARGET_USE_FANCY_MATH_387"
14364 "* return output_fix_trunc (insn, operands, 0);"
14365 [(set_attr "type" "fpspc")
14366 (set_attr "mode" "DI")])
14368 (define_insn "fistdi2_with_temp"
14369 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14370 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14372 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14373 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14374 "TARGET_USE_FANCY_MATH_387"
14376 [(set_attr "type" "fpspc")
14377 (set_attr "mode" "DI")])
14380 [(set (match_operand:DI 0 "register_operand" "")
14381 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14383 (clobber (match_operand:DI 2 "memory_operand" ""))
14384 (clobber (match_scratch 3 ""))]
14386 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14387 (clobber (match_dup 3))])
14388 (set (match_dup 0) (match_dup 2))])
14391 [(set (match_operand:DI 0 "memory_operand" "")
14392 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14394 (clobber (match_operand:DI 2 "memory_operand" ""))
14395 (clobber (match_scratch 3 ""))]
14397 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14398 (clobber (match_dup 3))])])
14400 (define_insn_and_split "*fist<mode>2_1"
14401 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14402 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14404 "TARGET_USE_FANCY_MATH_387
14405 && can_create_pseudo_p ()"
14410 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14411 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14415 [(set_attr "type" "fpspc")
14416 (set_attr "mode" "<MODE>")])
14418 (define_insn "fist<mode>2"
14419 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14420 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14422 "TARGET_USE_FANCY_MATH_387"
14423 "* return output_fix_trunc (insn, operands, 0);"
14424 [(set_attr "type" "fpspc")
14425 (set_attr "mode" "<MODE>")])
14427 (define_insn "fist<mode>2_with_temp"
14428 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14429 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14431 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14432 "TARGET_USE_FANCY_MATH_387"
14434 [(set_attr "type" "fpspc")
14435 (set_attr "mode" "<MODE>")])
14438 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14439 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14441 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14443 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14444 (set (match_dup 0) (match_dup 2))])
14447 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14448 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14450 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14452 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14454 (define_expand "lrintxf<mode>2"
14455 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14456 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14458 "TARGET_USE_FANCY_MATH_387")
14460 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14461 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14462 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14463 UNSPEC_FIX_NOTRUNC))]
14464 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14465 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14467 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14468 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14469 (match_operand:MODEF 1 "register_operand" "")]
14470 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14471 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14472 && !flag_trapping_math && !flag_rounding_math"
14474 if (optimize_insn_for_size_p ())
14476 ix86_expand_lround (operand0, operand1);
14480 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14481 (define_insn_and_split "frndintxf2_floor"
14482 [(set (match_operand:XF 0 "register_operand" "")
14483 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14484 UNSPEC_FRNDINT_FLOOR))
14485 (clobber (reg:CC FLAGS_REG))]
14486 "TARGET_USE_FANCY_MATH_387
14487 && flag_unsafe_math_optimizations
14488 && can_create_pseudo_p ()"
14493 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14495 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14496 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14498 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14499 operands[2], operands[3]));
14502 [(set_attr "type" "frndint")
14503 (set_attr "i387_cw" "floor")
14504 (set_attr "mode" "XF")])
14506 (define_insn "frndintxf2_floor_i387"
14507 [(set (match_operand:XF 0 "register_operand" "=f")
14508 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14509 UNSPEC_FRNDINT_FLOOR))
14510 (use (match_operand:HI 2 "memory_operand" "m"))
14511 (use (match_operand:HI 3 "memory_operand" "m"))]
14512 "TARGET_USE_FANCY_MATH_387
14513 && flag_unsafe_math_optimizations"
14514 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14515 [(set_attr "type" "frndint")
14516 (set_attr "i387_cw" "floor")
14517 (set_attr "mode" "XF")])
14519 (define_expand "floorxf2"
14520 [(use (match_operand:XF 0 "register_operand" ""))
14521 (use (match_operand:XF 1 "register_operand" ""))]
14522 "TARGET_USE_FANCY_MATH_387
14523 && flag_unsafe_math_optimizations"
14525 if (optimize_insn_for_size_p ())
14527 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14531 (define_expand "floor<mode>2"
14532 [(use (match_operand:MODEF 0 "register_operand" ""))
14533 (use (match_operand:MODEF 1 "register_operand" ""))]
14534 "(TARGET_USE_FANCY_MATH_387
14535 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14536 || TARGET_MIX_SSE_I387)
14537 && flag_unsafe_math_optimizations)
14538 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14539 && !flag_trapping_math)"
14541 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14542 && !flag_trapping_math
14543 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14545 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14548 emit_insn (gen_sse4_1_round<mode>2
14549 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14550 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14551 ix86_expand_floorceil (operand0, operand1, true);
14553 ix86_expand_floorceildf_32 (operand0, operand1, true);
14559 if (optimize_insn_for_size_p ())
14562 op0 = gen_reg_rtx (XFmode);
14563 op1 = gen_reg_rtx (XFmode);
14564 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14565 emit_insn (gen_frndintxf2_floor (op0, op1));
14567 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14572 (define_insn_and_split "*fist<mode>2_floor_1"
14573 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14574 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14575 UNSPEC_FIST_FLOOR))
14576 (clobber (reg:CC FLAGS_REG))]
14577 "TARGET_USE_FANCY_MATH_387
14578 && flag_unsafe_math_optimizations
14579 && can_create_pseudo_p ()"
14584 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14586 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14587 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14588 if (memory_operand (operands[0], VOIDmode))
14589 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14590 operands[2], operands[3]));
14593 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14594 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14595 operands[2], operands[3],
14600 [(set_attr "type" "fistp")
14601 (set_attr "i387_cw" "floor")
14602 (set_attr "mode" "<MODE>")])
14604 (define_insn "fistdi2_floor"
14605 [(set (match_operand:DI 0 "memory_operand" "=m")
14606 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14607 UNSPEC_FIST_FLOOR))
14608 (use (match_operand:HI 2 "memory_operand" "m"))
14609 (use (match_operand:HI 3 "memory_operand" "m"))
14610 (clobber (match_scratch:XF 4 "=&1f"))]
14611 "TARGET_USE_FANCY_MATH_387
14612 && flag_unsafe_math_optimizations"
14613 "* return output_fix_trunc (insn, operands, 0);"
14614 [(set_attr "type" "fistp")
14615 (set_attr "i387_cw" "floor")
14616 (set_attr "mode" "DI")])
14618 (define_insn "fistdi2_floor_with_temp"
14619 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14620 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14621 UNSPEC_FIST_FLOOR))
14622 (use (match_operand:HI 2 "memory_operand" "m,m"))
14623 (use (match_operand:HI 3 "memory_operand" "m,m"))
14624 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14625 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14626 "TARGET_USE_FANCY_MATH_387
14627 && flag_unsafe_math_optimizations"
14629 [(set_attr "type" "fistp")
14630 (set_attr "i387_cw" "floor")
14631 (set_attr "mode" "DI")])
14634 [(set (match_operand:DI 0 "register_operand" "")
14635 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14636 UNSPEC_FIST_FLOOR))
14637 (use (match_operand:HI 2 "memory_operand" ""))
14638 (use (match_operand:HI 3 "memory_operand" ""))
14639 (clobber (match_operand:DI 4 "memory_operand" ""))
14640 (clobber (match_scratch 5 ""))]
14642 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14643 (use (match_dup 2))
14644 (use (match_dup 3))
14645 (clobber (match_dup 5))])
14646 (set (match_dup 0) (match_dup 4))])
14649 [(set (match_operand:DI 0 "memory_operand" "")
14650 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14651 UNSPEC_FIST_FLOOR))
14652 (use (match_operand:HI 2 "memory_operand" ""))
14653 (use (match_operand:HI 3 "memory_operand" ""))
14654 (clobber (match_operand:DI 4 "memory_operand" ""))
14655 (clobber (match_scratch 5 ""))]
14657 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14658 (use (match_dup 2))
14659 (use (match_dup 3))
14660 (clobber (match_dup 5))])])
14662 (define_insn "fist<mode>2_floor"
14663 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14664 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14665 UNSPEC_FIST_FLOOR))
14666 (use (match_operand:HI 2 "memory_operand" "m"))
14667 (use (match_operand:HI 3 "memory_operand" "m"))]
14668 "TARGET_USE_FANCY_MATH_387
14669 && flag_unsafe_math_optimizations"
14670 "* return output_fix_trunc (insn, operands, 0);"
14671 [(set_attr "type" "fistp")
14672 (set_attr "i387_cw" "floor")
14673 (set_attr "mode" "<MODE>")])
14675 (define_insn "fist<mode>2_floor_with_temp"
14676 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14677 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14678 UNSPEC_FIST_FLOOR))
14679 (use (match_operand:HI 2 "memory_operand" "m,m"))
14680 (use (match_operand:HI 3 "memory_operand" "m,m"))
14681 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14682 "TARGET_USE_FANCY_MATH_387
14683 && flag_unsafe_math_optimizations"
14685 [(set_attr "type" "fistp")
14686 (set_attr "i387_cw" "floor")
14687 (set_attr "mode" "<MODE>")])
14690 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14691 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14692 UNSPEC_FIST_FLOOR))
14693 (use (match_operand:HI 2 "memory_operand" ""))
14694 (use (match_operand:HI 3 "memory_operand" ""))
14695 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14697 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14698 UNSPEC_FIST_FLOOR))
14699 (use (match_dup 2))
14700 (use (match_dup 3))])
14701 (set (match_dup 0) (match_dup 4))])
14704 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14705 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14706 UNSPEC_FIST_FLOOR))
14707 (use (match_operand:HI 2 "memory_operand" ""))
14708 (use (match_operand:HI 3 "memory_operand" ""))
14709 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14711 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14712 UNSPEC_FIST_FLOOR))
14713 (use (match_dup 2))
14714 (use (match_dup 3))])])
14716 (define_expand "lfloorxf<mode>2"
14717 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14718 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14719 UNSPEC_FIST_FLOOR))
14720 (clobber (reg:CC FLAGS_REG))])]
14721 "TARGET_USE_FANCY_MATH_387
14722 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14723 && flag_unsafe_math_optimizations")
14725 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14726 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14727 (match_operand:MODEF 1 "register_operand" "")]
14728 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14729 && !flag_trapping_math"
14731 if (TARGET_64BIT && optimize_insn_for_size_p ())
14733 ix86_expand_lfloorceil (operand0, operand1, true);
14737 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14738 (define_insn_and_split "frndintxf2_ceil"
14739 [(set (match_operand:XF 0 "register_operand" "")
14740 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14741 UNSPEC_FRNDINT_CEIL))
14742 (clobber (reg:CC FLAGS_REG))]
14743 "TARGET_USE_FANCY_MATH_387
14744 && flag_unsafe_math_optimizations
14745 && can_create_pseudo_p ()"
14750 ix86_optimize_mode_switching[I387_CEIL] = 1;
14752 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14753 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14755 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14756 operands[2], operands[3]));
14759 [(set_attr "type" "frndint")
14760 (set_attr "i387_cw" "ceil")
14761 (set_attr "mode" "XF")])
14763 (define_insn "frndintxf2_ceil_i387"
14764 [(set (match_operand:XF 0 "register_operand" "=f")
14765 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14766 UNSPEC_FRNDINT_CEIL))
14767 (use (match_operand:HI 2 "memory_operand" "m"))
14768 (use (match_operand:HI 3 "memory_operand" "m"))]
14769 "TARGET_USE_FANCY_MATH_387
14770 && flag_unsafe_math_optimizations"
14771 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14772 [(set_attr "type" "frndint")
14773 (set_attr "i387_cw" "ceil")
14774 (set_attr "mode" "XF")])
14776 (define_expand "ceilxf2"
14777 [(use (match_operand:XF 0 "register_operand" ""))
14778 (use (match_operand:XF 1 "register_operand" ""))]
14779 "TARGET_USE_FANCY_MATH_387
14780 && flag_unsafe_math_optimizations"
14782 if (optimize_insn_for_size_p ())
14784 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14788 (define_expand "ceil<mode>2"
14789 [(use (match_operand:MODEF 0 "register_operand" ""))
14790 (use (match_operand:MODEF 1 "register_operand" ""))]
14791 "(TARGET_USE_FANCY_MATH_387
14792 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14793 || TARGET_MIX_SSE_I387)
14794 && flag_unsafe_math_optimizations)
14795 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14796 && !flag_trapping_math)"
14798 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14799 && !flag_trapping_math
14800 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14803 emit_insn (gen_sse4_1_round<mode>2
14804 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14805 else if (optimize_insn_for_size_p ())
14807 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14808 ix86_expand_floorceil (operand0, operand1, false);
14810 ix86_expand_floorceildf_32 (operand0, operand1, false);
14816 if (optimize_insn_for_size_p ())
14819 op0 = gen_reg_rtx (XFmode);
14820 op1 = gen_reg_rtx (XFmode);
14821 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14822 emit_insn (gen_frndintxf2_ceil (op0, op1));
14824 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14829 (define_insn_and_split "*fist<mode>2_ceil_1"
14830 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14831 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14833 (clobber (reg:CC FLAGS_REG))]
14834 "TARGET_USE_FANCY_MATH_387
14835 && flag_unsafe_math_optimizations
14836 && can_create_pseudo_p ()"
14841 ix86_optimize_mode_switching[I387_CEIL] = 1;
14843 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14844 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14845 if (memory_operand (operands[0], VOIDmode))
14846 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14847 operands[2], operands[3]));
14850 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14851 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14852 operands[2], operands[3],
14857 [(set_attr "type" "fistp")
14858 (set_attr "i387_cw" "ceil")
14859 (set_attr "mode" "<MODE>")])
14861 (define_insn "fistdi2_ceil"
14862 [(set (match_operand:DI 0 "memory_operand" "=m")
14863 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14865 (use (match_operand:HI 2 "memory_operand" "m"))
14866 (use (match_operand:HI 3 "memory_operand" "m"))
14867 (clobber (match_scratch:XF 4 "=&1f"))]
14868 "TARGET_USE_FANCY_MATH_387
14869 && flag_unsafe_math_optimizations"
14870 "* return output_fix_trunc (insn, operands, 0);"
14871 [(set_attr "type" "fistp")
14872 (set_attr "i387_cw" "ceil")
14873 (set_attr "mode" "DI")])
14875 (define_insn "fistdi2_ceil_with_temp"
14876 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14877 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14879 (use (match_operand:HI 2 "memory_operand" "m,m"))
14880 (use (match_operand:HI 3 "memory_operand" "m,m"))
14881 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14882 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14883 "TARGET_USE_FANCY_MATH_387
14884 && flag_unsafe_math_optimizations"
14886 [(set_attr "type" "fistp")
14887 (set_attr "i387_cw" "ceil")
14888 (set_attr "mode" "DI")])
14891 [(set (match_operand:DI 0 "register_operand" "")
14892 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14894 (use (match_operand:HI 2 "memory_operand" ""))
14895 (use (match_operand:HI 3 "memory_operand" ""))
14896 (clobber (match_operand:DI 4 "memory_operand" ""))
14897 (clobber (match_scratch 5 ""))]
14899 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14900 (use (match_dup 2))
14901 (use (match_dup 3))
14902 (clobber (match_dup 5))])
14903 (set (match_dup 0) (match_dup 4))])
14906 [(set (match_operand:DI 0 "memory_operand" "")
14907 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14909 (use (match_operand:HI 2 "memory_operand" ""))
14910 (use (match_operand:HI 3 "memory_operand" ""))
14911 (clobber (match_operand:DI 4 "memory_operand" ""))
14912 (clobber (match_scratch 5 ""))]
14914 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14915 (use (match_dup 2))
14916 (use (match_dup 3))
14917 (clobber (match_dup 5))])])
14919 (define_insn "fist<mode>2_ceil"
14920 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14921 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14923 (use (match_operand:HI 2 "memory_operand" "m"))
14924 (use (match_operand:HI 3 "memory_operand" "m"))]
14925 "TARGET_USE_FANCY_MATH_387
14926 && flag_unsafe_math_optimizations"
14927 "* return output_fix_trunc (insn, operands, 0);"
14928 [(set_attr "type" "fistp")
14929 (set_attr "i387_cw" "ceil")
14930 (set_attr "mode" "<MODE>")])
14932 (define_insn "fist<mode>2_ceil_with_temp"
14933 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14934 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14936 (use (match_operand:HI 2 "memory_operand" "m,m"))
14937 (use (match_operand:HI 3 "memory_operand" "m,m"))
14938 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && flag_unsafe_math_optimizations"
14942 [(set_attr "type" "fistp")
14943 (set_attr "i387_cw" "ceil")
14944 (set_attr "mode" "<MODE>")])
14947 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14948 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14950 (use (match_operand:HI 2 "memory_operand" ""))
14951 (use (match_operand:HI 3 "memory_operand" ""))
14952 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14954 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14956 (use (match_dup 2))
14957 (use (match_dup 3))])
14958 (set (match_dup 0) (match_dup 4))])
14961 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14962 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14964 (use (match_operand:HI 2 "memory_operand" ""))
14965 (use (match_operand:HI 3 "memory_operand" ""))
14966 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14968 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14970 (use (match_dup 2))
14971 (use (match_dup 3))])])
14973 (define_expand "lceilxf<mode>2"
14974 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14975 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14977 (clobber (reg:CC FLAGS_REG))])]
14978 "TARGET_USE_FANCY_MATH_387
14979 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14980 && flag_unsafe_math_optimizations")
14982 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14983 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14984 (match_operand:MODEF 1 "register_operand" "")]
14985 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14986 && !flag_trapping_math"
14988 ix86_expand_lfloorceil (operand0, operand1, false);
14992 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14993 (define_insn_and_split "frndintxf2_trunc"
14994 [(set (match_operand:XF 0 "register_operand" "")
14995 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14996 UNSPEC_FRNDINT_TRUNC))
14997 (clobber (reg:CC FLAGS_REG))]
14998 "TARGET_USE_FANCY_MATH_387
14999 && flag_unsafe_math_optimizations
15000 && can_create_pseudo_p ()"
15005 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15007 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15008 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15010 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15011 operands[2], operands[3]));
15014 [(set_attr "type" "frndint")
15015 (set_attr "i387_cw" "trunc")
15016 (set_attr "mode" "XF")])
15018 (define_insn "frndintxf2_trunc_i387"
15019 [(set (match_operand:XF 0 "register_operand" "=f")
15020 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15021 UNSPEC_FRNDINT_TRUNC))
15022 (use (match_operand:HI 2 "memory_operand" "m"))
15023 (use (match_operand:HI 3 "memory_operand" "m"))]
15024 "TARGET_USE_FANCY_MATH_387
15025 && flag_unsafe_math_optimizations"
15026 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15027 [(set_attr "type" "frndint")
15028 (set_attr "i387_cw" "trunc")
15029 (set_attr "mode" "XF")])
15031 (define_expand "btruncxf2"
15032 [(use (match_operand:XF 0 "register_operand" ""))
15033 (use (match_operand:XF 1 "register_operand" ""))]
15034 "TARGET_USE_FANCY_MATH_387
15035 && flag_unsafe_math_optimizations"
15037 if (optimize_insn_for_size_p ())
15039 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15043 (define_expand "btrunc<mode>2"
15044 [(use (match_operand:MODEF 0 "register_operand" ""))
15045 (use (match_operand:MODEF 1 "register_operand" ""))]
15046 "(TARGET_USE_FANCY_MATH_387
15047 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15048 || TARGET_MIX_SSE_I387)
15049 && flag_unsafe_math_optimizations)
15050 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15051 && !flag_trapping_math)"
15053 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15054 && !flag_trapping_math
15055 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15058 emit_insn (gen_sse4_1_round<mode>2
15059 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15060 else if (optimize_insn_for_size_p ())
15062 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15063 ix86_expand_trunc (operand0, operand1);
15065 ix86_expand_truncdf_32 (operand0, operand1);
15071 if (optimize_insn_for_size_p ())
15074 op0 = gen_reg_rtx (XFmode);
15075 op1 = gen_reg_rtx (XFmode);
15076 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15077 emit_insn (gen_frndintxf2_trunc (op0, op1));
15079 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15084 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15085 (define_insn_and_split "frndintxf2_mask_pm"
15086 [(set (match_operand:XF 0 "register_operand" "")
15087 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15088 UNSPEC_FRNDINT_MASK_PM))
15089 (clobber (reg:CC FLAGS_REG))]
15090 "TARGET_USE_FANCY_MATH_387
15091 && flag_unsafe_math_optimizations
15092 && can_create_pseudo_p ()"
15097 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15099 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15100 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15102 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15103 operands[2], operands[3]));
15106 [(set_attr "type" "frndint")
15107 (set_attr "i387_cw" "mask_pm")
15108 (set_attr "mode" "XF")])
15110 (define_insn "frndintxf2_mask_pm_i387"
15111 [(set (match_operand:XF 0 "register_operand" "=f")
15112 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15113 UNSPEC_FRNDINT_MASK_PM))
15114 (use (match_operand:HI 2 "memory_operand" "m"))
15115 (use (match_operand:HI 3 "memory_operand" "m"))]
15116 "TARGET_USE_FANCY_MATH_387
15117 && flag_unsafe_math_optimizations"
15118 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15119 [(set_attr "type" "frndint")
15120 (set_attr "i387_cw" "mask_pm")
15121 (set_attr "mode" "XF")])
15123 (define_expand "nearbyintxf2"
15124 [(use (match_operand:XF 0 "register_operand" ""))
15125 (use (match_operand:XF 1 "register_operand" ""))]
15126 "TARGET_USE_FANCY_MATH_387
15127 && flag_unsafe_math_optimizations"
15129 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15133 (define_expand "nearbyint<mode>2"
15134 [(use (match_operand:MODEF 0 "register_operand" ""))
15135 (use (match_operand:MODEF 1 "register_operand" ""))]
15136 "TARGET_USE_FANCY_MATH_387
15137 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15138 || TARGET_MIX_SSE_I387)
15139 && flag_unsafe_math_optimizations"
15141 rtx op0 = gen_reg_rtx (XFmode);
15142 rtx op1 = gen_reg_rtx (XFmode);
15144 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15145 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15147 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15151 (define_insn "fxam<mode>2_i387"
15152 [(set (match_operand:HI 0 "register_operand" "=a")
15154 [(match_operand:X87MODEF 1 "register_operand" "f")]
15156 "TARGET_USE_FANCY_MATH_387"
15157 "fxam\n\tfnstsw\t%0"
15158 [(set_attr "type" "multi")
15159 (set_attr "length" "4")
15160 (set_attr "unit" "i387")
15161 (set_attr "mode" "<MODE>")])
15163 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15164 [(set (match_operand:HI 0 "register_operand" "")
15166 [(match_operand:MODEF 1 "memory_operand" "")]
15168 "TARGET_USE_FANCY_MATH_387
15169 && can_create_pseudo_p ()"
15172 [(set (match_dup 2)(match_dup 1))
15174 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15176 operands[2] = gen_reg_rtx (<MODE>mode);
15178 MEM_VOLATILE_P (operands[1]) = 1;
15180 [(set_attr "type" "multi")
15181 (set_attr "unit" "i387")
15182 (set_attr "mode" "<MODE>")])
15184 (define_expand "isinfxf2"
15185 [(use (match_operand:SI 0 "register_operand" ""))
15186 (use (match_operand:XF 1 "register_operand" ""))]
15187 "TARGET_USE_FANCY_MATH_387
15188 && TARGET_C99_FUNCTIONS"
15190 rtx mask = GEN_INT (0x45);
15191 rtx val = GEN_INT (0x05);
15195 rtx scratch = gen_reg_rtx (HImode);
15196 rtx res = gen_reg_rtx (QImode);
15198 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15200 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15201 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15202 cond = gen_rtx_fmt_ee (EQ, QImode,
15203 gen_rtx_REG (CCmode, FLAGS_REG),
15205 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15206 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15210 (define_expand "isinf<mode>2"
15211 [(use (match_operand:SI 0 "register_operand" ""))
15212 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15213 "TARGET_USE_FANCY_MATH_387
15214 && TARGET_C99_FUNCTIONS
15215 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15217 rtx mask = GEN_INT (0x45);
15218 rtx val = GEN_INT (0x05);
15222 rtx scratch = gen_reg_rtx (HImode);
15223 rtx res = gen_reg_rtx (QImode);
15225 /* Remove excess precision by forcing value through memory. */
15226 if (memory_operand (operands[1], VOIDmode))
15227 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15230 enum ix86_stack_slot slot = (virtuals_instantiated
15233 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15235 emit_move_insn (temp, operands[1]);
15236 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15239 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15240 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15241 cond = gen_rtx_fmt_ee (EQ, QImode,
15242 gen_rtx_REG (CCmode, FLAGS_REG),
15244 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15245 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15249 (define_expand "signbitxf2"
15250 [(use (match_operand:SI 0 "register_operand" ""))
15251 (use (match_operand:XF 1 "register_operand" ""))]
15252 "TARGET_USE_FANCY_MATH_387"
15254 rtx scratch = gen_reg_rtx (HImode);
15256 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15257 emit_insn (gen_andsi3 (operands[0],
15258 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15262 (define_insn "movmsk_df"
15263 [(set (match_operand:SI 0 "register_operand" "=r")
15265 [(match_operand:DF 1 "register_operand" "x")]
15267 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15268 "%vmovmskpd\t{%1, %0|%0, %1}"
15269 [(set_attr "type" "ssemov")
15270 (set_attr "prefix" "maybe_vex")
15271 (set_attr "mode" "DF")])
15273 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15274 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15275 (define_expand "signbitdf2"
15276 [(use (match_operand:SI 0 "register_operand" ""))
15277 (use (match_operand:DF 1 "register_operand" ""))]
15278 "TARGET_USE_FANCY_MATH_387
15279 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15281 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15283 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15284 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15288 rtx scratch = gen_reg_rtx (HImode);
15290 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15291 emit_insn (gen_andsi3 (operands[0],
15292 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15297 (define_expand "signbitsf2"
15298 [(use (match_operand:SI 0 "register_operand" ""))
15299 (use (match_operand:SF 1 "register_operand" ""))]
15300 "TARGET_USE_FANCY_MATH_387
15301 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15303 rtx scratch = gen_reg_rtx (HImode);
15305 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15306 emit_insn (gen_andsi3 (operands[0],
15307 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15311 ;; Block operation instructions
15314 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15317 [(set_attr "length" "1")
15318 (set_attr "length_immediate" "0")
15319 (set_attr "modrm" "0")])
15321 (define_expand "movmem<mode>"
15322 [(use (match_operand:BLK 0 "memory_operand" ""))
15323 (use (match_operand:BLK 1 "memory_operand" ""))
15324 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15325 (use (match_operand:SWI48 3 "const_int_operand" ""))
15326 (use (match_operand:SI 4 "const_int_operand" ""))
15327 (use (match_operand:SI 5 "const_int_operand" ""))]
15330 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15331 operands[4], operands[5]))
15337 ;; Most CPUs don't like single string operations
15338 ;; Handle this case here to simplify previous expander.
15340 (define_expand "strmov"
15341 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15342 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15343 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15344 (clobber (reg:CC FLAGS_REG))])
15345 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15346 (clobber (reg:CC FLAGS_REG))])]
15349 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15351 /* If .md ever supports :P for Pmode, these can be directly
15352 in the pattern above. */
15353 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15354 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15356 /* Can't use this if the user has appropriated esi or edi. */
15357 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15358 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15360 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15361 operands[2], operands[3],
15362 operands[5], operands[6]));
15366 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15369 (define_expand "strmov_singleop"
15370 [(parallel [(set (match_operand 1 "memory_operand" "")
15371 (match_operand 3 "memory_operand" ""))
15372 (set (match_operand 0 "register_operand" "")
15373 (match_operand 4 "" ""))
15374 (set (match_operand 2 "register_operand" "")
15375 (match_operand 5 "" ""))])]
15377 "ix86_current_function_needs_cld = 1;")
15379 (define_insn "*strmovdi_rex_1"
15380 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15381 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15382 (set (match_operand:DI 0 "register_operand" "=D")
15383 (plus:DI (match_dup 2)
15385 (set (match_operand:DI 1 "register_operand" "=S")
15386 (plus:DI (match_dup 3)
15390 [(set_attr "type" "str")
15391 (set_attr "memory" "both")
15392 (set_attr "mode" "DI")])
15394 (define_insn "*strmovsi_1"
15395 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15396 (mem:SI (match_operand:P 3 "register_operand" "1")))
15397 (set (match_operand:P 0 "register_operand" "=D")
15398 (plus:P (match_dup 2)
15400 (set (match_operand:P 1 "register_operand" "=S")
15401 (plus:P (match_dup 3)
15405 [(set_attr "type" "str")
15406 (set_attr "memory" "both")
15407 (set_attr "mode" "SI")])
15409 (define_insn "*strmovhi_1"
15410 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15411 (mem:HI (match_operand:P 3 "register_operand" "1")))
15412 (set (match_operand:P 0 "register_operand" "=D")
15413 (plus:P (match_dup 2)
15415 (set (match_operand:P 1 "register_operand" "=S")
15416 (plus:P (match_dup 3)
15420 [(set_attr "type" "str")
15421 (set_attr "memory" "both")
15422 (set_attr "mode" "HI")])
15424 (define_insn "*strmovqi_1"
15425 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15426 (mem:QI (match_operand:P 3 "register_operand" "1")))
15427 (set (match_operand:P 0 "register_operand" "=D")
15428 (plus:P (match_dup 2)
15430 (set (match_operand:P 1 "register_operand" "=S")
15431 (plus:P (match_dup 3)
15435 [(set_attr "type" "str")
15436 (set_attr "memory" "both")
15437 (set (attr "prefix_rex")
15439 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15441 (const_string "*")))
15442 (set_attr "mode" "QI")])
15444 (define_expand "rep_mov"
15445 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15446 (set (match_operand 0 "register_operand" "")
15447 (match_operand 5 "" ""))
15448 (set (match_operand 2 "register_operand" "")
15449 (match_operand 6 "" ""))
15450 (set (match_operand 1 "memory_operand" "")
15451 (match_operand 3 "memory_operand" ""))
15452 (use (match_dup 4))])]
15454 "ix86_current_function_needs_cld = 1;")
15456 (define_insn "*rep_movdi_rex64"
15457 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15458 (set (match_operand:DI 0 "register_operand" "=D")
15459 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15461 (match_operand:DI 3 "register_operand" "0")))
15462 (set (match_operand:DI 1 "register_operand" "=S")
15463 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15464 (match_operand:DI 4 "register_operand" "1")))
15465 (set (mem:BLK (match_dup 3))
15466 (mem:BLK (match_dup 4)))
15467 (use (match_dup 5))]
15470 [(set_attr "type" "str")
15471 (set_attr "prefix_rep" "1")
15472 (set_attr "memory" "both")
15473 (set_attr "mode" "DI")])
15475 (define_insn "*rep_movsi"
15476 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15477 (set (match_operand:P 0 "register_operand" "=D")
15478 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15480 (match_operand:P 3 "register_operand" "0")))
15481 (set (match_operand:P 1 "register_operand" "=S")
15482 (plus:P (ashift:P (match_dup 5) (const_int 2))
15483 (match_operand:P 4 "register_operand" "1")))
15484 (set (mem:BLK (match_dup 3))
15485 (mem:BLK (match_dup 4)))
15486 (use (match_dup 5))]
15488 "rep{%;} movs{l|d}"
15489 [(set_attr "type" "str")
15490 (set_attr "prefix_rep" "1")
15491 (set_attr "memory" "both")
15492 (set_attr "mode" "SI")])
15494 (define_insn "*rep_movqi"
15495 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15496 (set (match_operand:P 0 "register_operand" "=D")
15497 (plus:P (match_operand:P 3 "register_operand" "0")
15498 (match_operand:P 5 "register_operand" "2")))
15499 (set (match_operand:P 1 "register_operand" "=S")
15500 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15501 (set (mem:BLK (match_dup 3))
15502 (mem:BLK (match_dup 4)))
15503 (use (match_dup 5))]
15506 [(set_attr "type" "str")
15507 (set_attr "prefix_rep" "1")
15508 (set_attr "memory" "both")
15509 (set_attr "mode" "QI")])
15511 (define_expand "setmem<mode>"
15512 [(use (match_operand:BLK 0 "memory_operand" ""))
15513 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15514 (use (match_operand:QI 2 "nonmemory_operand" ""))
15515 (use (match_operand 3 "const_int_operand" ""))
15516 (use (match_operand:SI 4 "const_int_operand" ""))
15517 (use (match_operand:SI 5 "const_int_operand" ""))]
15520 if (ix86_expand_setmem (operands[0], operands[1],
15521 operands[2], operands[3],
15522 operands[4], operands[5]))
15528 ;; Most CPUs don't like single string operations
15529 ;; Handle this case here to simplify previous expander.
15531 (define_expand "strset"
15532 [(set (match_operand 1 "memory_operand" "")
15533 (match_operand 2 "register_operand" ""))
15534 (parallel [(set (match_operand 0 "register_operand" "")
15536 (clobber (reg:CC FLAGS_REG))])]
15539 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15540 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15542 /* If .md ever supports :P for Pmode, this can be directly
15543 in the pattern above. */
15544 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15545 GEN_INT (GET_MODE_SIZE (GET_MODE
15547 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15549 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15555 (define_expand "strset_singleop"
15556 [(parallel [(set (match_operand 1 "memory_operand" "")
15557 (match_operand 2 "register_operand" ""))
15558 (set (match_operand 0 "register_operand" "")
15559 (match_operand 3 "" ""))])]
15561 "ix86_current_function_needs_cld = 1;")
15563 (define_insn "*strsetdi_rex_1"
15564 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15565 (match_operand:DI 2 "register_operand" "a"))
15566 (set (match_operand:DI 0 "register_operand" "=D")
15567 (plus:DI (match_dup 1)
15571 [(set_attr "type" "str")
15572 (set_attr "memory" "store")
15573 (set_attr "mode" "DI")])
15575 (define_insn "*strsetsi_1"
15576 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15577 (match_operand:SI 2 "register_operand" "a"))
15578 (set (match_operand:P 0 "register_operand" "=D")
15579 (plus:P (match_dup 1)
15583 [(set_attr "type" "str")
15584 (set_attr "memory" "store")
15585 (set_attr "mode" "SI")])
15587 (define_insn "*strsethi_1"
15588 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15589 (match_operand:HI 2 "register_operand" "a"))
15590 (set (match_operand:P 0 "register_operand" "=D")
15591 (plus:P (match_dup 1)
15595 [(set_attr "type" "str")
15596 (set_attr "memory" "store")
15597 (set_attr "mode" "HI")])
15599 (define_insn "*strsetqi_1"
15600 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15601 (match_operand:QI 2 "register_operand" "a"))
15602 (set (match_operand:P 0 "register_operand" "=D")
15603 (plus:P (match_dup 1)
15607 [(set_attr "type" "str")
15608 (set_attr "memory" "store")
15609 (set (attr "prefix_rex")
15611 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15613 (const_string "*")))
15614 (set_attr "mode" "QI")])
15616 (define_expand "rep_stos"
15617 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15618 (set (match_operand 0 "register_operand" "")
15619 (match_operand 4 "" ""))
15620 (set (match_operand 2 "memory_operand" "") (const_int 0))
15621 (use (match_operand 3 "register_operand" ""))
15622 (use (match_dup 1))])]
15624 "ix86_current_function_needs_cld = 1;")
15626 (define_insn "*rep_stosdi_rex64"
15627 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15628 (set (match_operand:DI 0 "register_operand" "=D")
15629 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15631 (match_operand:DI 3 "register_operand" "0")))
15632 (set (mem:BLK (match_dup 3))
15634 (use (match_operand:DI 2 "register_operand" "a"))
15635 (use (match_dup 4))]
15638 [(set_attr "type" "str")
15639 (set_attr "prefix_rep" "1")
15640 (set_attr "memory" "store")
15641 (set_attr "mode" "DI")])
15643 (define_insn "*rep_stossi"
15644 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15645 (set (match_operand:P 0 "register_operand" "=D")
15646 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15648 (match_operand:P 3 "register_operand" "0")))
15649 (set (mem:BLK (match_dup 3))
15651 (use (match_operand:SI 2 "register_operand" "a"))
15652 (use (match_dup 4))]
15654 "rep{%;} stos{l|d}"
15655 [(set_attr "type" "str")
15656 (set_attr "prefix_rep" "1")
15657 (set_attr "memory" "store")
15658 (set_attr "mode" "SI")])
15660 (define_insn "*rep_stosqi"
15661 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15662 (set (match_operand:P 0 "register_operand" "=D")
15663 (plus:P (match_operand:P 3 "register_operand" "0")
15664 (match_operand:P 4 "register_operand" "1")))
15665 (set (mem:BLK (match_dup 3))
15667 (use (match_operand:QI 2 "register_operand" "a"))
15668 (use (match_dup 4))]
15671 [(set_attr "type" "str")
15672 (set_attr "prefix_rep" "1")
15673 (set_attr "memory" "store")
15674 (set (attr "prefix_rex")
15676 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15678 (const_string "*")))
15679 (set_attr "mode" "QI")])
15681 (define_expand "cmpstrnsi"
15682 [(set (match_operand:SI 0 "register_operand" "")
15683 (compare:SI (match_operand:BLK 1 "general_operand" "")
15684 (match_operand:BLK 2 "general_operand" "")))
15685 (use (match_operand 3 "general_operand" ""))
15686 (use (match_operand 4 "immediate_operand" ""))]
15689 rtx addr1, addr2, out, outlow, count, countreg, align;
15691 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15694 /* Can't use this if the user has appropriated esi or edi. */
15695 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15700 out = gen_reg_rtx (SImode);
15702 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15703 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15704 if (addr1 != XEXP (operands[1], 0))
15705 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15706 if (addr2 != XEXP (operands[2], 0))
15707 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15709 count = operands[3];
15710 countreg = ix86_zero_extend_to_Pmode (count);
15712 /* %%% Iff we are testing strict equality, we can use known alignment
15713 to good advantage. This may be possible with combine, particularly
15714 once cc0 is dead. */
15715 align = operands[4];
15717 if (CONST_INT_P (count))
15719 if (INTVAL (count) == 0)
15721 emit_move_insn (operands[0], const0_rtx);
15724 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15725 operands[1], operands[2]));
15729 rtx (*gen_cmp) (rtx, rtx);
15731 gen_cmp = (TARGET_64BIT
15732 ? gen_cmpdi_1 : gen_cmpsi_1);
15734 emit_insn (gen_cmp (countreg, countreg));
15735 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15736 operands[1], operands[2]));
15739 outlow = gen_lowpart (QImode, out);
15740 emit_insn (gen_cmpintqi (outlow));
15741 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15743 if (operands[0] != out)
15744 emit_move_insn (operands[0], out);
15749 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15751 (define_expand "cmpintqi"
15752 [(set (match_dup 1)
15753 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15755 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15756 (parallel [(set (match_operand:QI 0 "register_operand" "")
15757 (minus:QI (match_dup 1)
15759 (clobber (reg:CC FLAGS_REG))])]
15762 operands[1] = gen_reg_rtx (QImode);
15763 operands[2] = gen_reg_rtx (QImode);
15766 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15767 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15769 (define_expand "cmpstrnqi_nz_1"
15770 [(parallel [(set (reg:CC FLAGS_REG)
15771 (compare:CC (match_operand 4 "memory_operand" "")
15772 (match_operand 5 "memory_operand" "")))
15773 (use (match_operand 2 "register_operand" ""))
15774 (use (match_operand:SI 3 "immediate_operand" ""))
15775 (clobber (match_operand 0 "register_operand" ""))
15776 (clobber (match_operand 1 "register_operand" ""))
15777 (clobber (match_dup 2))])]
15779 "ix86_current_function_needs_cld = 1;")
15781 (define_insn "*cmpstrnqi_nz_1"
15782 [(set (reg:CC FLAGS_REG)
15783 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15784 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15785 (use (match_operand:P 6 "register_operand" "2"))
15786 (use (match_operand:SI 3 "immediate_operand" "i"))
15787 (clobber (match_operand:P 0 "register_operand" "=S"))
15788 (clobber (match_operand:P 1 "register_operand" "=D"))
15789 (clobber (match_operand:P 2 "register_operand" "=c"))]
15792 [(set_attr "type" "str")
15793 (set_attr "mode" "QI")
15794 (set (attr "prefix_rex")
15796 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15798 (const_string "*")))
15799 (set_attr "prefix_rep" "1")])
15801 ;; The same, but the count is not known to not be zero.
15803 (define_expand "cmpstrnqi_1"
15804 [(parallel [(set (reg:CC FLAGS_REG)
15805 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15807 (compare:CC (match_operand 4 "memory_operand" "")
15808 (match_operand 5 "memory_operand" ""))
15810 (use (match_operand:SI 3 "immediate_operand" ""))
15811 (use (reg:CC FLAGS_REG))
15812 (clobber (match_operand 0 "register_operand" ""))
15813 (clobber (match_operand 1 "register_operand" ""))
15814 (clobber (match_dup 2))])]
15816 "ix86_current_function_needs_cld = 1;")
15818 (define_insn "*cmpstrnqi_1"
15819 [(set (reg:CC FLAGS_REG)
15820 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15822 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15823 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15825 (use (match_operand:SI 3 "immediate_operand" "i"))
15826 (use (reg:CC FLAGS_REG))
15827 (clobber (match_operand:P 0 "register_operand" "=S"))
15828 (clobber (match_operand:P 1 "register_operand" "=D"))
15829 (clobber (match_operand:P 2 "register_operand" "=c"))]
15832 [(set_attr "type" "str")
15833 (set_attr "mode" "QI")
15834 (set (attr "prefix_rex")
15836 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15838 (const_string "*")))
15839 (set_attr "prefix_rep" "1")])
15841 (define_expand "strlen<mode>"
15842 [(set (match_operand:SWI48x 0 "register_operand" "")
15843 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15844 (match_operand:QI 2 "immediate_operand" "")
15845 (match_operand 3 "immediate_operand" "")]
15849 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15855 (define_expand "strlenqi_1"
15856 [(parallel [(set (match_operand 0 "register_operand" "")
15857 (match_operand 2 "" ""))
15858 (clobber (match_operand 1 "register_operand" ""))
15859 (clobber (reg:CC FLAGS_REG))])]
15861 "ix86_current_function_needs_cld = 1;")
15863 (define_insn "*strlenqi_1"
15864 [(set (match_operand:P 0 "register_operand" "=&c")
15865 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15866 (match_operand:QI 2 "register_operand" "a")
15867 (match_operand:P 3 "immediate_operand" "i")
15868 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15869 (clobber (match_operand:P 1 "register_operand" "=D"))
15870 (clobber (reg:CC FLAGS_REG))]
15873 [(set_attr "type" "str")
15874 (set_attr "mode" "QI")
15875 (set (attr "prefix_rex")
15877 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15879 (const_string "*")))
15880 (set_attr "prefix_rep" "1")])
15882 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15883 ;; handled in combine, but it is not currently up to the task.
15884 ;; When used for their truth value, the cmpstrn* expanders generate
15893 ;; The intermediate three instructions are unnecessary.
15895 ;; This one handles cmpstrn*_nz_1...
15898 (set (reg:CC FLAGS_REG)
15899 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15900 (mem:BLK (match_operand 5 "register_operand" ""))))
15901 (use (match_operand 6 "register_operand" ""))
15902 (use (match_operand:SI 3 "immediate_operand" ""))
15903 (clobber (match_operand 0 "register_operand" ""))
15904 (clobber (match_operand 1 "register_operand" ""))
15905 (clobber (match_operand 2 "register_operand" ""))])
15906 (set (match_operand:QI 7 "register_operand" "")
15907 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15908 (set (match_operand:QI 8 "register_operand" "")
15909 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15910 (set (reg FLAGS_REG)
15911 (compare (match_dup 7) (match_dup 8)))
15913 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15915 (set (reg:CC FLAGS_REG)
15916 (compare:CC (mem:BLK (match_dup 4))
15917 (mem:BLK (match_dup 5))))
15918 (use (match_dup 6))
15919 (use (match_dup 3))
15920 (clobber (match_dup 0))
15921 (clobber (match_dup 1))
15922 (clobber (match_dup 2))])])
15924 ;; ...and this one handles cmpstrn*_1.
15927 (set (reg:CC FLAGS_REG)
15928 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15930 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15931 (mem:BLK (match_operand 5 "register_operand" "")))
15933 (use (match_operand:SI 3 "immediate_operand" ""))
15934 (use (reg:CC FLAGS_REG))
15935 (clobber (match_operand 0 "register_operand" ""))
15936 (clobber (match_operand 1 "register_operand" ""))
15937 (clobber (match_operand 2 "register_operand" ""))])
15938 (set (match_operand:QI 7 "register_operand" "")
15939 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15940 (set (match_operand:QI 8 "register_operand" "")
15941 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15942 (set (reg FLAGS_REG)
15943 (compare (match_dup 7) (match_dup 8)))
15945 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15947 (set (reg:CC FLAGS_REG)
15948 (if_then_else:CC (ne (match_dup 6)
15950 (compare:CC (mem:BLK (match_dup 4))
15951 (mem:BLK (match_dup 5)))
15953 (use (match_dup 3))
15954 (use (reg:CC FLAGS_REG))
15955 (clobber (match_dup 0))
15956 (clobber (match_dup 1))
15957 (clobber (match_dup 2))])])
15959 ;; Conditional move instructions.
15961 (define_expand "mov<mode>cc"
15962 [(set (match_operand:SWIM 0 "register_operand" "")
15963 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15964 (match_operand:SWIM 2 "general_operand" "")
15965 (match_operand:SWIM 3 "general_operand" "")))]
15967 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15969 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15970 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15971 ;; So just document what we're doing explicitly.
15973 (define_expand "x86_mov<mode>cc_0_m1"
15975 [(set (match_operand:SWI48 0 "register_operand" "")
15976 (if_then_else:SWI48
15977 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15978 [(match_operand 1 "flags_reg_operand" "")
15982 (clobber (reg:CC FLAGS_REG))])])
15984 (define_insn "*x86_mov<mode>cc_0_m1"
15985 [(set (match_operand:SWI48 0 "register_operand" "=r")
15986 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15987 [(reg FLAGS_REG) (const_int 0)])
15990 (clobber (reg:CC FLAGS_REG))]
15992 "sbb{<imodesuffix>}\t%0, %0"
15993 ; Since we don't have the proper number of operands for an alu insn,
15994 ; fill in all the blanks.
15995 [(set_attr "type" "alu")
15996 (set_attr "use_carry" "1")
15997 (set_attr "pent_pair" "pu")
15998 (set_attr "memory" "none")
15999 (set_attr "imm_disp" "false")
16000 (set_attr "mode" "<MODE>")
16001 (set_attr "length_immediate" "0")])
16003 (define_insn "*x86_mov<mode>cc_0_m1_se"
16004 [(set (match_operand:SWI48 0 "register_operand" "=r")
16005 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16006 [(reg FLAGS_REG) (const_int 0)])
16009 (clobber (reg:CC FLAGS_REG))]
16011 "sbb{<imodesuffix>}\t%0, %0"
16012 [(set_attr "type" "alu")
16013 (set_attr "use_carry" "1")
16014 (set_attr "pent_pair" "pu")
16015 (set_attr "memory" "none")
16016 (set_attr "imm_disp" "false")
16017 (set_attr "mode" "<MODE>")
16018 (set_attr "length_immediate" "0")])
16020 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16021 [(set (match_operand:SWI48 0 "register_operand" "=r")
16022 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16023 [(reg FLAGS_REG) (const_int 0)])))]
16025 "sbb{<imodesuffix>}\t%0, %0"
16026 [(set_attr "type" "alu")
16027 (set_attr "use_carry" "1")
16028 (set_attr "pent_pair" "pu")
16029 (set_attr "memory" "none")
16030 (set_attr "imm_disp" "false")
16031 (set_attr "mode" "<MODE>")
16032 (set_attr "length_immediate" "0")])
16034 (define_insn "*mov<mode>cc_noc"
16035 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16036 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16037 [(reg FLAGS_REG) (const_int 0)])
16038 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16039 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16040 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16042 cmov%O2%C1\t{%2, %0|%0, %2}
16043 cmov%O2%c1\t{%3, %0|%0, %3}"
16044 [(set_attr "type" "icmov")
16045 (set_attr "mode" "<MODE>")])
16047 (define_insn_and_split "*movqicc_noc"
16048 [(set (match_operand:QI 0 "register_operand" "=r,r")
16049 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16050 [(match_operand 4 "flags_reg_operand" "")
16052 (match_operand:QI 2 "register_operand" "r,0")
16053 (match_operand:QI 3 "register_operand" "0,r")))]
16054 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16056 "&& reload_completed"
16057 [(set (match_dup 0)
16058 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16061 "operands[0] = gen_lowpart (SImode, operands[0]);
16062 operands[2] = gen_lowpart (SImode, operands[2]);
16063 operands[3] = gen_lowpart (SImode, operands[3]);"
16064 [(set_attr "type" "icmov")
16065 (set_attr "mode" "SI")])
16067 (define_expand "mov<mode>cc"
16068 [(set (match_operand:X87MODEF 0 "register_operand" "")
16069 (if_then_else:X87MODEF
16070 (match_operand 1 "ix86_fp_comparison_operator" "")
16071 (match_operand:X87MODEF 2 "register_operand" "")
16072 (match_operand:X87MODEF 3 "register_operand" "")))]
16073 "(TARGET_80387 && TARGET_CMOVE)
16074 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16075 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16077 (define_insn "*movxfcc_1"
16078 [(set (match_operand:XF 0 "register_operand" "=f,f")
16079 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16080 [(reg FLAGS_REG) (const_int 0)])
16081 (match_operand:XF 2 "register_operand" "f,0")
16082 (match_operand:XF 3 "register_operand" "0,f")))]
16083 "TARGET_80387 && TARGET_CMOVE"
16085 fcmov%F1\t{%2, %0|%0, %2}
16086 fcmov%f1\t{%3, %0|%0, %3}"
16087 [(set_attr "type" "fcmov")
16088 (set_attr "mode" "XF")])
16090 (define_insn "*movdfcc_1_rex64"
16091 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16092 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16093 [(reg FLAGS_REG) (const_int 0)])
16094 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16095 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16096 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16097 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16099 fcmov%F1\t{%2, %0|%0, %2}
16100 fcmov%f1\t{%3, %0|%0, %3}
16101 cmov%O2%C1\t{%2, %0|%0, %2}
16102 cmov%O2%c1\t{%3, %0|%0, %3}"
16103 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16104 (set_attr "mode" "DF,DF,DI,DI")])
16106 (define_insn "*movdfcc_1"
16107 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16108 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16109 [(reg FLAGS_REG) (const_int 0)])
16110 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16111 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16112 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16113 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16115 fcmov%F1\t{%2, %0|%0, %2}
16116 fcmov%f1\t{%3, %0|%0, %3}
16119 [(set_attr "type" "fcmov,fcmov,multi,multi")
16120 (set_attr "mode" "DF,DF,DI,DI")])
16123 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16124 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16125 [(match_operand 4 "flags_reg_operand" "")
16127 (match_operand:DF 2 "nonimmediate_operand" "")
16128 (match_operand:DF 3 "nonimmediate_operand" "")))]
16129 "!TARGET_64BIT && reload_completed"
16130 [(set (match_dup 2)
16131 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16135 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16139 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16140 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16143 (define_insn "*movsfcc_1_387"
16144 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16145 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16146 [(reg FLAGS_REG) (const_int 0)])
16147 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16148 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16149 "TARGET_80387 && TARGET_CMOVE
16150 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16152 fcmov%F1\t{%2, %0|%0, %2}
16153 fcmov%f1\t{%3, %0|%0, %3}
16154 cmov%O2%C1\t{%2, %0|%0, %2}
16155 cmov%O2%c1\t{%3, %0|%0, %3}"
16156 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16157 (set_attr "mode" "SF,SF,SI,SI")])
16159 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16160 ;; the scalar versions to have only XMM registers as operands.
16162 ;; XOP conditional move
16163 (define_insn "*xop_pcmov_<mode>"
16164 [(set (match_operand:MODEF 0 "register_operand" "=x")
16165 (if_then_else:MODEF
16166 (match_operand:MODEF 1 "register_operand" "x")
16167 (match_operand:MODEF 2 "register_operand" "x")
16168 (match_operand:MODEF 3 "register_operand" "x")))]
16170 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16171 [(set_attr "type" "sse4arg")])
16173 ;; These versions of the min/max patterns are intentionally ignorant of
16174 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16175 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16176 ;; are undefined in this condition, we're certain this is correct.
16178 (define_insn "<code><mode>3"
16179 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16181 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16182 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16183 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16185 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16186 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16187 [(set_attr "isa" "noavx,avx")
16188 (set_attr "prefix" "orig,vex")
16189 (set_attr "type" "sseadd")
16190 (set_attr "mode" "<MODE>")])
16192 ;; These versions of the min/max patterns implement exactly the operations
16193 ;; min = (op1 < op2 ? op1 : op2)
16194 ;; max = (!(op1 < op2) ? op1 : op2)
16195 ;; Their operands are not commutative, and thus they may be used in the
16196 ;; presence of -0.0 and NaN.
16198 (define_insn "*ieee_smin<mode>3"
16199 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16201 [(match_operand:MODEF 1 "register_operand" "0,x")
16202 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16204 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16206 min<ssemodesuffix>\t{%2, %0|%0, %2}
16207 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16208 [(set_attr "isa" "noavx,avx")
16209 (set_attr "prefix" "orig,vex")
16210 (set_attr "type" "sseadd")
16211 (set_attr "mode" "<MODE>")])
16213 (define_insn "*ieee_smax<mode>3"
16214 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16216 [(match_operand:MODEF 1 "register_operand" "0,x")
16217 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16219 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16221 max<ssemodesuffix>\t{%2, %0|%0, %2}
16222 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16223 [(set_attr "isa" "noavx,avx")
16224 (set_attr "prefix" "orig,vex")
16225 (set_attr "type" "sseadd")
16226 (set_attr "mode" "<MODE>")])
16228 ;; Make two stack loads independent:
16230 ;; fld %st(0) -> fld bb
16231 ;; fmul bb fmul %st(1), %st
16233 ;; Actually we only match the last two instructions for simplicity.
16235 [(set (match_operand 0 "fp_register_operand" "")
16236 (match_operand 1 "fp_register_operand" ""))
16238 (match_operator 2 "binary_fp_operator"
16240 (match_operand 3 "memory_operand" "")]))]
16241 "REGNO (operands[0]) != REGNO (operands[1])"
16242 [(set (match_dup 0) (match_dup 3))
16243 (set (match_dup 0) (match_dup 4))]
16245 ;; The % modifier is not operational anymore in peephole2's, so we have to
16246 ;; swap the operands manually in the case of addition and multiplication.
16247 "if (COMMUTATIVE_ARITH_P (operands[2]))
16248 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16249 GET_MODE (operands[2]),
16250 operands[0], operands[1]);
16252 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16253 GET_MODE (operands[2]),
16254 operands[1], operands[0]);")
16256 ;; Conditional addition patterns
16257 (define_expand "add<mode>cc"
16258 [(match_operand:SWI 0 "register_operand" "")
16259 (match_operand 1 "ordered_comparison_operator" "")
16260 (match_operand:SWI 2 "register_operand" "")
16261 (match_operand:SWI 3 "const_int_operand" "")]
16263 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16265 ;; Misc patterns (?)
16267 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16268 ;; Otherwise there will be nothing to keep
16270 ;; [(set (reg ebp) (reg esp))]
16271 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16272 ;; (clobber (eflags)]
16273 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16275 ;; in proper program order.
16277 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16278 [(set (match_operand:P 0 "register_operand" "=r,r")
16279 (plus:P (match_operand:P 1 "register_operand" "0,r")
16280 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16281 (clobber (reg:CC FLAGS_REG))
16282 (clobber (mem:BLK (scratch)))]
16285 switch (get_attr_type (insn))
16288 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16291 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16292 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16293 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16295 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16298 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16299 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16302 [(set (attr "type")
16303 (cond [(and (eq_attr "alternative" "0")
16304 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16305 (const_string "alu")
16306 (match_operand:<MODE> 2 "const0_operand" "")
16307 (const_string "imov")
16309 (const_string "lea")))
16310 (set (attr "length_immediate")
16311 (cond [(eq_attr "type" "imov")
16313 (and (eq_attr "type" "alu")
16314 (match_operand 2 "const128_operand" ""))
16317 (const_string "*")))
16318 (set_attr "mode" "<MODE>")])
16320 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16321 [(set (match_operand:P 0 "register_operand" "=r")
16322 (minus:P (match_operand:P 1 "register_operand" "0")
16323 (match_operand:P 2 "register_operand" "r")))
16324 (clobber (reg:CC FLAGS_REG))
16325 (clobber (mem:BLK (scratch)))]
16327 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16328 [(set_attr "type" "alu")
16329 (set_attr "mode" "<MODE>")])
16331 (define_insn "allocate_stack_worker_probe_<mode>"
16332 [(set (match_operand:P 0 "register_operand" "=a")
16333 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16334 UNSPECV_STACK_PROBE))
16335 (clobber (reg:CC FLAGS_REG))]
16336 "ix86_target_stack_probe ()"
16337 "call\t___chkstk_ms"
16338 [(set_attr "type" "multi")
16339 (set_attr "length" "5")])
16341 (define_expand "allocate_stack"
16342 [(match_operand 0 "register_operand" "")
16343 (match_operand 1 "general_operand" "")]
16344 "ix86_target_stack_probe ()"
16348 #ifndef CHECK_STACK_LIMIT
16349 #define CHECK_STACK_LIMIT 0
16352 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16353 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16355 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16356 stack_pointer_rtx, 0, OPTAB_DIRECT);
16357 if (x != stack_pointer_rtx)
16358 emit_move_insn (stack_pointer_rtx, x);
16362 x = copy_to_mode_reg (Pmode, operands[1]);
16364 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16366 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16367 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16368 stack_pointer_rtx, 0, OPTAB_DIRECT);
16369 if (x != stack_pointer_rtx)
16370 emit_move_insn (stack_pointer_rtx, x);
16373 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16377 ;; Use IOR for stack probes, this is shorter.
16378 (define_expand "probe_stack"
16379 [(match_operand 0 "memory_operand" "")]
16382 rtx (*gen_ior3) (rtx, rtx, rtx);
16384 gen_ior3 = (GET_MODE (operands[0]) == DImode
16385 ? gen_iordi3 : gen_iorsi3);
16387 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16391 (define_insn "adjust_stack_and_probe<mode>"
16392 [(set (match_operand:P 0 "register_operand" "=r")
16393 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16394 UNSPECV_PROBE_STACK_RANGE))
16395 (set (reg:P SP_REG)
16396 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16397 (clobber (reg:CC FLAGS_REG))
16398 (clobber (mem:BLK (scratch)))]
16400 "* return output_adjust_stack_and_probe (operands[0]);"
16401 [(set_attr "type" "multi")])
16403 (define_insn "probe_stack_range<mode>"
16404 [(set (match_operand:P 0 "register_operand" "=r")
16405 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16406 (match_operand:P 2 "const_int_operand" "n")]
16407 UNSPECV_PROBE_STACK_RANGE))
16408 (clobber (reg:CC FLAGS_REG))]
16410 "* return output_probe_stack_range (operands[0], operands[2]);"
16411 [(set_attr "type" "multi")])
16413 (define_expand "builtin_setjmp_receiver"
16414 [(label_ref (match_operand 0 "" ""))]
16415 "!TARGET_64BIT && flag_pic"
16421 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16422 rtx label_rtx = gen_label_rtx ();
16423 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16424 xops[0] = xops[1] = picreg;
16425 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16426 ix86_expand_binary_operator (MINUS, SImode, xops);
16430 emit_insn (gen_set_got (pic_offset_table_rtx));
16434 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16437 [(set (match_operand 0 "register_operand" "")
16438 (match_operator 3 "promotable_binary_operator"
16439 [(match_operand 1 "register_operand" "")
16440 (match_operand 2 "aligned_operand" "")]))
16441 (clobber (reg:CC FLAGS_REG))]
16442 "! TARGET_PARTIAL_REG_STALL && reload_completed
16443 && ((GET_MODE (operands[0]) == HImode
16444 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16445 /* ??? next two lines just !satisfies_constraint_K (...) */
16446 || !CONST_INT_P (operands[2])
16447 || satisfies_constraint_K (operands[2])))
16448 || (GET_MODE (operands[0]) == QImode
16449 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16450 [(parallel [(set (match_dup 0)
16451 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16452 (clobber (reg:CC FLAGS_REG))])]
16453 "operands[0] = gen_lowpart (SImode, operands[0]);
16454 operands[1] = gen_lowpart (SImode, operands[1]);
16455 if (GET_CODE (operands[3]) != ASHIFT)
16456 operands[2] = gen_lowpart (SImode, operands[2]);
16457 PUT_MODE (operands[3], SImode);")
16459 ; Promote the QImode tests, as i386 has encoding of the AND
16460 ; instruction with 32-bit sign-extended immediate and thus the
16461 ; instruction size is unchanged, except in the %eax case for
16462 ; which it is increased by one byte, hence the ! optimize_size.
16464 [(set (match_operand 0 "flags_reg_operand" "")
16465 (match_operator 2 "compare_operator"
16466 [(and (match_operand 3 "aligned_operand" "")
16467 (match_operand 4 "const_int_operand" ""))
16469 (set (match_operand 1 "register_operand" "")
16470 (and (match_dup 3) (match_dup 4)))]
16471 "! TARGET_PARTIAL_REG_STALL && reload_completed
16472 && optimize_insn_for_speed_p ()
16473 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16474 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16475 /* Ensure that the operand will remain sign-extended immediate. */
16476 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16477 [(parallel [(set (match_dup 0)
16478 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16481 (and:SI (match_dup 3) (match_dup 4)))])]
16484 = gen_int_mode (INTVAL (operands[4])
16485 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16486 operands[1] = gen_lowpart (SImode, operands[1]);
16487 operands[3] = gen_lowpart (SImode, operands[3]);
16490 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16491 ; the TEST instruction with 32-bit sign-extended immediate and thus
16492 ; the instruction size would at least double, which is not what we
16493 ; want even with ! optimize_size.
16495 [(set (match_operand 0 "flags_reg_operand" "")
16496 (match_operator 1 "compare_operator"
16497 [(and (match_operand:HI 2 "aligned_operand" "")
16498 (match_operand:HI 3 "const_int_operand" ""))
16500 "! TARGET_PARTIAL_REG_STALL && reload_completed
16501 && ! TARGET_FAST_PREFIX
16502 && optimize_insn_for_speed_p ()
16503 /* Ensure that the operand will remain sign-extended immediate. */
16504 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16505 [(set (match_dup 0)
16506 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16510 = gen_int_mode (INTVAL (operands[3])
16511 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16512 operands[2] = gen_lowpart (SImode, operands[2]);
16516 [(set (match_operand 0 "register_operand" "")
16517 (neg (match_operand 1 "register_operand" "")))
16518 (clobber (reg:CC FLAGS_REG))]
16519 "! TARGET_PARTIAL_REG_STALL && reload_completed
16520 && (GET_MODE (operands[0]) == HImode
16521 || (GET_MODE (operands[0]) == QImode
16522 && (TARGET_PROMOTE_QImode
16523 || optimize_insn_for_size_p ())))"
16524 [(parallel [(set (match_dup 0)
16525 (neg:SI (match_dup 1)))
16526 (clobber (reg:CC FLAGS_REG))])]
16527 "operands[0] = gen_lowpart (SImode, operands[0]);
16528 operands[1] = gen_lowpart (SImode, operands[1]);")
16531 [(set (match_operand 0 "register_operand" "")
16532 (not (match_operand 1 "register_operand" "")))]
16533 "! TARGET_PARTIAL_REG_STALL && reload_completed
16534 && (GET_MODE (operands[0]) == HImode
16535 || (GET_MODE (operands[0]) == QImode
16536 && (TARGET_PROMOTE_QImode
16537 || optimize_insn_for_size_p ())))"
16538 [(set (match_dup 0)
16539 (not:SI (match_dup 1)))]
16540 "operands[0] = gen_lowpart (SImode, operands[0]);
16541 operands[1] = gen_lowpart (SImode, operands[1]);")
16544 [(set (match_operand 0 "register_operand" "")
16545 (if_then_else (match_operator 1 "ordered_comparison_operator"
16546 [(reg FLAGS_REG) (const_int 0)])
16547 (match_operand 2 "register_operand" "")
16548 (match_operand 3 "register_operand" "")))]
16549 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16550 && (GET_MODE (operands[0]) == HImode
16551 || (GET_MODE (operands[0]) == QImode
16552 && (TARGET_PROMOTE_QImode
16553 || optimize_insn_for_size_p ())))"
16554 [(set (match_dup 0)
16555 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16556 "operands[0] = gen_lowpart (SImode, operands[0]);
16557 operands[2] = gen_lowpart (SImode, operands[2]);
16558 operands[3] = gen_lowpart (SImode, operands[3]);")
16560 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16561 ;; transform a complex memory operation into two memory to register operations.
16563 ;; Don't push memory operands
16565 [(set (match_operand:SWI 0 "push_operand" "")
16566 (match_operand:SWI 1 "memory_operand" ""))
16567 (match_scratch:SWI 2 "<r>")]
16568 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16569 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16570 [(set (match_dup 2) (match_dup 1))
16571 (set (match_dup 0) (match_dup 2))])
16573 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16576 [(set (match_operand:SF 0 "push_operand" "")
16577 (match_operand:SF 1 "memory_operand" ""))
16578 (match_scratch:SF 2 "r")]
16579 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16580 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16581 [(set (match_dup 2) (match_dup 1))
16582 (set (match_dup 0) (match_dup 2))])
16584 ;; Don't move an immediate directly to memory when the instruction
16587 [(match_scratch:SWI124 1 "<r>")
16588 (set (match_operand:SWI124 0 "memory_operand" "")
16590 "optimize_insn_for_speed_p ()
16591 && !TARGET_USE_MOV0
16592 && TARGET_SPLIT_LONG_MOVES
16593 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16594 && peep2_regno_dead_p (0, FLAGS_REG)"
16595 [(parallel [(set (match_dup 2) (const_int 0))
16596 (clobber (reg:CC FLAGS_REG))])
16597 (set (match_dup 0) (match_dup 1))]
16598 "operands[2] = gen_lowpart (SImode, operands[1]);")
16601 [(match_scratch:SWI124 2 "<r>")
16602 (set (match_operand:SWI124 0 "memory_operand" "")
16603 (match_operand:SWI124 1 "immediate_operand" ""))]
16604 "optimize_insn_for_speed_p ()
16605 && TARGET_SPLIT_LONG_MOVES
16606 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16607 [(set (match_dup 2) (match_dup 1))
16608 (set (match_dup 0) (match_dup 2))])
16610 ;; Don't compare memory with zero, load and use a test instead.
16612 [(set (match_operand 0 "flags_reg_operand" "")
16613 (match_operator 1 "compare_operator"
16614 [(match_operand:SI 2 "memory_operand" "")
16616 (match_scratch:SI 3 "r")]
16617 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16618 [(set (match_dup 3) (match_dup 2))
16619 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16621 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16622 ;; Don't split NOTs with a displacement operand, because resulting XOR
16623 ;; will not be pairable anyway.
16625 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16626 ;; represented using a modRM byte. The XOR replacement is long decoded,
16627 ;; so this split helps here as well.
16629 ;; Note: Can't do this as a regular split because we can't get proper
16630 ;; lifetime information then.
16633 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16634 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16635 "optimize_insn_for_speed_p ()
16636 && ((TARGET_NOT_UNPAIRABLE
16637 && (!MEM_P (operands[0])
16638 || !memory_displacement_operand (operands[0], <MODE>mode)))
16639 || (TARGET_NOT_VECTORMODE
16640 && long_memory_operand (operands[0], <MODE>mode)))
16641 && peep2_regno_dead_p (0, FLAGS_REG)"
16642 [(parallel [(set (match_dup 0)
16643 (xor:SWI124 (match_dup 1) (const_int -1)))
16644 (clobber (reg:CC FLAGS_REG))])])
16646 ;; Non pairable "test imm, reg" instructions can be translated to
16647 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16648 ;; byte opcode instead of two, have a short form for byte operands),
16649 ;; so do it for other CPUs as well. Given that the value was dead,
16650 ;; this should not create any new dependencies. Pass on the sub-word
16651 ;; versions if we're concerned about partial register stalls.
16654 [(set (match_operand 0 "flags_reg_operand" "")
16655 (match_operator 1 "compare_operator"
16656 [(and:SI (match_operand:SI 2 "register_operand" "")
16657 (match_operand:SI 3 "immediate_operand" ""))
16659 "ix86_match_ccmode (insn, CCNOmode)
16660 && (true_regnum (operands[2]) != AX_REG
16661 || satisfies_constraint_K (operands[3]))
16662 && peep2_reg_dead_p (1, operands[2])"
16664 [(set (match_dup 0)
16665 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16668 (and:SI (match_dup 2) (match_dup 3)))])])
16670 ;; We don't need to handle HImode case, because it will be promoted to SImode
16671 ;; on ! TARGET_PARTIAL_REG_STALL
16674 [(set (match_operand 0 "flags_reg_operand" "")
16675 (match_operator 1 "compare_operator"
16676 [(and:QI (match_operand:QI 2 "register_operand" "")
16677 (match_operand:QI 3 "immediate_operand" ""))
16679 "! TARGET_PARTIAL_REG_STALL
16680 && ix86_match_ccmode (insn, CCNOmode)
16681 && true_regnum (operands[2]) != AX_REG
16682 && peep2_reg_dead_p (1, operands[2])"
16684 [(set (match_dup 0)
16685 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16688 (and:QI (match_dup 2) (match_dup 3)))])])
16691 [(set (match_operand 0 "flags_reg_operand" "")
16692 (match_operator 1 "compare_operator"
16695 (match_operand 2 "ext_register_operand" "")
16698 (match_operand 3 "const_int_operand" ""))
16700 "! TARGET_PARTIAL_REG_STALL
16701 && ix86_match_ccmode (insn, CCNOmode)
16702 && true_regnum (operands[2]) != AX_REG
16703 && peep2_reg_dead_p (1, operands[2])"
16704 [(parallel [(set (match_dup 0)
16713 (set (zero_extract:SI (match_dup 2)
16721 (match_dup 3)))])])
16723 ;; Don't do logical operations with memory inputs.
16725 [(match_scratch:SI 2 "r")
16726 (parallel [(set (match_operand:SI 0 "register_operand" "")
16727 (match_operator:SI 3 "arith_or_logical_operator"
16729 (match_operand:SI 1 "memory_operand" "")]))
16730 (clobber (reg:CC FLAGS_REG))])]
16731 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16732 [(set (match_dup 2) (match_dup 1))
16733 (parallel [(set (match_dup 0)
16734 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16735 (clobber (reg:CC FLAGS_REG))])])
16738 [(match_scratch:SI 2 "r")
16739 (parallel [(set (match_operand:SI 0 "register_operand" "")
16740 (match_operator:SI 3 "arith_or_logical_operator"
16741 [(match_operand:SI 1 "memory_operand" "")
16743 (clobber (reg:CC FLAGS_REG))])]
16744 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16745 [(set (match_dup 2) (match_dup 1))
16746 (parallel [(set (match_dup 0)
16747 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16748 (clobber (reg:CC FLAGS_REG))])])
16750 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16751 ;; refers to the destination of the load!
16754 [(set (match_operand:SI 0 "register_operand" "")
16755 (match_operand:SI 1 "register_operand" ""))
16756 (parallel [(set (match_dup 0)
16757 (match_operator:SI 3 "commutative_operator"
16759 (match_operand:SI 2 "memory_operand" "")]))
16760 (clobber (reg:CC FLAGS_REG))])]
16761 "REGNO (operands[0]) != REGNO (operands[1])
16762 && GENERAL_REGNO_P (REGNO (operands[0]))
16763 && GENERAL_REGNO_P (REGNO (operands[1]))"
16764 [(set (match_dup 0) (match_dup 4))
16765 (parallel [(set (match_dup 0)
16766 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16767 (clobber (reg:CC FLAGS_REG))])]
16768 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16771 [(set (match_operand 0 "register_operand" "")
16772 (match_operand 1 "register_operand" ""))
16774 (match_operator 3 "commutative_operator"
16776 (match_operand 2 "memory_operand" "")]))]
16777 "REGNO (operands[0]) != REGNO (operands[1])
16778 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16779 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16780 [(set (match_dup 0) (match_dup 2))
16782 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16784 ; Don't do logical operations with memory outputs
16786 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16787 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16788 ; the same decoder scheduling characteristics as the original.
16791 [(match_scratch:SI 2 "r")
16792 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16793 (match_operator:SI 3 "arith_or_logical_operator"
16795 (match_operand:SI 1 "nonmemory_operand" "")]))
16796 (clobber (reg:CC FLAGS_REG))])]
16797 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16798 /* Do not split stack checking probes. */
16799 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16800 [(set (match_dup 2) (match_dup 0))
16801 (parallel [(set (match_dup 2)
16802 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16803 (clobber (reg:CC FLAGS_REG))])
16804 (set (match_dup 0) (match_dup 2))])
16807 [(match_scratch:SI 2 "r")
16808 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16809 (match_operator:SI 3 "arith_or_logical_operator"
16810 [(match_operand:SI 1 "nonmemory_operand" "")
16812 (clobber (reg:CC FLAGS_REG))])]
16813 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16814 /* Do not split stack checking probes. */
16815 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16816 [(set (match_dup 2) (match_dup 0))
16817 (parallel [(set (match_dup 2)
16818 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16819 (clobber (reg:CC FLAGS_REG))])
16820 (set (match_dup 0) (match_dup 2))])
16822 ;; Attempt to always use XOR for zeroing registers.
16824 [(set (match_operand 0 "register_operand" "")
16825 (match_operand 1 "const0_operand" ""))]
16826 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16827 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16828 && GENERAL_REG_P (operands[0])
16829 && peep2_regno_dead_p (0, FLAGS_REG)"
16830 [(parallel [(set (match_dup 0) (const_int 0))
16831 (clobber (reg:CC FLAGS_REG))])]
16832 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16835 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16837 "(GET_MODE (operands[0]) == QImode
16838 || GET_MODE (operands[0]) == HImode)
16839 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16840 && peep2_regno_dead_p (0, FLAGS_REG)"
16841 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16842 (clobber (reg:CC FLAGS_REG))])])
16844 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16846 [(set (match_operand:SWI248 0 "register_operand" "")
16848 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16849 && peep2_regno_dead_p (0, FLAGS_REG)"
16850 [(parallel [(set (match_dup 0) (const_int -1))
16851 (clobber (reg:CC FLAGS_REG))])]
16853 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16854 operands[0] = gen_lowpart (SImode, operands[0]);
16857 ;; Attempt to convert simple lea to add/shift.
16858 ;; These can be created by move expanders.
16861 [(set (match_operand:SWI48 0 "register_operand" "")
16862 (plus:SWI48 (match_dup 0)
16863 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16864 "peep2_regno_dead_p (0, FLAGS_REG)"
16865 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16866 (clobber (reg:CC FLAGS_REG))])])
16869 [(set (match_operand:SI 0 "register_operand" "")
16870 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16871 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16873 && peep2_regno_dead_p (0, FLAGS_REG)
16874 && REGNO (operands[0]) == REGNO (operands[1])"
16875 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16876 (clobber (reg:CC FLAGS_REG))])]
16877 "operands[2] = gen_lowpart (SImode, operands[2]);")
16880 [(set (match_operand:SWI48 0 "register_operand" "")
16881 (mult:SWI48 (match_dup 0)
16882 (match_operand:SWI48 1 "const_int_operand" "")))]
16883 "exact_log2 (INTVAL (operands[1])) >= 0
16884 && peep2_regno_dead_p (0, FLAGS_REG)"
16885 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16886 (clobber (reg:CC FLAGS_REG))])]
16887 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16890 [(set (match_operand:SI 0 "register_operand" "")
16891 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16892 (match_operand:DI 2 "const_int_operand" "")) 0))]
16894 && exact_log2 (INTVAL (operands[2])) >= 0
16895 && REGNO (operands[0]) == REGNO (operands[1])
16896 && peep2_regno_dead_p (0, FLAGS_REG)"
16897 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16898 (clobber (reg:CC FLAGS_REG))])]
16899 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16901 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16902 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16903 ;; On many CPUs it is also faster, since special hardware to avoid esp
16904 ;; dependencies is present.
16906 ;; While some of these conversions may be done using splitters, we use
16907 ;; peepholes in order to allow combine_stack_adjustments pass to see
16908 ;; nonobfuscated RTL.
16910 ;; Convert prologue esp subtractions to push.
16911 ;; We need register to push. In order to keep verify_flow_info happy we have
16913 ;; - use scratch and clobber it in order to avoid dependencies
16914 ;; - use already live register
16915 ;; We can't use the second way right now, since there is no reliable way how to
16916 ;; verify that given register is live. First choice will also most likely in
16917 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16918 ;; call clobbered registers are dead. We may want to use base pointer as an
16919 ;; alternative when no register is available later.
16922 [(match_scratch:P 1 "r")
16923 (parallel [(set (reg:P SP_REG)
16924 (plus:P (reg:P SP_REG)
16925 (match_operand:P 0 "const_int_operand" "")))
16926 (clobber (reg:CC FLAGS_REG))
16927 (clobber (mem:BLK (scratch)))])]
16928 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16929 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16930 [(clobber (match_dup 1))
16931 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16932 (clobber (mem:BLK (scratch)))])])
16935 [(match_scratch:P 1 "r")
16936 (parallel [(set (reg:P SP_REG)
16937 (plus:P (reg:P SP_REG)
16938 (match_operand:P 0 "const_int_operand" "")))
16939 (clobber (reg:CC FLAGS_REG))
16940 (clobber (mem:BLK (scratch)))])]
16941 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16942 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16943 [(clobber (match_dup 1))
16944 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16945 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16946 (clobber (mem:BLK (scratch)))])])
16948 ;; Convert esp subtractions to push.
16950 [(match_scratch:P 1 "r")
16951 (parallel [(set (reg:P SP_REG)
16952 (plus:P (reg:P SP_REG)
16953 (match_operand:P 0 "const_int_operand" "")))
16954 (clobber (reg:CC FLAGS_REG))])]
16955 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16956 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16957 [(clobber (match_dup 1))
16958 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16961 [(match_scratch:P 1 "r")
16962 (parallel [(set (reg:P SP_REG)
16963 (plus:P (reg:P SP_REG)
16964 (match_operand:P 0 "const_int_operand" "")))
16965 (clobber (reg:CC FLAGS_REG))])]
16966 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16967 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16968 [(clobber (match_dup 1))
16969 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16970 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16972 ;; Convert epilogue deallocator to pop.
16974 [(match_scratch:P 1 "r")
16975 (parallel [(set (reg:P SP_REG)
16976 (plus:P (reg:P SP_REG)
16977 (match_operand:P 0 "const_int_operand" "")))
16978 (clobber (reg:CC FLAGS_REG))
16979 (clobber (mem:BLK (scratch)))])]
16980 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16981 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16982 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16983 (clobber (mem:BLK (scratch)))])])
16985 ;; Two pops case is tricky, since pop causes dependency
16986 ;; on destination register. We use two registers if available.
16988 [(match_scratch:P 1 "r")
16989 (match_scratch:P 2 "r")
16990 (parallel [(set (reg:P SP_REG)
16991 (plus:P (reg:P SP_REG)
16992 (match_operand:P 0 "const_int_operand" "")))
16993 (clobber (reg:CC FLAGS_REG))
16994 (clobber (mem:BLK (scratch)))])]
16995 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16996 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16997 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16998 (clobber (mem:BLK (scratch)))])
16999 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17002 [(match_scratch:P 1 "r")
17003 (parallel [(set (reg:P SP_REG)
17004 (plus:P (reg:P SP_REG)
17005 (match_operand:P 0 "const_int_operand" "")))
17006 (clobber (reg:CC FLAGS_REG))
17007 (clobber (mem:BLK (scratch)))])]
17008 "optimize_insn_for_size_p ()
17009 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17010 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17011 (clobber (mem:BLK (scratch)))])
17012 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17014 ;; Convert esp additions to pop.
17016 [(match_scratch:P 1 "r")
17017 (parallel [(set (reg:P SP_REG)
17018 (plus:P (reg:P SP_REG)
17019 (match_operand:P 0 "const_int_operand" "")))
17020 (clobber (reg:CC FLAGS_REG))])]
17021 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17022 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17024 ;; Two pops case is tricky, since pop causes dependency
17025 ;; on destination register. We use two registers if available.
17027 [(match_scratch:P 1 "r")
17028 (match_scratch:P 2 "r")
17029 (parallel [(set (reg:P SP_REG)
17030 (plus:P (reg:P SP_REG)
17031 (match_operand:P 0 "const_int_operand" "")))
17032 (clobber (reg:CC FLAGS_REG))])]
17033 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17034 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17035 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17038 [(match_scratch:P 1 "r")
17039 (parallel [(set (reg:P SP_REG)
17040 (plus:P (reg:P SP_REG)
17041 (match_operand:P 0 "const_int_operand" "")))
17042 (clobber (reg:CC FLAGS_REG))])]
17043 "optimize_insn_for_size_p ()
17044 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17045 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17046 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17048 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17049 ;; required and register dies. Similarly for 128 to -128.
17051 [(set (match_operand 0 "flags_reg_operand" "")
17052 (match_operator 1 "compare_operator"
17053 [(match_operand 2 "register_operand" "")
17054 (match_operand 3 "const_int_operand" "")]))]
17055 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17056 && incdec_operand (operands[3], GET_MODE (operands[3])))
17057 || (!TARGET_FUSE_CMP_AND_BRANCH
17058 && INTVAL (operands[3]) == 128))
17059 && ix86_match_ccmode (insn, CCGCmode)
17060 && peep2_reg_dead_p (1, operands[2])"
17061 [(parallel [(set (match_dup 0)
17062 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17063 (clobber (match_dup 2))])])
17065 ;; Convert imul by three, five and nine into lea
17068 [(set (match_operand:SWI48 0 "register_operand" "")
17069 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17070 (match_operand:SWI48 2 "const_int_operand" "")))
17071 (clobber (reg:CC FLAGS_REG))])]
17072 "INTVAL (operands[2]) == 3
17073 || INTVAL (operands[2]) == 5
17074 || INTVAL (operands[2]) == 9"
17075 [(set (match_dup 0)
17076 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17078 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17082 [(set (match_operand:SWI48 0 "register_operand" "")
17083 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17084 (match_operand:SWI48 2 "const_int_operand" "")))
17085 (clobber (reg:CC FLAGS_REG))])]
17086 "optimize_insn_for_speed_p ()
17087 && (INTVAL (operands[2]) == 3
17088 || INTVAL (operands[2]) == 5
17089 || INTVAL (operands[2]) == 9)"
17090 [(set (match_dup 0) (match_dup 1))
17092 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17094 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17096 ;; imul $32bit_imm, mem, reg is vector decoded, while
17097 ;; imul $32bit_imm, reg, reg is direct decoded.
17099 [(match_scratch:SWI48 3 "r")
17100 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17101 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17102 (match_operand:SWI48 2 "immediate_operand" "")))
17103 (clobber (reg:CC FLAGS_REG))])]
17104 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17105 && !satisfies_constraint_K (operands[2])"
17106 [(set (match_dup 3) (match_dup 1))
17107 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17108 (clobber (reg:CC FLAGS_REG))])])
17111 [(match_scratch:SI 3 "r")
17112 (parallel [(set (match_operand:DI 0 "register_operand" "")
17114 (mult:SI (match_operand:SI 1 "memory_operand" "")
17115 (match_operand:SI 2 "immediate_operand" ""))))
17116 (clobber (reg:CC FLAGS_REG))])]
17118 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17119 && !satisfies_constraint_K (operands[2])"
17120 [(set (match_dup 3) (match_dup 1))
17121 (parallel [(set (match_dup 0)
17122 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17123 (clobber (reg:CC FLAGS_REG))])])
17125 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17126 ;; Convert it into imul reg, reg
17127 ;; It would be better to force assembler to encode instruction using long
17128 ;; immediate, but there is apparently no way to do so.
17130 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17132 (match_operand:SWI248 1 "nonimmediate_operand" "")
17133 (match_operand:SWI248 2 "const_int_operand" "")))
17134 (clobber (reg:CC FLAGS_REG))])
17135 (match_scratch:SWI248 3 "r")]
17136 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17137 && satisfies_constraint_K (operands[2])"
17138 [(set (match_dup 3) (match_dup 2))
17139 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17140 (clobber (reg:CC FLAGS_REG))])]
17142 if (!rtx_equal_p (operands[0], operands[1]))
17143 emit_move_insn (operands[0], operands[1]);
17146 ;; After splitting up read-modify operations, array accesses with memory
17147 ;; operands might end up in form:
17149 ;; movl 4(%esp), %edx
17151 ;; instead of pre-splitting:
17153 ;; addl 4(%esp), %eax
17155 ;; movl 4(%esp), %edx
17156 ;; leal (%edx,%eax,4), %eax
17159 [(match_scratch:P 5 "r")
17160 (parallel [(set (match_operand 0 "register_operand" "")
17161 (ashift (match_operand 1 "register_operand" "")
17162 (match_operand 2 "const_int_operand" "")))
17163 (clobber (reg:CC FLAGS_REG))])
17164 (parallel [(set (match_operand 3 "register_operand" "")
17165 (plus (match_dup 0)
17166 (match_operand 4 "x86_64_general_operand" "")))
17167 (clobber (reg:CC FLAGS_REG))])]
17168 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17169 /* Validate MODE for lea. */
17170 && ((!TARGET_PARTIAL_REG_STALL
17171 && (GET_MODE (operands[0]) == QImode
17172 || GET_MODE (operands[0]) == HImode))
17173 || GET_MODE (operands[0]) == SImode
17174 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17175 && (rtx_equal_p (operands[0], operands[3])
17176 || peep2_reg_dead_p (2, operands[0]))
17177 /* We reorder load and the shift. */
17178 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17179 [(set (match_dup 5) (match_dup 4))
17180 (set (match_dup 0) (match_dup 1))]
17182 enum machine_mode op1mode = GET_MODE (operands[1]);
17183 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17184 int scale = 1 << INTVAL (operands[2]);
17185 rtx index = gen_lowpart (Pmode, operands[1]);
17186 rtx base = gen_lowpart (Pmode, operands[5]);
17187 rtx dest = gen_lowpart (mode, operands[3]);
17189 operands[1] = gen_rtx_PLUS (Pmode, base,
17190 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17191 operands[5] = base;
17193 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17194 if (op1mode != Pmode)
17195 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17196 operands[0] = dest;
17199 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17200 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17201 ;; caught for use by garbage collectors and the like. Using an insn that
17202 ;; maps to SIGILL makes it more likely the program will rightfully die.
17203 ;; Keeping with tradition, "6" is in honor of #UD.
17204 (define_insn "trap"
17205 [(trap_if (const_int 1) (const_int 6))]
17207 { return ASM_SHORT "0x0b0f"; }
17208 [(set_attr "length" "2")])
17210 (define_expand "prefetch"
17211 [(prefetch (match_operand 0 "address_operand" "")
17212 (match_operand:SI 1 "const_int_operand" "")
17213 (match_operand:SI 2 "const_int_operand" ""))]
17214 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17216 int rw = INTVAL (operands[1]);
17217 int locality = INTVAL (operands[2]);
17219 gcc_assert (rw == 0 || rw == 1);
17220 gcc_assert (locality >= 0 && locality <= 3);
17221 gcc_assert (GET_MODE (operands[0]) == Pmode
17222 || GET_MODE (operands[0]) == VOIDmode);
17224 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17225 supported by SSE counterpart or the SSE prefetch is not available
17226 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17228 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17229 operands[2] = GEN_INT (3);
17231 operands[1] = const0_rtx;
17234 (define_insn "*prefetch_sse_<mode>"
17235 [(prefetch (match_operand:P 0 "address_operand" "p")
17237 (match_operand:SI 1 "const_int_operand" ""))]
17238 "TARGET_PREFETCH_SSE"
17240 static const char * const patterns[4] = {
17241 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17244 int locality = INTVAL (operands[1]);
17245 gcc_assert (locality >= 0 && locality <= 3);
17247 return patterns[locality];
17249 [(set_attr "type" "sse")
17250 (set_attr "atom_sse_attr" "prefetch")
17251 (set (attr "length_address")
17252 (symbol_ref "memory_address_length (operands[0])"))
17253 (set_attr "memory" "none")])
17255 (define_insn "*prefetch_3dnow_<mode>"
17256 [(prefetch (match_operand:P 0 "address_operand" "p")
17257 (match_operand:SI 1 "const_int_operand" "n")
17261 if (INTVAL (operands[1]) == 0)
17262 return "prefetch\t%a0";
17264 return "prefetchw\t%a0";
17266 [(set_attr "type" "mmx")
17267 (set (attr "length_address")
17268 (symbol_ref "memory_address_length (operands[0])"))
17269 (set_attr "memory" "none")])
17271 (define_expand "stack_protect_set"
17272 [(match_operand 0 "memory_operand" "")
17273 (match_operand 1 "memory_operand" "")]
17276 rtx (*insn)(rtx, rtx);
17278 #ifdef TARGET_THREAD_SSP_OFFSET
17279 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17280 insn = (TARGET_64BIT
17281 ? gen_stack_tls_protect_set_di
17282 : gen_stack_tls_protect_set_si);
17284 insn = (TARGET_64BIT
17285 ? gen_stack_protect_set_di
17286 : gen_stack_protect_set_si);
17289 emit_insn (insn (operands[0], operands[1]));
17293 (define_insn "stack_protect_set_<mode>"
17294 [(set (match_operand:P 0 "memory_operand" "=m")
17295 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17296 (set (match_scratch:P 2 "=&r") (const_int 0))
17297 (clobber (reg:CC FLAGS_REG))]
17299 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17300 [(set_attr "type" "multi")])
17302 (define_insn "stack_tls_protect_set_<mode>"
17303 [(set (match_operand:P 0 "memory_operand" "=m")
17304 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17305 UNSPEC_SP_TLS_SET))
17306 (set (match_scratch:P 2 "=&r") (const_int 0))
17307 (clobber (reg:CC FLAGS_REG))]
17309 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17310 [(set_attr "type" "multi")])
17312 (define_expand "stack_protect_test"
17313 [(match_operand 0 "memory_operand" "")
17314 (match_operand 1 "memory_operand" "")
17315 (match_operand 2 "" "")]
17318 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17320 rtx (*insn)(rtx, rtx, rtx);
17322 #ifdef TARGET_THREAD_SSP_OFFSET
17323 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17324 insn = (TARGET_64BIT
17325 ? gen_stack_tls_protect_test_di
17326 : gen_stack_tls_protect_test_si);
17328 insn = (TARGET_64BIT
17329 ? gen_stack_protect_test_di
17330 : gen_stack_protect_test_si);
17333 emit_insn (insn (flags, operands[0], operands[1]));
17335 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17336 flags, const0_rtx, operands[2]));
17340 (define_insn "stack_protect_test_<mode>"
17341 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17342 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17343 (match_operand:P 2 "memory_operand" "m")]
17345 (clobber (match_scratch:P 3 "=&r"))]
17347 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17348 [(set_attr "type" "multi")])
17350 (define_insn "stack_tls_protect_test_<mode>"
17351 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17352 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17353 (match_operand:P 2 "const_int_operand" "i")]
17354 UNSPEC_SP_TLS_TEST))
17355 (clobber (match_scratch:P 3 "=r"))]
17357 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17358 [(set_attr "type" "multi")])
17360 (define_insn "sse4_2_crc32<mode>"
17361 [(set (match_operand:SI 0 "register_operand" "=r")
17363 [(match_operand:SI 1 "register_operand" "0")
17364 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17366 "TARGET_SSE4_2 || TARGET_CRC32"
17367 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17368 [(set_attr "type" "sselog1")
17369 (set_attr "prefix_rep" "1")
17370 (set_attr "prefix_extra" "1")
17371 (set (attr "prefix_data16")
17372 (if_then_else (match_operand:HI 2 "" "")
17374 (const_string "*")))
17375 (set (attr "prefix_rex")
17376 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17378 (const_string "*")))
17379 (set_attr "mode" "SI")])
17381 (define_insn "sse4_2_crc32di"
17382 [(set (match_operand:DI 0 "register_operand" "=r")
17384 [(match_operand:DI 1 "register_operand" "0")
17385 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17387 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17388 "crc32{q}\t{%2, %0|%0, %2}"
17389 [(set_attr "type" "sselog1")
17390 (set_attr "prefix_rep" "1")
17391 (set_attr "prefix_extra" "1")
17392 (set_attr "mode" "DI")])
17394 (define_expand "rdpmc"
17395 [(match_operand:DI 0 "register_operand" "")
17396 (match_operand:SI 1 "register_operand" "")]
17399 rtx reg = gen_reg_rtx (DImode);
17402 /* Force operand 1 into ECX. */
17403 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17404 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17405 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17410 rtvec vec = rtvec_alloc (2);
17411 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17412 rtx upper = gen_reg_rtx (DImode);
17413 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17414 gen_rtvec (1, const0_rtx),
17416 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17417 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17419 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17420 NULL, 1, OPTAB_DIRECT);
17421 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17425 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17426 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17430 (define_insn "*rdpmc"
17431 [(set (match_operand:DI 0 "register_operand" "=A")
17432 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17436 [(set_attr "type" "other")
17437 (set_attr "length" "2")])
17439 (define_insn "*rdpmc_rex64"
17440 [(set (match_operand:DI 0 "register_operand" "=a")
17441 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17443 (set (match_operand:DI 1 "register_operand" "=d")
17444 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17447 [(set_attr "type" "other")
17448 (set_attr "length" "2")])
17450 (define_expand "rdtsc"
17451 [(set (match_operand:DI 0 "register_operand" "")
17452 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17457 rtvec vec = rtvec_alloc (2);
17458 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17459 rtx upper = gen_reg_rtx (DImode);
17460 rtx lower = gen_reg_rtx (DImode);
17461 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17462 gen_rtvec (1, const0_rtx),
17464 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17465 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17467 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17468 NULL, 1, OPTAB_DIRECT);
17469 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17471 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17476 (define_insn "*rdtsc"
17477 [(set (match_operand:DI 0 "register_operand" "=A")
17478 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17481 [(set_attr "type" "other")
17482 (set_attr "length" "2")])
17484 (define_insn "*rdtsc_rex64"
17485 [(set (match_operand:DI 0 "register_operand" "=a")
17486 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17487 (set (match_operand:DI 1 "register_operand" "=d")
17488 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17491 [(set_attr "type" "other")
17492 (set_attr "length" "2")])
17494 (define_expand "rdtscp"
17495 [(match_operand:DI 0 "register_operand" "")
17496 (match_operand:SI 1 "memory_operand" "")]
17499 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17500 gen_rtvec (1, const0_rtx),
17502 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17503 gen_rtvec (1, const0_rtx),
17505 rtx reg = gen_reg_rtx (DImode);
17506 rtx tmp = gen_reg_rtx (SImode);
17510 rtvec vec = rtvec_alloc (3);
17511 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17512 rtx upper = gen_reg_rtx (DImode);
17513 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17514 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17515 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17517 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17518 NULL, 1, OPTAB_DIRECT);
17519 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17524 rtvec vec = rtvec_alloc (2);
17525 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17526 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17527 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17530 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17531 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17535 (define_insn "*rdtscp"
17536 [(set (match_operand:DI 0 "register_operand" "=A")
17537 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17538 (set (match_operand:SI 1 "register_operand" "=c")
17539 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17542 [(set_attr "type" "other")
17543 (set_attr "length" "3")])
17545 (define_insn "*rdtscp_rex64"
17546 [(set (match_operand:DI 0 "register_operand" "=a")
17547 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17548 (set (match_operand:DI 1 "register_operand" "=d")
17549 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17550 (set (match_operand:SI 2 "register_operand" "=c")
17551 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17554 [(set_attr "type" "other")
17555 (set_attr "length" "3")])
17557 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17559 ;; LWP instructions
17561 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17563 (define_expand "lwp_llwpcb"
17564 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17565 UNSPECV_LLWP_INTRINSIC)]
17568 (define_insn "*lwp_llwpcb<mode>1"
17569 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17570 UNSPECV_LLWP_INTRINSIC)]
17573 [(set_attr "type" "lwp")
17574 (set_attr "mode" "<MODE>")
17575 (set_attr "length" "5")])
17577 (define_expand "lwp_slwpcb"
17578 [(set (match_operand 0 "register_operand" "=r")
17579 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17584 insn = (TARGET_64BIT
17586 : gen_lwp_slwpcbsi);
17588 emit_insn (insn (operands[0]));
17592 (define_insn "lwp_slwpcb<mode>"
17593 [(set (match_operand:P 0 "register_operand" "=r")
17594 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17597 [(set_attr "type" "lwp")
17598 (set_attr "mode" "<MODE>")
17599 (set_attr "length" "5")])
17601 (define_expand "lwp_lwpval<mode>3"
17602 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17603 (match_operand:SI 2 "nonimmediate_operand" "rm")
17604 (match_operand:SI 3 "const_int_operand" "i")]
17605 UNSPECV_LWPVAL_INTRINSIC)]
17607 "/* Avoid unused variable warning. */
17610 (define_insn "*lwp_lwpval<mode>3_1"
17611 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17612 (match_operand:SI 1 "nonimmediate_operand" "rm")
17613 (match_operand:SI 2 "const_int_operand" "i")]
17614 UNSPECV_LWPVAL_INTRINSIC)]
17616 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17617 [(set_attr "type" "lwp")
17618 (set_attr "mode" "<MODE>")
17619 (set (attr "length")
17620 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17622 (define_expand "lwp_lwpins<mode>3"
17623 [(set (reg:CCC FLAGS_REG)
17624 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17625 (match_operand:SI 2 "nonimmediate_operand" "rm")
17626 (match_operand:SI 3 "const_int_operand" "i")]
17627 UNSPECV_LWPINS_INTRINSIC))
17628 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17629 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17632 (define_insn "*lwp_lwpins<mode>3_1"
17633 [(set (reg:CCC FLAGS_REG)
17634 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17635 (match_operand:SI 1 "nonimmediate_operand" "rm")
17636 (match_operand:SI 2 "const_int_operand" "i")]
17637 UNSPECV_LWPINS_INTRINSIC))]
17639 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17640 [(set_attr "type" "lwp")
17641 (set_attr "mode" "<MODE>")
17642 (set (attr "length")
17643 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17645 (define_insn "rdfsbase<mode>"
17646 [(set (match_operand:SWI48 0 "register_operand" "=r")
17647 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17648 "TARGET_64BIT && TARGET_FSGSBASE"
17650 [(set_attr "type" "other")
17651 (set_attr "prefix_extra" "2")])
17653 (define_insn "rdgsbase<mode>"
17654 [(set (match_operand:SWI48 0 "register_operand" "=r")
17655 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17656 "TARGET_64BIT && TARGET_FSGSBASE"
17658 [(set_attr "type" "other")
17659 (set_attr "prefix_extra" "2")])
17661 (define_insn "wrfsbase<mode>"
17662 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17664 "TARGET_64BIT && TARGET_FSGSBASE"
17666 [(set_attr "type" "other")
17667 (set_attr "prefix_extra" "2")])
17669 (define_insn "wrgsbase<mode>"
17670 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17672 "TARGET_64BIT && TARGET_FSGSBASE"
17674 [(set_attr "type" "other")
17675 (set_attr "prefix_extra" "2")])
17677 (define_insn "rdrand<mode>_1"
17678 [(set (match_operand:SWI248 0 "register_operand" "=r")
17679 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17680 (set (reg:CCC FLAGS_REG)
17681 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17684 [(set_attr "type" "other")
17685 (set_attr "prefix_extra" "1")])
17689 (include "sync.md")