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, true)")
418 (eq_attr "type" "imov,test")
419 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
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, true, true)")
528 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
529 (if_then_else (eq_attr "prefix_vex_w" "1")
530 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
531 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
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, false, false);"
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, false, false);"
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, false, false);"
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, false, true);"
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, false, false);"
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, true, false);"
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, true, false);"
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, true, false);"
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, true, true);"
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, true, true);"
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, true, true);"
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, true);"
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, false);"
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, false);"
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, false);
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, true);
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], false);
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, false);
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, true);
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], false);
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")
12359 [(match_operand:SI 1 "register_operand" "b")
12360 (match_operand:SI 2 "tls_symbolic_operand" "")
12361 (match_operand:SI 3 "constant_call_address_operand" "z")]
12363 (clobber (match_scratch:SI 4 "=d"))
12364 (clobber (match_scratch:SI 5 "=c"))
12365 (clobber (reg:CC FLAGS_REG))]
12366 "!TARGET_64BIT && TARGET_GNU_TLS"
12369 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12370 return "call\t%P3";
12372 [(set_attr "type" "multi")
12373 (set_attr "length" "12")])
12375 (define_expand "tls_global_dynamic_32"
12377 [(set (match_operand:SI 0 "register_operand" "")
12378 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12379 (match_operand:SI 1 "tls_symbolic_operand" "")
12380 (match_operand:SI 3 "constant_call_address_operand" "")]
12382 (clobber (match_scratch:SI 4 ""))
12383 (clobber (match_scratch:SI 5 ""))
12384 (clobber (reg:CC FLAGS_REG))])])
12386 (define_insn "*tls_global_dynamic_64"
12387 [(set (match_operand:DI 0 "register_operand" "=a")
12389 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12390 (match_operand:DI 3 "" "")))
12391 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12395 fputs (ASM_BYTE "0x66\n", asm_out_file);
12397 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12398 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12399 fputs ("\trex64\n", asm_out_file);
12400 return "call\t%P2";
12402 [(set_attr "type" "multi")
12403 (set_attr "length" "16")])
12405 (define_expand "tls_global_dynamic_64"
12407 [(set (match_operand:DI 0 "register_operand" "")
12409 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12411 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12414 (define_insn "*tls_local_dynamic_base_32_gnu"
12415 [(set (match_operand:SI 0 "register_operand" "=a")
12417 [(match_operand:SI 1 "register_operand" "b")
12418 (match_operand:SI 2 "constant_call_address_operand" "z")]
12419 UNSPEC_TLS_LD_BASE))
12420 (clobber (match_scratch:SI 3 "=d"))
12421 (clobber (match_scratch:SI 4 "=c"))
12422 (clobber (reg:CC FLAGS_REG))]
12423 "!TARGET_64BIT && TARGET_GNU_TLS"
12426 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12427 return "call\t%P2";
12429 [(set_attr "type" "multi")
12430 (set_attr "length" "11")])
12432 (define_expand "tls_local_dynamic_base_32"
12434 [(set (match_operand:SI 0 "register_operand" "")
12436 [(match_operand:SI 1 "register_operand" "")
12437 (match_operand:SI 2 "constant_call_address_operand" "")]
12438 UNSPEC_TLS_LD_BASE))
12439 (clobber (match_scratch:SI 3 ""))
12440 (clobber (match_scratch:SI 4 ""))
12441 (clobber (reg:CC FLAGS_REG))])])
12443 (define_insn "*tls_local_dynamic_base_64"
12444 [(set (match_operand:DI 0 "register_operand" "=a")
12446 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12447 (match_operand:DI 2 "" "")))
12448 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12452 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12453 return "call\t%P1";
12455 [(set_attr "type" "multi")
12456 (set_attr "length" "12")])
12458 (define_expand "tls_local_dynamic_base_64"
12460 [(set (match_operand:DI 0 "register_operand" "")
12462 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12464 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12466 ;; Local dynamic of a single variable is a lose. Show combine how
12467 ;; to convert that back to global dynamic.
12469 (define_insn_and_split "*tls_local_dynamic_32_once"
12470 [(set (match_operand:SI 0 "register_operand" "=a")
12472 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12473 (match_operand:SI 2 "constant_call_address_operand" "z")]
12474 UNSPEC_TLS_LD_BASE)
12475 (const:SI (unspec:SI
12476 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12478 (clobber (match_scratch:SI 4 "=d"))
12479 (clobber (match_scratch:SI 5 "=c"))
12480 (clobber (reg:CC FLAGS_REG))]
12485 [(set (match_dup 0)
12486 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12488 (clobber (match_dup 4))
12489 (clobber (match_dup 5))
12490 (clobber (reg:CC FLAGS_REG))])])
12492 ;; Segment register for the thread base ptr load
12493 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12495 ;; Load and add the thread base pointer from %<tp_seg>:0.
12496 (define_insn "*load_tp_<mode>"
12497 [(set (match_operand:P 0 "register_operand" "=r")
12498 (unspec:P [(const_int 0)] UNSPEC_TP))]
12500 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12501 [(set_attr "type" "imov")
12502 (set_attr "modrm" "0")
12503 (set_attr "length" "7")
12504 (set_attr "memory" "load")
12505 (set_attr "imm_disp" "false")])
12507 (define_insn "*add_tp_<mode>"
12508 [(set (match_operand:P 0 "register_operand" "=r")
12509 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12510 (match_operand:P 1 "register_operand" "0")))
12511 (clobber (reg:CC FLAGS_REG))]
12513 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12514 [(set_attr "type" "alu")
12515 (set_attr "modrm" "0")
12516 (set_attr "length" "7")
12517 (set_attr "memory" "load")
12518 (set_attr "imm_disp" "false")])
12520 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12521 ;; %rax as destination of the initial executable code sequence.
12522 (define_insn "tls_initial_exec_64_sun"
12523 [(set (match_operand:DI 0 "register_operand" "=a")
12525 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12526 UNSPEC_TLS_IE_SUN))
12527 (clobber (reg:CC FLAGS_REG))]
12528 "TARGET_64BIT && TARGET_SUN_TLS"
12531 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands)
12532 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12534 [(set_attr "type" "multi")])
12536 ;; GNU2 TLS patterns can be split.
12538 (define_expand "tls_dynamic_gnu2_32"
12539 [(set (match_dup 3)
12540 (plus:SI (match_operand:SI 2 "register_operand" "")
12542 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12545 [(set (match_operand:SI 0 "register_operand" "")
12546 (unspec:SI [(match_dup 1) (match_dup 3)
12547 (match_dup 2) (reg:SI SP_REG)]
12549 (clobber (reg:CC FLAGS_REG))])]
12550 "!TARGET_64BIT && TARGET_GNU2_TLS"
12552 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12553 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12556 (define_insn "*tls_dynamic_lea_32"
12557 [(set (match_operand:SI 0 "register_operand" "=r")
12558 (plus:SI (match_operand:SI 1 "register_operand" "b")
12560 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12561 UNSPEC_TLSDESC))))]
12562 "!TARGET_64BIT && TARGET_GNU2_TLS"
12563 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12564 [(set_attr "type" "lea")
12565 (set_attr "mode" "SI")
12566 (set_attr "length" "6")
12567 (set_attr "length_address" "4")])
12569 (define_insn "*tls_dynamic_call_32"
12570 [(set (match_operand:SI 0 "register_operand" "=a")
12571 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12572 (match_operand:SI 2 "register_operand" "0")
12573 ;; we have to make sure %ebx still points to the GOT
12574 (match_operand:SI 3 "register_operand" "b")
12577 (clobber (reg:CC FLAGS_REG))]
12578 "!TARGET_64BIT && TARGET_GNU2_TLS"
12579 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12580 [(set_attr "type" "call")
12581 (set_attr "length" "2")
12582 (set_attr "length_address" "0")])
12584 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12585 [(set (match_operand:SI 0 "register_operand" "=&a")
12587 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12588 (match_operand:SI 4 "" "")
12589 (match_operand:SI 2 "register_operand" "b")
12592 (const:SI (unspec:SI
12593 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12595 (clobber (reg:CC FLAGS_REG))]
12596 "!TARGET_64BIT && TARGET_GNU2_TLS"
12599 [(set (match_dup 0) (match_dup 5))]
12601 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12602 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12605 (define_expand "tls_dynamic_gnu2_64"
12606 [(set (match_dup 2)
12607 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12610 [(set (match_operand:DI 0 "register_operand" "")
12611 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12613 (clobber (reg:CC FLAGS_REG))])]
12614 "TARGET_64BIT && TARGET_GNU2_TLS"
12616 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12617 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12620 (define_insn "*tls_dynamic_lea_64"
12621 [(set (match_operand:DI 0 "register_operand" "=r")
12622 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12624 "TARGET_64BIT && TARGET_GNU2_TLS"
12625 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12626 [(set_attr "type" "lea")
12627 (set_attr "mode" "DI")
12628 (set_attr "length" "7")
12629 (set_attr "length_address" "4")])
12631 (define_insn "*tls_dynamic_call_64"
12632 [(set (match_operand:DI 0 "register_operand" "=a")
12633 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12634 (match_operand:DI 2 "register_operand" "0")
12637 (clobber (reg:CC FLAGS_REG))]
12638 "TARGET_64BIT && TARGET_GNU2_TLS"
12639 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12640 [(set_attr "type" "call")
12641 (set_attr "length" "2")
12642 (set_attr "length_address" "0")])
12644 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12645 [(set (match_operand:DI 0 "register_operand" "=&a")
12647 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12648 (match_operand:DI 3 "" "")
12651 (const:DI (unspec:DI
12652 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12654 (clobber (reg:CC FLAGS_REG))]
12655 "TARGET_64BIT && TARGET_GNU2_TLS"
12658 [(set (match_dup 0) (match_dup 4))]
12660 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12661 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12664 ;; These patterns match the binary 387 instructions for addM3, subM3,
12665 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12666 ;; SFmode. The first is the normal insn, the second the same insn but
12667 ;; with one operand a conversion, and the third the same insn but with
12668 ;; the other operand a conversion. The conversion may be SFmode or
12669 ;; SImode if the target mode DFmode, but only SImode if the target mode
12672 ;; Gcc is slightly more smart about handling normal two address instructions
12673 ;; so use special patterns for add and mull.
12675 (define_insn "*fop_<mode>_comm_mixed"
12676 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12677 (match_operator:MODEF 3 "binary_fp_operator"
12678 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12679 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12680 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12681 && COMMUTATIVE_ARITH_P (operands[3])
12682 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12683 "* return output_387_binary_op (insn, operands);"
12684 [(set (attr "type")
12685 (if_then_else (eq_attr "alternative" "1,2")
12686 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12687 (const_string "ssemul")
12688 (const_string "sseadd"))
12689 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12690 (const_string "fmul")
12691 (const_string "fop"))))
12692 (set_attr "isa" "base,noavx,avx")
12693 (set_attr "prefix" "orig,orig,vex")
12694 (set_attr "mode" "<MODE>")])
12696 (define_insn "*fop_<mode>_comm_sse"
12697 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12698 (match_operator:MODEF 3 "binary_fp_operator"
12699 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12700 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12701 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
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 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12707 (const_string "ssemul")
12708 (const_string "sseadd")))
12709 (set_attr "isa" "noavx,avx")
12710 (set_attr "prefix" "orig,vex")
12711 (set_attr "mode" "<MODE>")])
12713 (define_insn "*fop_<mode>_comm_i387"
12714 [(set (match_operand:MODEF 0 "register_operand" "=f")
12715 (match_operator:MODEF 3 "binary_fp_operator"
12716 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12717 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12718 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12719 && COMMUTATIVE_ARITH_P (operands[3])
12720 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12721 "* return output_387_binary_op (insn, operands);"
12722 [(set (attr "type")
12723 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12724 (const_string "fmul")
12725 (const_string "fop")))
12726 (set_attr "mode" "<MODE>")])
12728 (define_insn "*fop_<mode>_1_mixed"
12729 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12730 (match_operator:MODEF 3 "binary_fp_operator"
12731 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12732 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12733 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12734 && !COMMUTATIVE_ARITH_P (operands[3])
12735 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12736 "* return output_387_binary_op (insn, operands);"
12737 [(set (attr "type")
12738 (cond [(and (eq_attr "alternative" "2,3")
12739 (match_operand:MODEF 3 "mult_operator" ""))
12740 (const_string "ssemul")
12741 (and (eq_attr "alternative" "2,3")
12742 (match_operand:MODEF 3 "div_operator" ""))
12743 (const_string "ssediv")
12744 (eq_attr "alternative" "2,3")
12745 (const_string "sseadd")
12746 (match_operand:MODEF 3 "mult_operator" "")
12747 (const_string "fmul")
12748 (match_operand:MODEF 3 "div_operator" "")
12749 (const_string "fdiv")
12751 (const_string "fop")))
12752 (set_attr "isa" "base,base,noavx,avx")
12753 (set_attr "prefix" "orig,orig,orig,vex")
12754 (set_attr "mode" "<MODE>")])
12756 (define_insn "*rcpsf2_sse"
12757 [(set (match_operand:SF 0 "register_operand" "=x")
12758 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12761 "%vrcpss\t{%1, %d0|%d0, %1}"
12762 [(set_attr "type" "sse")
12763 (set_attr "atom_sse_attr" "rcp")
12764 (set_attr "prefix" "maybe_vex")
12765 (set_attr "mode" "SF")])
12767 (define_insn "*fop_<mode>_1_sse"
12768 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12769 (match_operator:MODEF 3 "binary_fp_operator"
12770 [(match_operand:MODEF 1 "register_operand" "0,x")
12771 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12772 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12773 && !COMMUTATIVE_ARITH_P (operands[3])"
12774 "* return output_387_binary_op (insn, operands);"
12775 [(set (attr "type")
12776 (cond [(match_operand:MODEF 3 "mult_operator" "")
12777 (const_string "ssemul")
12778 (match_operand:MODEF 3 "div_operator" "")
12779 (const_string "ssediv")
12781 (const_string "sseadd")))
12782 (set_attr "isa" "noavx,avx")
12783 (set_attr "prefix" "orig,vex")
12784 (set_attr "mode" "<MODE>")])
12786 ;; This pattern is not fully shadowed by the pattern above.
12787 (define_insn "*fop_<mode>_1_i387"
12788 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12789 (match_operator:MODEF 3 "binary_fp_operator"
12790 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12791 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12792 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12793 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12794 && !COMMUTATIVE_ARITH_P (operands[3])
12795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12796 "* return output_387_binary_op (insn, operands);"
12797 [(set (attr "type")
12798 (cond [(match_operand:MODEF 3 "mult_operator" "")
12799 (const_string "fmul")
12800 (match_operand:MODEF 3 "div_operator" "")
12801 (const_string "fdiv")
12803 (const_string "fop")))
12804 (set_attr "mode" "<MODE>")])
12806 ;; ??? Add SSE splitters for these!
12807 (define_insn "*fop_<MODEF:mode>_2_i387"
12808 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12809 (match_operator:MODEF 3 "binary_fp_operator"
12811 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12812 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12813 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12814 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12815 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12816 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12817 [(set (attr "type")
12818 (cond [(match_operand:MODEF 3 "mult_operator" "")
12819 (const_string "fmul")
12820 (match_operand:MODEF 3 "div_operator" "")
12821 (const_string "fdiv")
12823 (const_string "fop")))
12824 (set_attr "fp_int_src" "true")
12825 (set_attr "mode" "<X87MODEI12:MODE>")])
12827 (define_insn "*fop_<MODEF:mode>_3_i387"
12828 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12829 (match_operator:MODEF 3 "binary_fp_operator"
12830 [(match_operand:MODEF 1 "register_operand" "0,0")
12832 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12833 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12834 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12835 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12836 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12837 [(set (attr "type")
12838 (cond [(match_operand:MODEF 3 "mult_operator" "")
12839 (const_string "fmul")
12840 (match_operand:MODEF 3 "div_operator" "")
12841 (const_string "fdiv")
12843 (const_string "fop")))
12844 (set_attr "fp_int_src" "true")
12845 (set_attr "mode" "<MODE>")])
12847 (define_insn "*fop_df_4_i387"
12848 [(set (match_operand:DF 0 "register_operand" "=f,f")
12849 (match_operator:DF 3 "binary_fp_operator"
12851 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12852 (match_operand:DF 2 "register_operand" "0,f")]))]
12853 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12854 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12855 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12856 "* return output_387_binary_op (insn, operands);"
12857 [(set (attr "type")
12858 (cond [(match_operand:DF 3 "mult_operator" "")
12859 (const_string "fmul")
12860 (match_operand:DF 3 "div_operator" "")
12861 (const_string "fdiv")
12863 (const_string "fop")))
12864 (set_attr "mode" "SF")])
12866 (define_insn "*fop_df_5_i387"
12867 [(set (match_operand:DF 0 "register_operand" "=f,f")
12868 (match_operator:DF 3 "binary_fp_operator"
12869 [(match_operand:DF 1 "register_operand" "0,f")
12871 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12872 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12873 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12874 "* return output_387_binary_op (insn, operands);"
12875 [(set (attr "type")
12876 (cond [(match_operand:DF 3 "mult_operator" "")
12877 (const_string "fmul")
12878 (match_operand:DF 3 "div_operator" "")
12879 (const_string "fdiv")
12881 (const_string "fop")))
12882 (set_attr "mode" "SF")])
12884 (define_insn "*fop_df_6_i387"
12885 [(set (match_operand:DF 0 "register_operand" "=f,f")
12886 (match_operator:DF 3 "binary_fp_operator"
12888 (match_operand:SF 1 "register_operand" "0,f"))
12890 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12891 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12892 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12893 "* return output_387_binary_op (insn, operands);"
12894 [(set (attr "type")
12895 (cond [(match_operand:DF 3 "mult_operator" "")
12896 (const_string "fmul")
12897 (match_operand:DF 3 "div_operator" "")
12898 (const_string "fdiv")
12900 (const_string "fop")))
12901 (set_attr "mode" "SF")])
12903 (define_insn "*fop_xf_comm_i387"
12904 [(set (match_operand:XF 0 "register_operand" "=f")
12905 (match_operator:XF 3 "binary_fp_operator"
12906 [(match_operand:XF 1 "register_operand" "%0")
12907 (match_operand:XF 2 "register_operand" "f")]))]
12909 && COMMUTATIVE_ARITH_P (operands[3])"
12910 "* return output_387_binary_op (insn, operands);"
12911 [(set (attr "type")
12912 (if_then_else (match_operand:XF 3 "mult_operator" "")
12913 (const_string "fmul")
12914 (const_string "fop")))
12915 (set_attr "mode" "XF")])
12917 (define_insn "*fop_xf_1_i387"
12918 [(set (match_operand:XF 0 "register_operand" "=f,f")
12919 (match_operator:XF 3 "binary_fp_operator"
12920 [(match_operand:XF 1 "register_operand" "0,f")
12921 (match_operand:XF 2 "register_operand" "f,0")]))]
12923 && !COMMUTATIVE_ARITH_P (operands[3])"
12924 "* return output_387_binary_op (insn, operands);"
12925 [(set (attr "type")
12926 (cond [(match_operand:XF 3 "mult_operator" "")
12927 (const_string "fmul")
12928 (match_operand:XF 3 "div_operator" "")
12929 (const_string "fdiv")
12931 (const_string "fop")))
12932 (set_attr "mode" "XF")])
12934 (define_insn "*fop_xf_2_i387"
12935 [(set (match_operand:XF 0 "register_operand" "=f,f")
12936 (match_operator:XF 3 "binary_fp_operator"
12938 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12939 (match_operand:XF 2 "register_operand" "0,0")]))]
12940 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12941 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12942 [(set (attr "type")
12943 (cond [(match_operand:XF 3 "mult_operator" "")
12944 (const_string "fmul")
12945 (match_operand:XF 3 "div_operator" "")
12946 (const_string "fdiv")
12948 (const_string "fop")))
12949 (set_attr "fp_int_src" "true")
12950 (set_attr "mode" "<MODE>")])
12952 (define_insn "*fop_xf_3_i387"
12953 [(set (match_operand:XF 0 "register_operand" "=f,f")
12954 (match_operator:XF 3 "binary_fp_operator"
12955 [(match_operand:XF 1 "register_operand" "0,0")
12957 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12958 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12959 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12960 [(set (attr "type")
12961 (cond [(match_operand:XF 3 "mult_operator" "")
12962 (const_string "fmul")
12963 (match_operand:XF 3 "div_operator" "")
12964 (const_string "fdiv")
12966 (const_string "fop")))
12967 (set_attr "fp_int_src" "true")
12968 (set_attr "mode" "<MODE>")])
12970 (define_insn "*fop_xf_4_i387"
12971 [(set (match_operand:XF 0 "register_operand" "=f,f")
12972 (match_operator:XF 3 "binary_fp_operator"
12974 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12975 (match_operand:XF 2 "register_operand" "0,f")]))]
12977 "* return output_387_binary_op (insn, operands);"
12978 [(set (attr "type")
12979 (cond [(match_operand:XF 3 "mult_operator" "")
12980 (const_string "fmul")
12981 (match_operand:XF 3 "div_operator" "")
12982 (const_string "fdiv")
12984 (const_string "fop")))
12985 (set_attr "mode" "<MODE>")])
12987 (define_insn "*fop_xf_5_i387"
12988 [(set (match_operand:XF 0 "register_operand" "=f,f")
12989 (match_operator:XF 3 "binary_fp_operator"
12990 [(match_operand:XF 1 "register_operand" "0,f")
12992 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12994 "* return output_387_binary_op (insn, operands);"
12995 [(set (attr "type")
12996 (cond [(match_operand:XF 3 "mult_operator" "")
12997 (const_string "fmul")
12998 (match_operand:XF 3 "div_operator" "")
12999 (const_string "fdiv")
13001 (const_string "fop")))
13002 (set_attr "mode" "<MODE>")])
13004 (define_insn "*fop_xf_6_i387"
13005 [(set (match_operand:XF 0 "register_operand" "=f,f")
13006 (match_operator:XF 3 "binary_fp_operator"
13008 (match_operand:MODEF 1 "register_operand" "0,f"))
13010 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13012 "* return output_387_binary_op (insn, operands);"
13013 [(set (attr "type")
13014 (cond [(match_operand:XF 3 "mult_operator" "")
13015 (const_string "fmul")
13016 (match_operand:XF 3 "div_operator" "")
13017 (const_string "fdiv")
13019 (const_string "fop")))
13020 (set_attr "mode" "<MODE>")])
13023 [(set (match_operand 0 "register_operand" "")
13024 (match_operator 3 "binary_fp_operator"
13025 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13026 (match_operand 2 "register_operand" "")]))]
13028 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13029 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13032 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13033 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13034 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13035 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13036 GET_MODE (operands[3]),
13039 ix86_free_from_memory (GET_MODE (operands[1]));
13044 [(set (match_operand 0 "register_operand" "")
13045 (match_operator 3 "binary_fp_operator"
13046 [(match_operand 1 "register_operand" "")
13047 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13049 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13050 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13053 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13054 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13055 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13056 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13057 GET_MODE (operands[3]),
13060 ix86_free_from_memory (GET_MODE (operands[2]));
13064 ;; FPU special functions.
13066 ;; This pattern implements a no-op XFmode truncation for
13067 ;; all fancy i386 XFmode math functions.
13069 (define_insn "truncxf<mode>2_i387_noop_unspec"
13070 [(set (match_operand:MODEF 0 "register_operand" "=f")
13071 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13072 UNSPEC_TRUNC_NOOP))]
13073 "TARGET_USE_FANCY_MATH_387"
13074 "* return output_387_reg_move (insn, operands);"
13075 [(set_attr "type" "fmov")
13076 (set_attr "mode" "<MODE>")])
13078 (define_insn "sqrtxf2"
13079 [(set (match_operand:XF 0 "register_operand" "=f")
13080 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13081 "TARGET_USE_FANCY_MATH_387"
13083 [(set_attr "type" "fpspc")
13084 (set_attr "mode" "XF")
13085 (set_attr "athlon_decode" "direct")
13086 (set_attr "amdfam10_decode" "direct")
13087 (set_attr "bdver1_decode" "direct")])
13089 (define_insn "sqrt_extend<mode>xf2_i387"
13090 [(set (match_operand:XF 0 "register_operand" "=f")
13093 (match_operand:MODEF 1 "register_operand" "0"))))]
13094 "TARGET_USE_FANCY_MATH_387"
13096 [(set_attr "type" "fpspc")
13097 (set_attr "mode" "XF")
13098 (set_attr "athlon_decode" "direct")
13099 (set_attr "amdfam10_decode" "direct")
13100 (set_attr "bdver1_decode" "direct")])
13102 (define_insn "*rsqrtsf2_sse"
13103 [(set (match_operand:SF 0 "register_operand" "=x")
13104 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13107 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13108 [(set_attr "type" "sse")
13109 (set_attr "atom_sse_attr" "rcp")
13110 (set_attr "prefix" "maybe_vex")
13111 (set_attr "mode" "SF")])
13113 (define_expand "rsqrtsf2"
13114 [(set (match_operand:SF 0 "register_operand" "")
13115 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13119 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13123 (define_insn "*sqrt<mode>2_sse"
13124 [(set (match_operand:MODEF 0 "register_operand" "=x")
13126 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13127 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13128 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13129 [(set_attr "type" "sse")
13130 (set_attr "atom_sse_attr" "sqrt")
13131 (set_attr "prefix" "maybe_vex")
13132 (set_attr "mode" "<MODE>")
13133 (set_attr "athlon_decode" "*")
13134 (set_attr "amdfam10_decode" "*")
13135 (set_attr "bdver1_decode" "*")])
13137 (define_expand "sqrt<mode>2"
13138 [(set (match_operand:MODEF 0 "register_operand" "")
13140 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13141 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13142 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13144 if (<MODE>mode == SFmode
13145 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13146 && flag_finite_math_only && !flag_trapping_math
13147 && flag_unsafe_math_optimizations)
13149 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13153 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13155 rtx op0 = gen_reg_rtx (XFmode);
13156 rtx op1 = force_reg (<MODE>mode, operands[1]);
13158 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13159 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13164 (define_insn "fpremxf4_i387"
13165 [(set (match_operand:XF 0 "register_operand" "=f")
13166 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13167 (match_operand:XF 3 "register_operand" "1")]
13169 (set (match_operand:XF 1 "register_operand" "=u")
13170 (unspec:XF [(match_dup 2) (match_dup 3)]
13172 (set (reg:CCFP FPSR_REG)
13173 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13175 "TARGET_USE_FANCY_MATH_387"
13177 [(set_attr "type" "fpspc")
13178 (set_attr "mode" "XF")])
13180 (define_expand "fmodxf3"
13181 [(use (match_operand:XF 0 "register_operand" ""))
13182 (use (match_operand:XF 1 "general_operand" ""))
13183 (use (match_operand:XF 2 "general_operand" ""))]
13184 "TARGET_USE_FANCY_MATH_387"
13186 rtx label = gen_label_rtx ();
13188 rtx op1 = gen_reg_rtx (XFmode);
13189 rtx op2 = gen_reg_rtx (XFmode);
13191 emit_move_insn (op2, operands[2]);
13192 emit_move_insn (op1, operands[1]);
13194 emit_label (label);
13195 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13196 ix86_emit_fp_unordered_jump (label);
13197 LABEL_NUSES (label) = 1;
13199 emit_move_insn (operands[0], op1);
13203 (define_expand "fmod<mode>3"
13204 [(use (match_operand:MODEF 0 "register_operand" ""))
13205 (use (match_operand:MODEF 1 "general_operand" ""))
13206 (use (match_operand:MODEF 2 "general_operand" ""))]
13207 "TARGET_USE_FANCY_MATH_387"
13209 rtx (*gen_truncxf) (rtx, rtx);
13211 rtx label = gen_label_rtx ();
13213 rtx op1 = gen_reg_rtx (XFmode);
13214 rtx op2 = gen_reg_rtx (XFmode);
13216 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13217 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13219 emit_label (label);
13220 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13221 ix86_emit_fp_unordered_jump (label);
13222 LABEL_NUSES (label) = 1;
13224 /* Truncate the result properly for strict SSE math. */
13225 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13226 && !TARGET_MIX_SSE_I387)
13227 gen_truncxf = gen_truncxf<mode>2;
13229 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13231 emit_insn (gen_truncxf (operands[0], op1));
13235 (define_insn "fprem1xf4_i387"
13236 [(set (match_operand:XF 0 "register_operand" "=f")
13237 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13238 (match_operand:XF 3 "register_operand" "1")]
13240 (set (match_operand:XF 1 "register_operand" "=u")
13241 (unspec:XF [(match_dup 2) (match_dup 3)]
13243 (set (reg:CCFP FPSR_REG)
13244 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13246 "TARGET_USE_FANCY_MATH_387"
13248 [(set_attr "type" "fpspc")
13249 (set_attr "mode" "XF")])
13251 (define_expand "remainderxf3"
13252 [(use (match_operand:XF 0 "register_operand" ""))
13253 (use (match_operand:XF 1 "general_operand" ""))
13254 (use (match_operand:XF 2 "general_operand" ""))]
13255 "TARGET_USE_FANCY_MATH_387"
13257 rtx label = gen_label_rtx ();
13259 rtx op1 = gen_reg_rtx (XFmode);
13260 rtx op2 = gen_reg_rtx (XFmode);
13262 emit_move_insn (op2, operands[2]);
13263 emit_move_insn (op1, operands[1]);
13265 emit_label (label);
13266 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13267 ix86_emit_fp_unordered_jump (label);
13268 LABEL_NUSES (label) = 1;
13270 emit_move_insn (operands[0], op1);
13274 (define_expand "remainder<mode>3"
13275 [(use (match_operand:MODEF 0 "register_operand" ""))
13276 (use (match_operand:MODEF 1 "general_operand" ""))
13277 (use (match_operand:MODEF 2 "general_operand" ""))]
13278 "TARGET_USE_FANCY_MATH_387"
13280 rtx (*gen_truncxf) (rtx, rtx);
13282 rtx label = gen_label_rtx ();
13284 rtx op1 = gen_reg_rtx (XFmode);
13285 rtx op2 = gen_reg_rtx (XFmode);
13287 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13288 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13290 emit_label (label);
13292 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13293 ix86_emit_fp_unordered_jump (label);
13294 LABEL_NUSES (label) = 1;
13296 /* Truncate the result properly for strict SSE math. */
13297 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13298 && !TARGET_MIX_SSE_I387)
13299 gen_truncxf = gen_truncxf<mode>2;
13301 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13303 emit_insn (gen_truncxf (operands[0], op1));
13307 (define_insn "*sinxf2_i387"
13308 [(set (match_operand:XF 0 "register_operand" "=f")
13309 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13310 "TARGET_USE_FANCY_MATH_387
13311 && flag_unsafe_math_optimizations"
13313 [(set_attr "type" "fpspc")
13314 (set_attr "mode" "XF")])
13316 (define_insn "*sin_extend<mode>xf2_i387"
13317 [(set (match_operand:XF 0 "register_operand" "=f")
13318 (unspec:XF [(float_extend:XF
13319 (match_operand:MODEF 1 "register_operand" "0"))]
13321 "TARGET_USE_FANCY_MATH_387
13322 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13323 || TARGET_MIX_SSE_I387)
13324 && flag_unsafe_math_optimizations"
13326 [(set_attr "type" "fpspc")
13327 (set_attr "mode" "XF")])
13329 (define_insn "*cosxf2_i387"
13330 [(set (match_operand:XF 0 "register_operand" "=f")
13331 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13332 "TARGET_USE_FANCY_MATH_387
13333 && flag_unsafe_math_optimizations"
13335 [(set_attr "type" "fpspc")
13336 (set_attr "mode" "XF")])
13338 (define_insn "*cos_extend<mode>xf2_i387"
13339 [(set (match_operand:XF 0 "register_operand" "=f")
13340 (unspec:XF [(float_extend:XF
13341 (match_operand:MODEF 1 "register_operand" "0"))]
13343 "TARGET_USE_FANCY_MATH_387
13344 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13345 || TARGET_MIX_SSE_I387)
13346 && flag_unsafe_math_optimizations"
13348 [(set_attr "type" "fpspc")
13349 (set_attr "mode" "XF")])
13351 ;; When sincos pattern is defined, sin and cos builtin functions will be
13352 ;; expanded to sincos pattern with one of its outputs left unused.
13353 ;; CSE pass will figure out if two sincos patterns can be combined,
13354 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13355 ;; depending on the unused output.
13357 (define_insn "sincosxf3"
13358 [(set (match_operand:XF 0 "register_operand" "=f")
13359 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13360 UNSPEC_SINCOS_COS))
13361 (set (match_operand:XF 1 "register_operand" "=u")
13362 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13363 "TARGET_USE_FANCY_MATH_387
13364 && flag_unsafe_math_optimizations"
13366 [(set_attr "type" "fpspc")
13367 (set_attr "mode" "XF")])
13370 [(set (match_operand:XF 0 "register_operand" "")
13371 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13372 UNSPEC_SINCOS_COS))
13373 (set (match_operand:XF 1 "register_operand" "")
13374 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13375 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13376 && can_create_pseudo_p ()"
13377 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13380 [(set (match_operand:XF 0 "register_operand" "")
13381 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13382 UNSPEC_SINCOS_COS))
13383 (set (match_operand:XF 1 "register_operand" "")
13384 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13385 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13386 && can_create_pseudo_p ()"
13387 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13389 (define_insn "sincos_extend<mode>xf3_i387"
13390 [(set (match_operand:XF 0 "register_operand" "=f")
13391 (unspec:XF [(float_extend:XF
13392 (match_operand:MODEF 2 "register_operand" "0"))]
13393 UNSPEC_SINCOS_COS))
13394 (set (match_operand:XF 1 "register_operand" "=u")
13395 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13396 "TARGET_USE_FANCY_MATH_387
13397 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13398 || TARGET_MIX_SSE_I387)
13399 && flag_unsafe_math_optimizations"
13401 [(set_attr "type" "fpspc")
13402 (set_attr "mode" "XF")])
13405 [(set (match_operand:XF 0 "register_operand" "")
13406 (unspec:XF [(float_extend:XF
13407 (match_operand:MODEF 2 "register_operand" ""))]
13408 UNSPEC_SINCOS_COS))
13409 (set (match_operand:XF 1 "register_operand" "")
13410 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13411 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13412 && can_create_pseudo_p ()"
13413 [(set (match_dup 1)
13414 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13417 [(set (match_operand:XF 0 "register_operand" "")
13418 (unspec:XF [(float_extend:XF
13419 (match_operand:MODEF 2 "register_operand" ""))]
13420 UNSPEC_SINCOS_COS))
13421 (set (match_operand:XF 1 "register_operand" "")
13422 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13423 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13424 && can_create_pseudo_p ()"
13425 [(set (match_dup 0)
13426 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13428 (define_expand "sincos<mode>3"
13429 [(use (match_operand:MODEF 0 "register_operand" ""))
13430 (use (match_operand:MODEF 1 "register_operand" ""))
13431 (use (match_operand:MODEF 2 "register_operand" ""))]
13432 "TARGET_USE_FANCY_MATH_387
13433 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13434 || TARGET_MIX_SSE_I387)
13435 && flag_unsafe_math_optimizations"
13437 rtx op0 = gen_reg_rtx (XFmode);
13438 rtx op1 = gen_reg_rtx (XFmode);
13440 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13441 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13442 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13446 (define_insn "fptanxf4_i387"
13447 [(set (match_operand:XF 0 "register_operand" "=f")
13448 (match_operand:XF 3 "const_double_operand" "F"))
13449 (set (match_operand:XF 1 "register_operand" "=u")
13450 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13452 "TARGET_USE_FANCY_MATH_387
13453 && flag_unsafe_math_optimizations
13454 && standard_80387_constant_p (operands[3]) == 2"
13456 [(set_attr "type" "fpspc")
13457 (set_attr "mode" "XF")])
13459 (define_insn "fptan_extend<mode>xf4_i387"
13460 [(set (match_operand:MODEF 0 "register_operand" "=f")
13461 (match_operand:MODEF 3 "const_double_operand" "F"))
13462 (set (match_operand:XF 1 "register_operand" "=u")
13463 (unspec:XF [(float_extend:XF
13464 (match_operand:MODEF 2 "register_operand" "0"))]
13466 "TARGET_USE_FANCY_MATH_387
13467 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13468 || TARGET_MIX_SSE_I387)
13469 && flag_unsafe_math_optimizations
13470 && standard_80387_constant_p (operands[3]) == 2"
13472 [(set_attr "type" "fpspc")
13473 (set_attr "mode" "XF")])
13475 (define_expand "tanxf2"
13476 [(use (match_operand:XF 0 "register_operand" ""))
13477 (use (match_operand:XF 1 "register_operand" ""))]
13478 "TARGET_USE_FANCY_MATH_387
13479 && flag_unsafe_math_optimizations"
13481 rtx one = gen_reg_rtx (XFmode);
13482 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13484 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13488 (define_expand "tan<mode>2"
13489 [(use (match_operand:MODEF 0 "register_operand" ""))
13490 (use (match_operand:MODEF 1 "register_operand" ""))]
13491 "TARGET_USE_FANCY_MATH_387
13492 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13493 || TARGET_MIX_SSE_I387)
13494 && flag_unsafe_math_optimizations"
13496 rtx op0 = gen_reg_rtx (XFmode);
13498 rtx one = gen_reg_rtx (<MODE>mode);
13499 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13501 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13502 operands[1], op2));
13503 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13507 (define_insn "*fpatanxf3_i387"
13508 [(set (match_operand:XF 0 "register_operand" "=f")
13509 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13510 (match_operand:XF 2 "register_operand" "u")]
13512 (clobber (match_scratch:XF 3 "=2"))]
13513 "TARGET_USE_FANCY_MATH_387
13514 && flag_unsafe_math_optimizations"
13516 [(set_attr "type" "fpspc")
13517 (set_attr "mode" "XF")])
13519 (define_insn "fpatan_extend<mode>xf3_i387"
13520 [(set (match_operand:XF 0 "register_operand" "=f")
13521 (unspec:XF [(float_extend:XF
13522 (match_operand:MODEF 1 "register_operand" "0"))
13524 (match_operand:MODEF 2 "register_operand" "u"))]
13526 (clobber (match_scratch:XF 3 "=2"))]
13527 "TARGET_USE_FANCY_MATH_387
13528 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13529 || TARGET_MIX_SSE_I387)
13530 && flag_unsafe_math_optimizations"
13532 [(set_attr "type" "fpspc")
13533 (set_attr "mode" "XF")])
13535 (define_expand "atan2xf3"
13536 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13537 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13538 (match_operand:XF 1 "register_operand" "")]
13540 (clobber (match_scratch:XF 3 ""))])]
13541 "TARGET_USE_FANCY_MATH_387
13542 && flag_unsafe_math_optimizations")
13544 (define_expand "atan2<mode>3"
13545 [(use (match_operand:MODEF 0 "register_operand" ""))
13546 (use (match_operand:MODEF 1 "register_operand" ""))
13547 (use (match_operand:MODEF 2 "register_operand" ""))]
13548 "TARGET_USE_FANCY_MATH_387
13549 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13550 || TARGET_MIX_SSE_I387)
13551 && flag_unsafe_math_optimizations"
13553 rtx op0 = gen_reg_rtx (XFmode);
13555 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13556 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13560 (define_expand "atanxf2"
13561 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13562 (unspec:XF [(match_dup 2)
13563 (match_operand:XF 1 "register_operand" "")]
13565 (clobber (match_scratch:XF 3 ""))])]
13566 "TARGET_USE_FANCY_MATH_387
13567 && flag_unsafe_math_optimizations"
13569 operands[2] = gen_reg_rtx (XFmode);
13570 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13573 (define_expand "atan<mode>2"
13574 [(use (match_operand:MODEF 0 "register_operand" ""))
13575 (use (match_operand:MODEF 1 "register_operand" ""))]
13576 "TARGET_USE_FANCY_MATH_387
13577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13578 || TARGET_MIX_SSE_I387)
13579 && flag_unsafe_math_optimizations"
13581 rtx op0 = gen_reg_rtx (XFmode);
13583 rtx op2 = gen_reg_rtx (<MODE>mode);
13584 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13586 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13587 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13591 (define_expand "asinxf2"
13592 [(set (match_dup 2)
13593 (mult:XF (match_operand:XF 1 "register_operand" "")
13595 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13596 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13597 (parallel [(set (match_operand:XF 0 "register_operand" "")
13598 (unspec:XF [(match_dup 5) (match_dup 1)]
13600 (clobber (match_scratch:XF 6 ""))])]
13601 "TARGET_USE_FANCY_MATH_387
13602 && flag_unsafe_math_optimizations"
13606 if (optimize_insn_for_size_p ())
13609 for (i = 2; i < 6; i++)
13610 operands[i] = gen_reg_rtx (XFmode);
13612 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13615 (define_expand "asin<mode>2"
13616 [(use (match_operand:MODEF 0 "register_operand" ""))
13617 (use (match_operand:MODEF 1 "general_operand" ""))]
13618 "TARGET_USE_FANCY_MATH_387
13619 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13620 || TARGET_MIX_SSE_I387)
13621 && flag_unsafe_math_optimizations"
13623 rtx op0 = gen_reg_rtx (XFmode);
13624 rtx op1 = gen_reg_rtx (XFmode);
13626 if (optimize_insn_for_size_p ())
13629 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13630 emit_insn (gen_asinxf2 (op0, op1));
13631 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13635 (define_expand "acosxf2"
13636 [(set (match_dup 2)
13637 (mult:XF (match_operand:XF 1 "register_operand" "")
13639 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13640 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13641 (parallel [(set (match_operand:XF 0 "register_operand" "")
13642 (unspec:XF [(match_dup 1) (match_dup 5)]
13644 (clobber (match_scratch:XF 6 ""))])]
13645 "TARGET_USE_FANCY_MATH_387
13646 && flag_unsafe_math_optimizations"
13650 if (optimize_insn_for_size_p ())
13653 for (i = 2; i < 6; i++)
13654 operands[i] = gen_reg_rtx (XFmode);
13656 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13659 (define_expand "acos<mode>2"
13660 [(use (match_operand:MODEF 0 "register_operand" ""))
13661 (use (match_operand:MODEF 1 "general_operand" ""))]
13662 "TARGET_USE_FANCY_MATH_387
13663 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13664 || TARGET_MIX_SSE_I387)
13665 && flag_unsafe_math_optimizations"
13667 rtx op0 = gen_reg_rtx (XFmode);
13668 rtx op1 = gen_reg_rtx (XFmode);
13670 if (optimize_insn_for_size_p ())
13673 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13674 emit_insn (gen_acosxf2 (op0, op1));
13675 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13679 (define_insn "fyl2xxf3_i387"
13680 [(set (match_operand:XF 0 "register_operand" "=f")
13681 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13682 (match_operand:XF 2 "register_operand" "u")]
13684 (clobber (match_scratch:XF 3 "=2"))]
13685 "TARGET_USE_FANCY_MATH_387
13686 && flag_unsafe_math_optimizations"
13688 [(set_attr "type" "fpspc")
13689 (set_attr "mode" "XF")])
13691 (define_insn "fyl2x_extend<mode>xf3_i387"
13692 [(set (match_operand:XF 0 "register_operand" "=f")
13693 (unspec:XF [(float_extend:XF
13694 (match_operand:MODEF 1 "register_operand" "0"))
13695 (match_operand:XF 2 "register_operand" "u")]
13697 (clobber (match_scratch:XF 3 "=2"))]
13698 "TARGET_USE_FANCY_MATH_387
13699 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13700 || TARGET_MIX_SSE_I387)
13701 && flag_unsafe_math_optimizations"
13703 [(set_attr "type" "fpspc")
13704 (set_attr "mode" "XF")])
13706 (define_expand "logxf2"
13707 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13708 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13709 (match_dup 2)] UNSPEC_FYL2X))
13710 (clobber (match_scratch:XF 3 ""))])]
13711 "TARGET_USE_FANCY_MATH_387
13712 && flag_unsafe_math_optimizations"
13714 operands[2] = gen_reg_rtx (XFmode);
13715 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13718 (define_expand "log<mode>2"
13719 [(use (match_operand:MODEF 0 "register_operand" ""))
13720 (use (match_operand:MODEF 1 "register_operand" ""))]
13721 "TARGET_USE_FANCY_MATH_387
13722 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13723 || TARGET_MIX_SSE_I387)
13724 && flag_unsafe_math_optimizations"
13726 rtx op0 = gen_reg_rtx (XFmode);
13728 rtx op2 = gen_reg_rtx (XFmode);
13729 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13731 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13732 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13736 (define_expand "log10xf2"
13737 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13738 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13739 (match_dup 2)] UNSPEC_FYL2X))
13740 (clobber (match_scratch:XF 3 ""))])]
13741 "TARGET_USE_FANCY_MATH_387
13742 && flag_unsafe_math_optimizations"
13744 operands[2] = gen_reg_rtx (XFmode);
13745 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13748 (define_expand "log10<mode>2"
13749 [(use (match_operand:MODEF 0 "register_operand" ""))
13750 (use (match_operand:MODEF 1 "register_operand" ""))]
13751 "TARGET_USE_FANCY_MATH_387
13752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13753 || TARGET_MIX_SSE_I387)
13754 && flag_unsafe_math_optimizations"
13756 rtx op0 = gen_reg_rtx (XFmode);
13758 rtx op2 = gen_reg_rtx (XFmode);
13759 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13761 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13762 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13766 (define_expand "log2xf2"
13767 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13768 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13769 (match_dup 2)] UNSPEC_FYL2X))
13770 (clobber (match_scratch:XF 3 ""))])]
13771 "TARGET_USE_FANCY_MATH_387
13772 && flag_unsafe_math_optimizations"
13774 operands[2] = gen_reg_rtx (XFmode);
13775 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13778 (define_expand "log2<mode>2"
13779 [(use (match_operand:MODEF 0 "register_operand" ""))
13780 (use (match_operand:MODEF 1 "register_operand" ""))]
13781 "TARGET_USE_FANCY_MATH_387
13782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13783 || TARGET_MIX_SSE_I387)
13784 && flag_unsafe_math_optimizations"
13786 rtx op0 = gen_reg_rtx (XFmode);
13788 rtx op2 = gen_reg_rtx (XFmode);
13789 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13791 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13792 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13796 (define_insn "fyl2xp1xf3_i387"
13797 [(set (match_operand:XF 0 "register_operand" "=f")
13798 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13799 (match_operand:XF 2 "register_operand" "u")]
13801 (clobber (match_scratch:XF 3 "=2"))]
13802 "TARGET_USE_FANCY_MATH_387
13803 && flag_unsafe_math_optimizations"
13805 [(set_attr "type" "fpspc")
13806 (set_attr "mode" "XF")])
13808 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13809 [(set (match_operand:XF 0 "register_operand" "=f")
13810 (unspec:XF [(float_extend:XF
13811 (match_operand:MODEF 1 "register_operand" "0"))
13812 (match_operand:XF 2 "register_operand" "u")]
13814 (clobber (match_scratch:XF 3 "=2"))]
13815 "TARGET_USE_FANCY_MATH_387
13816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13817 || TARGET_MIX_SSE_I387)
13818 && flag_unsafe_math_optimizations"
13820 [(set_attr "type" "fpspc")
13821 (set_attr "mode" "XF")])
13823 (define_expand "log1pxf2"
13824 [(use (match_operand:XF 0 "register_operand" ""))
13825 (use (match_operand:XF 1 "register_operand" ""))]
13826 "TARGET_USE_FANCY_MATH_387
13827 && flag_unsafe_math_optimizations"
13829 if (optimize_insn_for_size_p ())
13832 ix86_emit_i387_log1p (operands[0], operands[1]);
13836 (define_expand "log1p<mode>2"
13837 [(use (match_operand:MODEF 0 "register_operand" ""))
13838 (use (match_operand:MODEF 1 "register_operand" ""))]
13839 "TARGET_USE_FANCY_MATH_387
13840 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13841 || TARGET_MIX_SSE_I387)
13842 && flag_unsafe_math_optimizations"
13846 if (optimize_insn_for_size_p ())
13849 op0 = gen_reg_rtx (XFmode);
13851 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13853 ix86_emit_i387_log1p (op0, operands[1]);
13854 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13858 (define_insn "fxtractxf3_i387"
13859 [(set (match_operand:XF 0 "register_operand" "=f")
13860 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13861 UNSPEC_XTRACT_FRACT))
13862 (set (match_operand:XF 1 "register_operand" "=u")
13863 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13864 "TARGET_USE_FANCY_MATH_387
13865 && flag_unsafe_math_optimizations"
13867 [(set_attr "type" "fpspc")
13868 (set_attr "mode" "XF")])
13870 (define_insn "fxtract_extend<mode>xf3_i387"
13871 [(set (match_operand:XF 0 "register_operand" "=f")
13872 (unspec:XF [(float_extend:XF
13873 (match_operand:MODEF 2 "register_operand" "0"))]
13874 UNSPEC_XTRACT_FRACT))
13875 (set (match_operand:XF 1 "register_operand" "=u")
13876 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13877 "TARGET_USE_FANCY_MATH_387
13878 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13879 || TARGET_MIX_SSE_I387)
13880 && flag_unsafe_math_optimizations"
13882 [(set_attr "type" "fpspc")
13883 (set_attr "mode" "XF")])
13885 (define_expand "logbxf2"
13886 [(parallel [(set (match_dup 2)
13887 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13888 UNSPEC_XTRACT_FRACT))
13889 (set (match_operand:XF 0 "register_operand" "")
13890 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13891 "TARGET_USE_FANCY_MATH_387
13892 && flag_unsafe_math_optimizations"
13893 "operands[2] = gen_reg_rtx (XFmode);")
13895 (define_expand "logb<mode>2"
13896 [(use (match_operand:MODEF 0 "register_operand" ""))
13897 (use (match_operand:MODEF 1 "register_operand" ""))]
13898 "TARGET_USE_FANCY_MATH_387
13899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13900 || TARGET_MIX_SSE_I387)
13901 && flag_unsafe_math_optimizations"
13903 rtx op0 = gen_reg_rtx (XFmode);
13904 rtx op1 = gen_reg_rtx (XFmode);
13906 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13907 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13911 (define_expand "ilogbxf2"
13912 [(use (match_operand:SI 0 "register_operand" ""))
13913 (use (match_operand:XF 1 "register_operand" ""))]
13914 "TARGET_USE_FANCY_MATH_387
13915 && flag_unsafe_math_optimizations"
13919 if (optimize_insn_for_size_p ())
13922 op0 = gen_reg_rtx (XFmode);
13923 op1 = gen_reg_rtx (XFmode);
13925 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13926 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13930 (define_expand "ilogb<mode>2"
13931 [(use (match_operand:SI 0 "register_operand" ""))
13932 (use (match_operand:MODEF 1 "register_operand" ""))]
13933 "TARGET_USE_FANCY_MATH_387
13934 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13935 || TARGET_MIX_SSE_I387)
13936 && flag_unsafe_math_optimizations"
13940 if (optimize_insn_for_size_p ())
13943 op0 = gen_reg_rtx (XFmode);
13944 op1 = gen_reg_rtx (XFmode);
13946 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13947 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13951 (define_insn "*f2xm1xf2_i387"
13952 [(set (match_operand:XF 0 "register_operand" "=f")
13953 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13955 "TARGET_USE_FANCY_MATH_387
13956 && flag_unsafe_math_optimizations"
13958 [(set_attr "type" "fpspc")
13959 (set_attr "mode" "XF")])
13961 (define_insn "*fscalexf4_i387"
13962 [(set (match_operand:XF 0 "register_operand" "=f")
13963 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13964 (match_operand:XF 3 "register_operand" "1")]
13965 UNSPEC_FSCALE_FRACT))
13966 (set (match_operand:XF 1 "register_operand" "=u")
13967 (unspec:XF [(match_dup 2) (match_dup 3)]
13968 UNSPEC_FSCALE_EXP))]
13969 "TARGET_USE_FANCY_MATH_387
13970 && flag_unsafe_math_optimizations"
13972 [(set_attr "type" "fpspc")
13973 (set_attr "mode" "XF")])
13975 (define_expand "expNcorexf3"
13976 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13977 (match_operand:XF 2 "register_operand" "")))
13978 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13979 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13980 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13981 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13982 (parallel [(set (match_operand:XF 0 "register_operand" "")
13983 (unspec:XF [(match_dup 8) (match_dup 4)]
13984 UNSPEC_FSCALE_FRACT))
13986 (unspec:XF [(match_dup 8) (match_dup 4)]
13987 UNSPEC_FSCALE_EXP))])]
13988 "TARGET_USE_FANCY_MATH_387
13989 && flag_unsafe_math_optimizations"
13993 if (optimize_insn_for_size_p ())
13996 for (i = 3; i < 10; i++)
13997 operands[i] = gen_reg_rtx (XFmode);
13999 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14002 (define_expand "expxf2"
14003 [(use (match_operand:XF 0 "register_operand" ""))
14004 (use (match_operand:XF 1 "register_operand" ""))]
14005 "TARGET_USE_FANCY_MATH_387
14006 && flag_unsafe_math_optimizations"
14010 if (optimize_insn_for_size_p ())
14013 op2 = gen_reg_rtx (XFmode);
14014 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14016 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14020 (define_expand "exp<mode>2"
14021 [(use (match_operand:MODEF 0 "register_operand" ""))
14022 (use (match_operand:MODEF 1 "general_operand" ""))]
14023 "TARGET_USE_FANCY_MATH_387
14024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14025 || TARGET_MIX_SSE_I387)
14026 && flag_unsafe_math_optimizations"
14030 if (optimize_insn_for_size_p ())
14033 op0 = gen_reg_rtx (XFmode);
14034 op1 = gen_reg_rtx (XFmode);
14036 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14037 emit_insn (gen_expxf2 (op0, op1));
14038 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14042 (define_expand "exp10xf2"
14043 [(use (match_operand:XF 0 "register_operand" ""))
14044 (use (match_operand:XF 1 "register_operand" ""))]
14045 "TARGET_USE_FANCY_MATH_387
14046 && flag_unsafe_math_optimizations"
14050 if (optimize_insn_for_size_p ())
14053 op2 = gen_reg_rtx (XFmode);
14054 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14056 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14060 (define_expand "exp10<mode>2"
14061 [(use (match_operand:MODEF 0 "register_operand" ""))
14062 (use (match_operand:MODEF 1 "general_operand" ""))]
14063 "TARGET_USE_FANCY_MATH_387
14064 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14065 || TARGET_MIX_SSE_I387)
14066 && flag_unsafe_math_optimizations"
14070 if (optimize_insn_for_size_p ())
14073 op0 = gen_reg_rtx (XFmode);
14074 op1 = gen_reg_rtx (XFmode);
14076 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14077 emit_insn (gen_exp10xf2 (op0, op1));
14078 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14082 (define_expand "exp2xf2"
14083 [(use (match_operand:XF 0 "register_operand" ""))
14084 (use (match_operand:XF 1 "register_operand" ""))]
14085 "TARGET_USE_FANCY_MATH_387
14086 && flag_unsafe_math_optimizations"
14090 if (optimize_insn_for_size_p ())
14093 op2 = gen_reg_rtx (XFmode);
14094 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14096 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14100 (define_expand "exp2<mode>2"
14101 [(use (match_operand:MODEF 0 "register_operand" ""))
14102 (use (match_operand:MODEF 1 "general_operand" ""))]
14103 "TARGET_USE_FANCY_MATH_387
14104 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14105 || TARGET_MIX_SSE_I387)
14106 && flag_unsafe_math_optimizations"
14110 if (optimize_insn_for_size_p ())
14113 op0 = gen_reg_rtx (XFmode);
14114 op1 = gen_reg_rtx (XFmode);
14116 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14117 emit_insn (gen_exp2xf2 (op0, op1));
14118 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14122 (define_expand "expm1xf2"
14123 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14125 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14126 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14127 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14128 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14129 (parallel [(set (match_dup 7)
14130 (unspec:XF [(match_dup 6) (match_dup 4)]
14131 UNSPEC_FSCALE_FRACT))
14133 (unspec:XF [(match_dup 6) (match_dup 4)]
14134 UNSPEC_FSCALE_EXP))])
14135 (parallel [(set (match_dup 10)
14136 (unspec:XF [(match_dup 9) (match_dup 8)]
14137 UNSPEC_FSCALE_FRACT))
14138 (set (match_dup 11)
14139 (unspec:XF [(match_dup 9) (match_dup 8)]
14140 UNSPEC_FSCALE_EXP))])
14141 (set (match_dup 12) (minus:XF (match_dup 10)
14142 (float_extend:XF (match_dup 13))))
14143 (set (match_operand:XF 0 "register_operand" "")
14144 (plus:XF (match_dup 12) (match_dup 7)))]
14145 "TARGET_USE_FANCY_MATH_387
14146 && flag_unsafe_math_optimizations"
14150 if (optimize_insn_for_size_p ())
14153 for (i = 2; i < 13; i++)
14154 operands[i] = gen_reg_rtx (XFmode);
14157 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14159 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14162 (define_expand "expm1<mode>2"
14163 [(use (match_operand:MODEF 0 "register_operand" ""))
14164 (use (match_operand:MODEF 1 "general_operand" ""))]
14165 "TARGET_USE_FANCY_MATH_387
14166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167 || TARGET_MIX_SSE_I387)
14168 && flag_unsafe_math_optimizations"
14172 if (optimize_insn_for_size_p ())
14175 op0 = gen_reg_rtx (XFmode);
14176 op1 = gen_reg_rtx (XFmode);
14178 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14179 emit_insn (gen_expm1xf2 (op0, op1));
14180 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14184 (define_expand "ldexpxf3"
14185 [(set (match_dup 3)
14186 (float:XF (match_operand:SI 2 "register_operand" "")))
14187 (parallel [(set (match_operand:XF 0 " register_operand" "")
14188 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14190 UNSPEC_FSCALE_FRACT))
14192 (unspec:XF [(match_dup 1) (match_dup 3)]
14193 UNSPEC_FSCALE_EXP))])]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations"
14197 if (optimize_insn_for_size_p ())
14200 operands[3] = gen_reg_rtx (XFmode);
14201 operands[4] = gen_reg_rtx (XFmode);
14204 (define_expand "ldexp<mode>3"
14205 [(use (match_operand:MODEF 0 "register_operand" ""))
14206 (use (match_operand:MODEF 1 "general_operand" ""))
14207 (use (match_operand:SI 2 "register_operand" ""))]
14208 "TARGET_USE_FANCY_MATH_387
14209 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14210 || TARGET_MIX_SSE_I387)
14211 && flag_unsafe_math_optimizations"
14215 if (optimize_insn_for_size_p ())
14218 op0 = gen_reg_rtx (XFmode);
14219 op1 = gen_reg_rtx (XFmode);
14221 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14222 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14223 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14227 (define_expand "scalbxf3"
14228 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14229 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14230 (match_operand:XF 2 "register_operand" "")]
14231 UNSPEC_FSCALE_FRACT))
14233 (unspec:XF [(match_dup 1) (match_dup 2)]
14234 UNSPEC_FSCALE_EXP))])]
14235 "TARGET_USE_FANCY_MATH_387
14236 && flag_unsafe_math_optimizations"
14238 if (optimize_insn_for_size_p ())
14241 operands[3] = gen_reg_rtx (XFmode);
14244 (define_expand "scalb<mode>3"
14245 [(use (match_operand:MODEF 0 "register_operand" ""))
14246 (use (match_operand:MODEF 1 "general_operand" ""))
14247 (use (match_operand:MODEF 2 "general_operand" ""))]
14248 "TARGET_USE_FANCY_MATH_387
14249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14250 || TARGET_MIX_SSE_I387)
14251 && flag_unsafe_math_optimizations"
14255 if (optimize_insn_for_size_p ())
14258 op0 = gen_reg_rtx (XFmode);
14259 op1 = gen_reg_rtx (XFmode);
14260 op2 = gen_reg_rtx (XFmode);
14262 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14263 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14264 emit_insn (gen_scalbxf3 (op0, op1, op2));
14265 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14269 (define_expand "significandxf2"
14270 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14271 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14272 UNSPEC_XTRACT_FRACT))
14274 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14275 "TARGET_USE_FANCY_MATH_387
14276 && flag_unsafe_math_optimizations"
14277 "operands[2] = gen_reg_rtx (XFmode);")
14279 (define_expand "significand<mode>2"
14280 [(use (match_operand:MODEF 0 "register_operand" ""))
14281 (use (match_operand:MODEF 1 "register_operand" ""))]
14282 "TARGET_USE_FANCY_MATH_387
14283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14284 || TARGET_MIX_SSE_I387)
14285 && flag_unsafe_math_optimizations"
14287 rtx op0 = gen_reg_rtx (XFmode);
14288 rtx op1 = gen_reg_rtx (XFmode);
14290 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14291 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14296 (define_insn "sse4_1_round<mode>2"
14297 [(set (match_operand:MODEF 0 "register_operand" "=x")
14298 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14299 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14302 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14303 [(set_attr "type" "ssecvt")
14304 (set_attr "prefix_extra" "1")
14305 (set_attr "prefix" "maybe_vex")
14306 (set_attr "mode" "<MODE>")])
14308 (define_insn "rintxf2"
14309 [(set (match_operand:XF 0 "register_operand" "=f")
14310 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14312 "TARGET_USE_FANCY_MATH_387
14313 && flag_unsafe_math_optimizations"
14315 [(set_attr "type" "fpspc")
14316 (set_attr "mode" "XF")])
14318 (define_expand "rint<mode>2"
14319 [(use (match_operand:MODEF 0 "register_operand" ""))
14320 (use (match_operand:MODEF 1 "register_operand" ""))]
14321 "(TARGET_USE_FANCY_MATH_387
14322 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14323 || TARGET_MIX_SSE_I387)
14324 && flag_unsafe_math_optimizations)
14325 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14326 && !flag_trapping_math)"
14328 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14329 && !flag_trapping_math)
14331 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14334 emit_insn (gen_sse4_1_round<mode>2
14335 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14337 ix86_expand_rint (operand0, operand1);
14341 rtx op0 = gen_reg_rtx (XFmode);
14342 rtx op1 = gen_reg_rtx (XFmode);
14344 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14345 emit_insn (gen_rintxf2 (op0, op1));
14347 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14352 (define_expand "round<mode>2"
14353 [(match_operand:MODEF 0 "register_operand" "")
14354 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14355 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14356 && !flag_trapping_math && !flag_rounding_math"
14358 if (optimize_insn_for_size_p ())
14360 if (TARGET_64BIT || (<MODE>mode != DFmode))
14361 ix86_expand_round (operand0, operand1);
14363 ix86_expand_rounddf_32 (operand0, operand1);
14367 (define_insn_and_split "*fistdi2_1"
14368 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14369 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14371 "TARGET_USE_FANCY_MATH_387
14372 && can_create_pseudo_p ()"
14377 if (memory_operand (operands[0], VOIDmode))
14378 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14381 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14382 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14387 [(set_attr "type" "fpspc")
14388 (set_attr "mode" "DI")])
14390 (define_insn "fistdi2"
14391 [(set (match_operand:DI 0 "memory_operand" "=m")
14392 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14394 (clobber (match_scratch:XF 2 "=&1f"))]
14395 "TARGET_USE_FANCY_MATH_387"
14396 "* return output_fix_trunc (insn, operands, false);"
14397 [(set_attr "type" "fpspc")
14398 (set_attr "mode" "DI")])
14400 (define_insn "fistdi2_with_temp"
14401 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14402 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14404 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14405 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14406 "TARGET_USE_FANCY_MATH_387"
14408 [(set_attr "type" "fpspc")
14409 (set_attr "mode" "DI")])
14412 [(set (match_operand:DI 0 "register_operand" "")
14413 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14415 (clobber (match_operand:DI 2 "memory_operand" ""))
14416 (clobber (match_scratch 3 ""))]
14418 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14419 (clobber (match_dup 3))])
14420 (set (match_dup 0) (match_dup 2))])
14423 [(set (match_operand:DI 0 "memory_operand" "")
14424 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14426 (clobber (match_operand:DI 2 "memory_operand" ""))
14427 (clobber (match_scratch 3 ""))]
14429 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14430 (clobber (match_dup 3))])])
14432 (define_insn_and_split "*fist<mode>2_1"
14433 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14434 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14436 "TARGET_USE_FANCY_MATH_387
14437 && can_create_pseudo_p ()"
14442 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14443 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14447 [(set_attr "type" "fpspc")
14448 (set_attr "mode" "<MODE>")])
14450 (define_insn "fist<mode>2"
14451 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14452 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14454 "TARGET_USE_FANCY_MATH_387"
14455 "* return output_fix_trunc (insn, operands, false);"
14456 [(set_attr "type" "fpspc")
14457 (set_attr "mode" "<MODE>")])
14459 (define_insn "fist<mode>2_with_temp"
14460 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14461 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14463 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14464 "TARGET_USE_FANCY_MATH_387"
14466 [(set_attr "type" "fpspc")
14467 (set_attr "mode" "<MODE>")])
14470 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14471 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14473 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14475 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14476 (set (match_dup 0) (match_dup 2))])
14479 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14480 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14482 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14484 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14486 (define_expand "lrintxf<mode>2"
14487 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14488 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14490 "TARGET_USE_FANCY_MATH_387")
14492 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14493 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14494 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14495 UNSPEC_FIX_NOTRUNC))]
14496 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14497 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14499 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14500 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14501 (match_operand:MODEF 1 "register_operand" "")]
14502 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14503 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14504 && !flag_trapping_math && !flag_rounding_math"
14506 if (optimize_insn_for_size_p ())
14508 ix86_expand_lround (operand0, operand1);
14512 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14513 (define_insn_and_split "frndintxf2_floor"
14514 [(set (match_operand:XF 0 "register_operand" "")
14515 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14516 UNSPEC_FRNDINT_FLOOR))
14517 (clobber (reg:CC FLAGS_REG))]
14518 "TARGET_USE_FANCY_MATH_387
14519 && flag_unsafe_math_optimizations
14520 && can_create_pseudo_p ()"
14525 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14527 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14528 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14530 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14531 operands[2], operands[3]));
14534 [(set_attr "type" "frndint")
14535 (set_attr "i387_cw" "floor")
14536 (set_attr "mode" "XF")])
14538 (define_insn "frndintxf2_floor_i387"
14539 [(set (match_operand:XF 0 "register_operand" "=f")
14540 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14541 UNSPEC_FRNDINT_FLOOR))
14542 (use (match_operand:HI 2 "memory_operand" "m"))
14543 (use (match_operand:HI 3 "memory_operand" "m"))]
14544 "TARGET_USE_FANCY_MATH_387
14545 && flag_unsafe_math_optimizations"
14546 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14547 [(set_attr "type" "frndint")
14548 (set_attr "i387_cw" "floor")
14549 (set_attr "mode" "XF")])
14551 (define_expand "floorxf2"
14552 [(use (match_operand:XF 0 "register_operand" ""))
14553 (use (match_operand:XF 1 "register_operand" ""))]
14554 "TARGET_USE_FANCY_MATH_387
14555 && flag_unsafe_math_optimizations"
14557 if (optimize_insn_for_size_p ())
14559 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14563 (define_expand "floor<mode>2"
14564 [(use (match_operand:MODEF 0 "register_operand" ""))
14565 (use (match_operand:MODEF 1 "register_operand" ""))]
14566 "(TARGET_USE_FANCY_MATH_387
14567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568 || TARGET_MIX_SSE_I387)
14569 && flag_unsafe_math_optimizations)
14570 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14571 && !flag_trapping_math)"
14573 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14574 && !flag_trapping_math
14575 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14577 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14580 emit_insn (gen_sse4_1_round<mode>2
14581 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14582 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14583 ix86_expand_floorceil (operand0, operand1, true);
14585 ix86_expand_floorceildf_32 (operand0, operand1, true);
14591 if (optimize_insn_for_size_p ())
14594 op0 = gen_reg_rtx (XFmode);
14595 op1 = gen_reg_rtx (XFmode);
14596 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14597 emit_insn (gen_frndintxf2_floor (op0, op1));
14599 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14604 (define_insn_and_split "*fist<mode>2_floor_1"
14605 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14606 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14607 UNSPEC_FIST_FLOOR))
14608 (clobber (reg:CC FLAGS_REG))]
14609 "TARGET_USE_FANCY_MATH_387
14610 && flag_unsafe_math_optimizations
14611 && can_create_pseudo_p ()"
14616 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14618 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14619 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14620 if (memory_operand (operands[0], VOIDmode))
14621 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14622 operands[2], operands[3]));
14625 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14626 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14627 operands[2], operands[3],
14632 [(set_attr "type" "fistp")
14633 (set_attr "i387_cw" "floor")
14634 (set_attr "mode" "<MODE>")])
14636 (define_insn "fistdi2_floor"
14637 [(set (match_operand:DI 0 "memory_operand" "=m")
14638 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14639 UNSPEC_FIST_FLOOR))
14640 (use (match_operand:HI 2 "memory_operand" "m"))
14641 (use (match_operand:HI 3 "memory_operand" "m"))
14642 (clobber (match_scratch:XF 4 "=&1f"))]
14643 "TARGET_USE_FANCY_MATH_387
14644 && flag_unsafe_math_optimizations"
14645 "* return output_fix_trunc (insn, operands, false);"
14646 [(set_attr "type" "fistp")
14647 (set_attr "i387_cw" "floor")
14648 (set_attr "mode" "DI")])
14650 (define_insn "fistdi2_floor_with_temp"
14651 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14652 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14653 UNSPEC_FIST_FLOOR))
14654 (use (match_operand:HI 2 "memory_operand" "m,m"))
14655 (use (match_operand:HI 3 "memory_operand" "m,m"))
14656 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14657 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14658 "TARGET_USE_FANCY_MATH_387
14659 && flag_unsafe_math_optimizations"
14661 [(set_attr "type" "fistp")
14662 (set_attr "i387_cw" "floor")
14663 (set_attr "mode" "DI")])
14666 [(set (match_operand:DI 0 "register_operand" "")
14667 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14668 UNSPEC_FIST_FLOOR))
14669 (use (match_operand:HI 2 "memory_operand" ""))
14670 (use (match_operand:HI 3 "memory_operand" ""))
14671 (clobber (match_operand:DI 4 "memory_operand" ""))
14672 (clobber (match_scratch 5 ""))]
14674 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14675 (use (match_dup 2))
14676 (use (match_dup 3))
14677 (clobber (match_dup 5))])
14678 (set (match_dup 0) (match_dup 4))])
14681 [(set (match_operand:DI 0 "memory_operand" "")
14682 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14683 UNSPEC_FIST_FLOOR))
14684 (use (match_operand:HI 2 "memory_operand" ""))
14685 (use (match_operand:HI 3 "memory_operand" ""))
14686 (clobber (match_operand:DI 4 "memory_operand" ""))
14687 (clobber (match_scratch 5 ""))]
14689 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14690 (use (match_dup 2))
14691 (use (match_dup 3))
14692 (clobber (match_dup 5))])])
14694 (define_insn "fist<mode>2_floor"
14695 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14696 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14697 UNSPEC_FIST_FLOOR))
14698 (use (match_operand:HI 2 "memory_operand" "m"))
14699 (use (match_operand:HI 3 "memory_operand" "m"))]
14700 "TARGET_USE_FANCY_MATH_387
14701 && flag_unsafe_math_optimizations"
14702 "* return output_fix_trunc (insn, operands, false);"
14703 [(set_attr "type" "fistp")
14704 (set_attr "i387_cw" "floor")
14705 (set_attr "mode" "<MODE>")])
14707 (define_insn "fist<mode>2_floor_with_temp"
14708 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14709 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14710 UNSPEC_FIST_FLOOR))
14711 (use (match_operand:HI 2 "memory_operand" "m,m"))
14712 (use (match_operand:HI 3 "memory_operand" "m,m"))
14713 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14714 "TARGET_USE_FANCY_MATH_387
14715 && flag_unsafe_math_optimizations"
14717 [(set_attr "type" "fistp")
14718 (set_attr "i387_cw" "floor")
14719 (set_attr "mode" "<MODE>")])
14722 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14723 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14724 UNSPEC_FIST_FLOOR))
14725 (use (match_operand:HI 2 "memory_operand" ""))
14726 (use (match_operand:HI 3 "memory_operand" ""))
14727 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14729 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14730 UNSPEC_FIST_FLOOR))
14731 (use (match_dup 2))
14732 (use (match_dup 3))])
14733 (set (match_dup 0) (match_dup 4))])
14736 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14737 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14738 UNSPEC_FIST_FLOOR))
14739 (use (match_operand:HI 2 "memory_operand" ""))
14740 (use (match_operand:HI 3 "memory_operand" ""))
14741 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14743 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14744 UNSPEC_FIST_FLOOR))
14745 (use (match_dup 2))
14746 (use (match_dup 3))])])
14748 (define_expand "lfloorxf<mode>2"
14749 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14750 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14751 UNSPEC_FIST_FLOOR))
14752 (clobber (reg:CC FLAGS_REG))])]
14753 "TARGET_USE_FANCY_MATH_387
14754 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14755 && flag_unsafe_math_optimizations")
14757 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14758 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14759 (match_operand:MODEF 1 "register_operand" "")]
14760 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14761 && !flag_trapping_math"
14763 if (TARGET_64BIT && optimize_insn_for_size_p ())
14765 ix86_expand_lfloorceil (operand0, operand1, true);
14769 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14770 (define_insn_and_split "frndintxf2_ceil"
14771 [(set (match_operand:XF 0 "register_operand" "")
14772 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14773 UNSPEC_FRNDINT_CEIL))
14774 (clobber (reg:CC FLAGS_REG))]
14775 "TARGET_USE_FANCY_MATH_387
14776 && flag_unsafe_math_optimizations
14777 && can_create_pseudo_p ()"
14782 ix86_optimize_mode_switching[I387_CEIL] = 1;
14784 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14785 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14787 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14788 operands[2], operands[3]));
14791 [(set_attr "type" "frndint")
14792 (set_attr "i387_cw" "ceil")
14793 (set_attr "mode" "XF")])
14795 (define_insn "frndintxf2_ceil_i387"
14796 [(set (match_operand:XF 0 "register_operand" "=f")
14797 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14798 UNSPEC_FRNDINT_CEIL))
14799 (use (match_operand:HI 2 "memory_operand" "m"))
14800 (use (match_operand:HI 3 "memory_operand" "m"))]
14801 "TARGET_USE_FANCY_MATH_387
14802 && flag_unsafe_math_optimizations"
14803 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14804 [(set_attr "type" "frndint")
14805 (set_attr "i387_cw" "ceil")
14806 (set_attr "mode" "XF")])
14808 (define_expand "ceilxf2"
14809 [(use (match_operand:XF 0 "register_operand" ""))
14810 (use (match_operand:XF 1 "register_operand" ""))]
14811 "TARGET_USE_FANCY_MATH_387
14812 && flag_unsafe_math_optimizations"
14814 if (optimize_insn_for_size_p ())
14816 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14820 (define_expand "ceil<mode>2"
14821 [(use (match_operand:MODEF 0 "register_operand" ""))
14822 (use (match_operand:MODEF 1 "register_operand" ""))]
14823 "(TARGET_USE_FANCY_MATH_387
14824 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14825 || TARGET_MIX_SSE_I387)
14826 && flag_unsafe_math_optimizations)
14827 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14828 && !flag_trapping_math)"
14830 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14831 && !flag_trapping_math
14832 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14835 emit_insn (gen_sse4_1_round<mode>2
14836 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14837 else if (optimize_insn_for_size_p ())
14839 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14840 ix86_expand_floorceil (operand0, operand1, false);
14842 ix86_expand_floorceildf_32 (operand0, operand1, false);
14848 if (optimize_insn_for_size_p ())
14851 op0 = gen_reg_rtx (XFmode);
14852 op1 = gen_reg_rtx (XFmode);
14853 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14854 emit_insn (gen_frndintxf2_ceil (op0, op1));
14856 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14861 (define_insn_and_split "*fist<mode>2_ceil_1"
14862 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14863 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14865 (clobber (reg:CC FLAGS_REG))]
14866 "TARGET_USE_FANCY_MATH_387
14867 && flag_unsafe_math_optimizations
14868 && can_create_pseudo_p ()"
14873 ix86_optimize_mode_switching[I387_CEIL] = 1;
14875 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14876 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14877 if (memory_operand (operands[0], VOIDmode))
14878 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14879 operands[2], operands[3]));
14882 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14883 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14884 operands[2], operands[3],
14889 [(set_attr "type" "fistp")
14890 (set_attr "i387_cw" "ceil")
14891 (set_attr "mode" "<MODE>")])
14893 (define_insn "fistdi2_ceil"
14894 [(set (match_operand:DI 0 "memory_operand" "=m")
14895 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14897 (use (match_operand:HI 2 "memory_operand" "m"))
14898 (use (match_operand:HI 3 "memory_operand" "m"))
14899 (clobber (match_scratch:XF 4 "=&1f"))]
14900 "TARGET_USE_FANCY_MATH_387
14901 && flag_unsafe_math_optimizations"
14902 "* return output_fix_trunc (insn, operands, false);"
14903 [(set_attr "type" "fistp")
14904 (set_attr "i387_cw" "ceil")
14905 (set_attr "mode" "DI")])
14907 (define_insn "fistdi2_ceil_with_temp"
14908 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14909 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14911 (use (match_operand:HI 2 "memory_operand" "m,m"))
14912 (use (match_operand:HI 3 "memory_operand" "m,m"))
14913 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14914 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14915 "TARGET_USE_FANCY_MATH_387
14916 && flag_unsafe_math_optimizations"
14918 [(set_attr "type" "fistp")
14919 (set_attr "i387_cw" "ceil")
14920 (set_attr "mode" "DI")])
14923 [(set (match_operand:DI 0 "register_operand" "")
14924 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14926 (use (match_operand:HI 2 "memory_operand" ""))
14927 (use (match_operand:HI 3 "memory_operand" ""))
14928 (clobber (match_operand:DI 4 "memory_operand" ""))
14929 (clobber (match_scratch 5 ""))]
14931 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14932 (use (match_dup 2))
14933 (use (match_dup 3))
14934 (clobber (match_dup 5))])
14935 (set (match_dup 0) (match_dup 4))])
14938 [(set (match_operand:DI 0 "memory_operand" "")
14939 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14941 (use (match_operand:HI 2 "memory_operand" ""))
14942 (use (match_operand:HI 3 "memory_operand" ""))
14943 (clobber (match_operand:DI 4 "memory_operand" ""))
14944 (clobber (match_scratch 5 ""))]
14946 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14947 (use (match_dup 2))
14948 (use (match_dup 3))
14949 (clobber (match_dup 5))])])
14951 (define_insn "fist<mode>2_ceil"
14952 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14953 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14955 (use (match_operand:HI 2 "memory_operand" "m"))
14956 (use (match_operand:HI 3 "memory_operand" "m"))]
14957 "TARGET_USE_FANCY_MATH_387
14958 && flag_unsafe_math_optimizations"
14959 "* return output_fix_trunc (insn, operands, false);"
14960 [(set_attr "type" "fistp")
14961 (set_attr "i387_cw" "ceil")
14962 (set_attr "mode" "<MODE>")])
14964 (define_insn "fist<mode>2_ceil_with_temp"
14965 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14966 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14968 (use (match_operand:HI 2 "memory_operand" "m,m"))
14969 (use (match_operand:HI 3 "memory_operand" "m,m"))
14970 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14971 "TARGET_USE_FANCY_MATH_387
14972 && flag_unsafe_math_optimizations"
14974 [(set_attr "type" "fistp")
14975 (set_attr "i387_cw" "ceil")
14976 (set_attr "mode" "<MODE>")])
14979 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14980 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14982 (use (match_operand:HI 2 "memory_operand" ""))
14983 (use (match_operand:HI 3 "memory_operand" ""))
14984 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14986 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14988 (use (match_dup 2))
14989 (use (match_dup 3))])
14990 (set (match_dup 0) (match_dup 4))])
14993 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14994 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14996 (use (match_operand:HI 2 "memory_operand" ""))
14997 (use (match_operand:HI 3 "memory_operand" ""))
14998 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15000 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15002 (use (match_dup 2))
15003 (use (match_dup 3))])])
15005 (define_expand "lceilxf<mode>2"
15006 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15007 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15009 (clobber (reg:CC FLAGS_REG))])]
15010 "TARGET_USE_FANCY_MATH_387
15011 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15012 && flag_unsafe_math_optimizations")
15014 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15015 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15016 (match_operand:MODEF 1 "register_operand" "")]
15017 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15018 && !flag_trapping_math"
15020 ix86_expand_lfloorceil (operand0, operand1, false);
15024 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15025 (define_insn_and_split "frndintxf2_trunc"
15026 [(set (match_operand:XF 0 "register_operand" "")
15027 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15028 UNSPEC_FRNDINT_TRUNC))
15029 (clobber (reg:CC FLAGS_REG))]
15030 "TARGET_USE_FANCY_MATH_387
15031 && flag_unsafe_math_optimizations
15032 && can_create_pseudo_p ()"
15037 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15039 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15040 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15042 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15043 operands[2], operands[3]));
15046 [(set_attr "type" "frndint")
15047 (set_attr "i387_cw" "trunc")
15048 (set_attr "mode" "XF")])
15050 (define_insn "frndintxf2_trunc_i387"
15051 [(set (match_operand:XF 0 "register_operand" "=f")
15052 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15053 UNSPEC_FRNDINT_TRUNC))
15054 (use (match_operand:HI 2 "memory_operand" "m"))
15055 (use (match_operand:HI 3 "memory_operand" "m"))]
15056 "TARGET_USE_FANCY_MATH_387
15057 && flag_unsafe_math_optimizations"
15058 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15059 [(set_attr "type" "frndint")
15060 (set_attr "i387_cw" "trunc")
15061 (set_attr "mode" "XF")])
15063 (define_expand "btruncxf2"
15064 [(use (match_operand:XF 0 "register_operand" ""))
15065 (use (match_operand:XF 1 "register_operand" ""))]
15066 "TARGET_USE_FANCY_MATH_387
15067 && flag_unsafe_math_optimizations"
15069 if (optimize_insn_for_size_p ())
15071 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15075 (define_expand "btrunc<mode>2"
15076 [(use (match_operand:MODEF 0 "register_operand" ""))
15077 (use (match_operand:MODEF 1 "register_operand" ""))]
15078 "(TARGET_USE_FANCY_MATH_387
15079 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15080 || TARGET_MIX_SSE_I387)
15081 && flag_unsafe_math_optimizations)
15082 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15083 && !flag_trapping_math)"
15085 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15086 && !flag_trapping_math
15087 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15090 emit_insn (gen_sse4_1_round<mode>2
15091 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15092 else if (optimize_insn_for_size_p ())
15094 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15095 ix86_expand_trunc (operand0, operand1);
15097 ix86_expand_truncdf_32 (operand0, operand1);
15103 if (optimize_insn_for_size_p ())
15106 op0 = gen_reg_rtx (XFmode);
15107 op1 = gen_reg_rtx (XFmode);
15108 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15109 emit_insn (gen_frndintxf2_trunc (op0, op1));
15111 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15116 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15117 (define_insn_and_split "frndintxf2_mask_pm"
15118 [(set (match_operand:XF 0 "register_operand" "")
15119 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15120 UNSPEC_FRNDINT_MASK_PM))
15121 (clobber (reg:CC FLAGS_REG))]
15122 "TARGET_USE_FANCY_MATH_387
15123 && flag_unsafe_math_optimizations
15124 && can_create_pseudo_p ()"
15129 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15131 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15132 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15134 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15135 operands[2], operands[3]));
15138 [(set_attr "type" "frndint")
15139 (set_attr "i387_cw" "mask_pm")
15140 (set_attr "mode" "XF")])
15142 (define_insn "frndintxf2_mask_pm_i387"
15143 [(set (match_operand:XF 0 "register_operand" "=f")
15144 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15145 UNSPEC_FRNDINT_MASK_PM))
15146 (use (match_operand:HI 2 "memory_operand" "m"))
15147 (use (match_operand:HI 3 "memory_operand" "m"))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations"
15150 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15151 [(set_attr "type" "frndint")
15152 (set_attr "i387_cw" "mask_pm")
15153 (set_attr "mode" "XF")])
15155 (define_expand "nearbyintxf2"
15156 [(use (match_operand:XF 0 "register_operand" ""))
15157 (use (match_operand:XF 1 "register_operand" ""))]
15158 "TARGET_USE_FANCY_MATH_387
15159 && flag_unsafe_math_optimizations"
15161 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15165 (define_expand "nearbyint<mode>2"
15166 [(use (match_operand:MODEF 0 "register_operand" ""))
15167 (use (match_operand:MODEF 1 "register_operand" ""))]
15168 "TARGET_USE_FANCY_MATH_387
15169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15170 || TARGET_MIX_SSE_I387)
15171 && flag_unsafe_math_optimizations"
15173 rtx op0 = gen_reg_rtx (XFmode);
15174 rtx op1 = gen_reg_rtx (XFmode);
15176 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15177 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15179 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15183 (define_insn "fxam<mode>2_i387"
15184 [(set (match_operand:HI 0 "register_operand" "=a")
15186 [(match_operand:X87MODEF 1 "register_operand" "f")]
15188 "TARGET_USE_FANCY_MATH_387"
15189 "fxam\n\tfnstsw\t%0"
15190 [(set_attr "type" "multi")
15191 (set_attr "length" "4")
15192 (set_attr "unit" "i387")
15193 (set_attr "mode" "<MODE>")])
15195 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15196 [(set (match_operand:HI 0 "register_operand" "")
15198 [(match_operand:MODEF 1 "memory_operand" "")]
15200 "TARGET_USE_FANCY_MATH_387
15201 && can_create_pseudo_p ()"
15204 [(set (match_dup 2)(match_dup 1))
15206 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15208 operands[2] = gen_reg_rtx (<MODE>mode);
15210 MEM_VOLATILE_P (operands[1]) = 1;
15212 [(set_attr "type" "multi")
15213 (set_attr "unit" "i387")
15214 (set_attr "mode" "<MODE>")])
15216 (define_expand "isinfxf2"
15217 [(use (match_operand:SI 0 "register_operand" ""))
15218 (use (match_operand:XF 1 "register_operand" ""))]
15219 "TARGET_USE_FANCY_MATH_387
15220 && TARGET_C99_FUNCTIONS"
15222 rtx mask = GEN_INT (0x45);
15223 rtx val = GEN_INT (0x05);
15227 rtx scratch = gen_reg_rtx (HImode);
15228 rtx res = gen_reg_rtx (QImode);
15230 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15232 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15233 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15234 cond = gen_rtx_fmt_ee (EQ, QImode,
15235 gen_rtx_REG (CCmode, FLAGS_REG),
15237 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15238 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15242 (define_expand "isinf<mode>2"
15243 [(use (match_operand:SI 0 "register_operand" ""))
15244 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15245 "TARGET_USE_FANCY_MATH_387
15246 && TARGET_C99_FUNCTIONS
15247 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15249 rtx mask = GEN_INT (0x45);
15250 rtx val = GEN_INT (0x05);
15254 rtx scratch = gen_reg_rtx (HImode);
15255 rtx res = gen_reg_rtx (QImode);
15257 /* Remove excess precision by forcing value through memory. */
15258 if (memory_operand (operands[1], VOIDmode))
15259 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15262 enum ix86_stack_slot slot = (virtuals_instantiated
15265 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15267 emit_move_insn (temp, operands[1]);
15268 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15271 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15272 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15273 cond = gen_rtx_fmt_ee (EQ, QImode,
15274 gen_rtx_REG (CCmode, FLAGS_REG),
15276 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15277 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15281 (define_expand "signbitxf2"
15282 [(use (match_operand:SI 0 "register_operand" ""))
15283 (use (match_operand:XF 1 "register_operand" ""))]
15284 "TARGET_USE_FANCY_MATH_387"
15286 rtx scratch = gen_reg_rtx (HImode);
15288 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15289 emit_insn (gen_andsi3 (operands[0],
15290 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15294 (define_insn "movmsk_df"
15295 [(set (match_operand:SI 0 "register_operand" "=r")
15297 [(match_operand:DF 1 "register_operand" "x")]
15299 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15300 "%vmovmskpd\t{%1, %0|%0, %1}"
15301 [(set_attr "type" "ssemov")
15302 (set_attr "prefix" "maybe_vex")
15303 (set_attr "mode" "DF")])
15305 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15306 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15307 (define_expand "signbitdf2"
15308 [(use (match_operand:SI 0 "register_operand" ""))
15309 (use (match_operand:DF 1 "register_operand" ""))]
15310 "TARGET_USE_FANCY_MATH_387
15311 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15313 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15315 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15316 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15320 rtx scratch = gen_reg_rtx (HImode);
15322 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15323 emit_insn (gen_andsi3 (operands[0],
15324 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15329 (define_expand "signbitsf2"
15330 [(use (match_operand:SI 0 "register_operand" ""))
15331 (use (match_operand:SF 1 "register_operand" ""))]
15332 "TARGET_USE_FANCY_MATH_387
15333 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15335 rtx scratch = gen_reg_rtx (HImode);
15337 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15338 emit_insn (gen_andsi3 (operands[0],
15339 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15343 ;; Block operation instructions
15346 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15349 [(set_attr "length" "1")
15350 (set_attr "length_immediate" "0")
15351 (set_attr "modrm" "0")])
15353 (define_expand "movmem<mode>"
15354 [(use (match_operand:BLK 0 "memory_operand" ""))
15355 (use (match_operand:BLK 1 "memory_operand" ""))
15356 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15357 (use (match_operand:SWI48 3 "const_int_operand" ""))
15358 (use (match_operand:SI 4 "const_int_operand" ""))
15359 (use (match_operand:SI 5 "const_int_operand" ""))]
15362 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15363 operands[4], operands[5]))
15369 ;; Most CPUs don't like single string operations
15370 ;; Handle this case here to simplify previous expander.
15372 (define_expand "strmov"
15373 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15374 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15375 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15376 (clobber (reg:CC FLAGS_REG))])
15377 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15378 (clobber (reg:CC FLAGS_REG))])]
15381 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15383 /* If .md ever supports :P for Pmode, these can be directly
15384 in the pattern above. */
15385 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15386 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15388 /* Can't use this if the user has appropriated esi or edi. */
15389 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15390 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15392 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15393 operands[2], operands[3],
15394 operands[5], operands[6]));
15398 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15401 (define_expand "strmov_singleop"
15402 [(parallel [(set (match_operand 1 "memory_operand" "")
15403 (match_operand 3 "memory_operand" ""))
15404 (set (match_operand 0 "register_operand" "")
15405 (match_operand 4 "" ""))
15406 (set (match_operand 2 "register_operand" "")
15407 (match_operand 5 "" ""))])]
15409 "ix86_current_function_needs_cld = 1;")
15411 (define_insn "*strmovdi_rex_1"
15412 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15413 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15414 (set (match_operand:DI 0 "register_operand" "=D")
15415 (plus:DI (match_dup 2)
15417 (set (match_operand:DI 1 "register_operand" "=S")
15418 (plus:DI (match_dup 3)
15422 [(set_attr "type" "str")
15423 (set_attr "memory" "both")
15424 (set_attr "mode" "DI")])
15426 (define_insn "*strmovsi_1"
15427 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15428 (mem:SI (match_operand:P 3 "register_operand" "1")))
15429 (set (match_operand:P 0 "register_operand" "=D")
15430 (plus:P (match_dup 2)
15432 (set (match_operand:P 1 "register_operand" "=S")
15433 (plus:P (match_dup 3)
15437 [(set_attr "type" "str")
15438 (set_attr "memory" "both")
15439 (set_attr "mode" "SI")])
15441 (define_insn "*strmovhi_1"
15442 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15443 (mem:HI (match_operand:P 3 "register_operand" "1")))
15444 (set (match_operand:P 0 "register_operand" "=D")
15445 (plus:P (match_dup 2)
15447 (set (match_operand:P 1 "register_operand" "=S")
15448 (plus:P (match_dup 3)
15452 [(set_attr "type" "str")
15453 (set_attr "memory" "both")
15454 (set_attr "mode" "HI")])
15456 (define_insn "*strmovqi_1"
15457 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15458 (mem:QI (match_operand:P 3 "register_operand" "1")))
15459 (set (match_operand:P 0 "register_operand" "=D")
15460 (plus:P (match_dup 2)
15462 (set (match_operand:P 1 "register_operand" "=S")
15463 (plus:P (match_dup 3)
15467 [(set_attr "type" "str")
15468 (set_attr "memory" "both")
15469 (set (attr "prefix_rex")
15471 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15473 (const_string "*")))
15474 (set_attr "mode" "QI")])
15476 (define_expand "rep_mov"
15477 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15478 (set (match_operand 0 "register_operand" "")
15479 (match_operand 5 "" ""))
15480 (set (match_operand 2 "register_operand" "")
15481 (match_operand 6 "" ""))
15482 (set (match_operand 1 "memory_operand" "")
15483 (match_operand 3 "memory_operand" ""))
15484 (use (match_dup 4))])]
15486 "ix86_current_function_needs_cld = 1;")
15488 (define_insn "*rep_movdi_rex64"
15489 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15490 (set (match_operand:DI 0 "register_operand" "=D")
15491 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15493 (match_operand:DI 3 "register_operand" "0")))
15494 (set (match_operand:DI 1 "register_operand" "=S")
15495 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15496 (match_operand:DI 4 "register_operand" "1")))
15497 (set (mem:BLK (match_dup 3))
15498 (mem:BLK (match_dup 4)))
15499 (use (match_dup 5))]
15502 [(set_attr "type" "str")
15503 (set_attr "prefix_rep" "1")
15504 (set_attr "memory" "both")
15505 (set_attr "mode" "DI")])
15507 (define_insn "*rep_movsi"
15508 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15509 (set (match_operand:P 0 "register_operand" "=D")
15510 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15512 (match_operand:P 3 "register_operand" "0")))
15513 (set (match_operand:P 1 "register_operand" "=S")
15514 (plus:P (ashift:P (match_dup 5) (const_int 2))
15515 (match_operand:P 4 "register_operand" "1")))
15516 (set (mem:BLK (match_dup 3))
15517 (mem:BLK (match_dup 4)))
15518 (use (match_dup 5))]
15520 "rep{%;} movs{l|d}"
15521 [(set_attr "type" "str")
15522 (set_attr "prefix_rep" "1")
15523 (set_attr "memory" "both")
15524 (set_attr "mode" "SI")])
15526 (define_insn "*rep_movqi"
15527 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15528 (set (match_operand:P 0 "register_operand" "=D")
15529 (plus:P (match_operand:P 3 "register_operand" "0")
15530 (match_operand:P 5 "register_operand" "2")))
15531 (set (match_operand:P 1 "register_operand" "=S")
15532 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15533 (set (mem:BLK (match_dup 3))
15534 (mem:BLK (match_dup 4)))
15535 (use (match_dup 5))]
15538 [(set_attr "type" "str")
15539 (set_attr "prefix_rep" "1")
15540 (set_attr "memory" "both")
15541 (set_attr "mode" "QI")])
15543 (define_expand "setmem<mode>"
15544 [(use (match_operand:BLK 0 "memory_operand" ""))
15545 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15546 (use (match_operand:QI 2 "nonmemory_operand" ""))
15547 (use (match_operand 3 "const_int_operand" ""))
15548 (use (match_operand:SI 4 "const_int_operand" ""))
15549 (use (match_operand:SI 5 "const_int_operand" ""))]
15552 if (ix86_expand_setmem (operands[0], operands[1],
15553 operands[2], operands[3],
15554 operands[4], operands[5]))
15560 ;; Most CPUs don't like single string operations
15561 ;; Handle this case here to simplify previous expander.
15563 (define_expand "strset"
15564 [(set (match_operand 1 "memory_operand" "")
15565 (match_operand 2 "register_operand" ""))
15566 (parallel [(set (match_operand 0 "register_operand" "")
15568 (clobber (reg:CC FLAGS_REG))])]
15571 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15572 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15574 /* If .md ever supports :P for Pmode, this can be directly
15575 in the pattern above. */
15576 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15577 GEN_INT (GET_MODE_SIZE (GET_MODE
15579 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15581 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15587 (define_expand "strset_singleop"
15588 [(parallel [(set (match_operand 1 "memory_operand" "")
15589 (match_operand 2 "register_operand" ""))
15590 (set (match_operand 0 "register_operand" "")
15591 (match_operand 3 "" ""))])]
15593 "ix86_current_function_needs_cld = 1;")
15595 (define_insn "*strsetdi_rex_1"
15596 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15597 (match_operand:DI 2 "register_operand" "a"))
15598 (set (match_operand:DI 0 "register_operand" "=D")
15599 (plus:DI (match_dup 1)
15603 [(set_attr "type" "str")
15604 (set_attr "memory" "store")
15605 (set_attr "mode" "DI")])
15607 (define_insn "*strsetsi_1"
15608 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15609 (match_operand:SI 2 "register_operand" "a"))
15610 (set (match_operand:P 0 "register_operand" "=D")
15611 (plus:P (match_dup 1)
15615 [(set_attr "type" "str")
15616 (set_attr "memory" "store")
15617 (set_attr "mode" "SI")])
15619 (define_insn "*strsethi_1"
15620 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15621 (match_operand:HI 2 "register_operand" "a"))
15622 (set (match_operand:P 0 "register_operand" "=D")
15623 (plus:P (match_dup 1)
15627 [(set_attr "type" "str")
15628 (set_attr "memory" "store")
15629 (set_attr "mode" "HI")])
15631 (define_insn "*strsetqi_1"
15632 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15633 (match_operand:QI 2 "register_operand" "a"))
15634 (set (match_operand:P 0 "register_operand" "=D")
15635 (plus:P (match_dup 1)
15639 [(set_attr "type" "str")
15640 (set_attr "memory" "store")
15641 (set (attr "prefix_rex")
15643 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15645 (const_string "*")))
15646 (set_attr "mode" "QI")])
15648 (define_expand "rep_stos"
15649 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15650 (set (match_operand 0 "register_operand" "")
15651 (match_operand 4 "" ""))
15652 (set (match_operand 2 "memory_operand" "") (const_int 0))
15653 (use (match_operand 3 "register_operand" ""))
15654 (use (match_dup 1))])]
15656 "ix86_current_function_needs_cld = 1;")
15658 (define_insn "*rep_stosdi_rex64"
15659 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15660 (set (match_operand:DI 0 "register_operand" "=D")
15661 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15663 (match_operand:DI 3 "register_operand" "0")))
15664 (set (mem:BLK (match_dup 3))
15666 (use (match_operand:DI 2 "register_operand" "a"))
15667 (use (match_dup 4))]
15670 [(set_attr "type" "str")
15671 (set_attr "prefix_rep" "1")
15672 (set_attr "memory" "store")
15673 (set_attr "mode" "DI")])
15675 (define_insn "*rep_stossi"
15676 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15677 (set (match_operand:P 0 "register_operand" "=D")
15678 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15680 (match_operand:P 3 "register_operand" "0")))
15681 (set (mem:BLK (match_dup 3))
15683 (use (match_operand:SI 2 "register_operand" "a"))
15684 (use (match_dup 4))]
15686 "rep{%;} stos{l|d}"
15687 [(set_attr "type" "str")
15688 (set_attr "prefix_rep" "1")
15689 (set_attr "memory" "store")
15690 (set_attr "mode" "SI")])
15692 (define_insn "*rep_stosqi"
15693 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15694 (set (match_operand:P 0 "register_operand" "=D")
15695 (plus:P (match_operand:P 3 "register_operand" "0")
15696 (match_operand:P 4 "register_operand" "1")))
15697 (set (mem:BLK (match_dup 3))
15699 (use (match_operand:QI 2 "register_operand" "a"))
15700 (use (match_dup 4))]
15703 [(set_attr "type" "str")
15704 (set_attr "prefix_rep" "1")
15705 (set_attr "memory" "store")
15706 (set (attr "prefix_rex")
15708 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15710 (const_string "*")))
15711 (set_attr "mode" "QI")])
15713 (define_expand "cmpstrnsi"
15714 [(set (match_operand:SI 0 "register_operand" "")
15715 (compare:SI (match_operand:BLK 1 "general_operand" "")
15716 (match_operand:BLK 2 "general_operand" "")))
15717 (use (match_operand 3 "general_operand" ""))
15718 (use (match_operand 4 "immediate_operand" ""))]
15721 rtx addr1, addr2, out, outlow, count, countreg, align;
15723 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15726 /* Can't use this if the user has appropriated esi or edi. */
15727 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15732 out = gen_reg_rtx (SImode);
15734 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15735 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15736 if (addr1 != XEXP (operands[1], 0))
15737 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15738 if (addr2 != XEXP (operands[2], 0))
15739 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15741 count = operands[3];
15742 countreg = ix86_zero_extend_to_Pmode (count);
15744 /* %%% Iff we are testing strict equality, we can use known alignment
15745 to good advantage. This may be possible with combine, particularly
15746 once cc0 is dead. */
15747 align = operands[4];
15749 if (CONST_INT_P (count))
15751 if (INTVAL (count) == 0)
15753 emit_move_insn (operands[0], const0_rtx);
15756 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15757 operands[1], operands[2]));
15761 rtx (*gen_cmp) (rtx, rtx);
15763 gen_cmp = (TARGET_64BIT
15764 ? gen_cmpdi_1 : gen_cmpsi_1);
15766 emit_insn (gen_cmp (countreg, countreg));
15767 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15768 operands[1], operands[2]));
15771 outlow = gen_lowpart (QImode, out);
15772 emit_insn (gen_cmpintqi (outlow));
15773 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15775 if (operands[0] != out)
15776 emit_move_insn (operands[0], out);
15781 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15783 (define_expand "cmpintqi"
15784 [(set (match_dup 1)
15785 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15787 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15788 (parallel [(set (match_operand:QI 0 "register_operand" "")
15789 (minus:QI (match_dup 1)
15791 (clobber (reg:CC FLAGS_REG))])]
15794 operands[1] = gen_reg_rtx (QImode);
15795 operands[2] = gen_reg_rtx (QImode);
15798 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15799 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15801 (define_expand "cmpstrnqi_nz_1"
15802 [(parallel [(set (reg:CC FLAGS_REG)
15803 (compare:CC (match_operand 4 "memory_operand" "")
15804 (match_operand 5 "memory_operand" "")))
15805 (use (match_operand 2 "register_operand" ""))
15806 (use (match_operand:SI 3 "immediate_operand" ""))
15807 (clobber (match_operand 0 "register_operand" ""))
15808 (clobber (match_operand 1 "register_operand" ""))
15809 (clobber (match_dup 2))])]
15811 "ix86_current_function_needs_cld = 1;")
15813 (define_insn "*cmpstrnqi_nz_1"
15814 [(set (reg:CC FLAGS_REG)
15815 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15816 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15817 (use (match_operand:P 6 "register_operand" "2"))
15818 (use (match_operand:SI 3 "immediate_operand" "i"))
15819 (clobber (match_operand:P 0 "register_operand" "=S"))
15820 (clobber (match_operand:P 1 "register_operand" "=D"))
15821 (clobber (match_operand:P 2 "register_operand" "=c"))]
15824 [(set_attr "type" "str")
15825 (set_attr "mode" "QI")
15826 (set (attr "prefix_rex")
15828 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15830 (const_string "*")))
15831 (set_attr "prefix_rep" "1")])
15833 ;; The same, but the count is not known to not be zero.
15835 (define_expand "cmpstrnqi_1"
15836 [(parallel [(set (reg:CC FLAGS_REG)
15837 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15839 (compare:CC (match_operand 4 "memory_operand" "")
15840 (match_operand 5 "memory_operand" ""))
15842 (use (match_operand:SI 3 "immediate_operand" ""))
15843 (use (reg:CC FLAGS_REG))
15844 (clobber (match_operand 0 "register_operand" ""))
15845 (clobber (match_operand 1 "register_operand" ""))
15846 (clobber (match_dup 2))])]
15848 "ix86_current_function_needs_cld = 1;")
15850 (define_insn "*cmpstrnqi_1"
15851 [(set (reg:CC FLAGS_REG)
15852 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15854 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15855 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15857 (use (match_operand:SI 3 "immediate_operand" "i"))
15858 (use (reg:CC FLAGS_REG))
15859 (clobber (match_operand:P 0 "register_operand" "=S"))
15860 (clobber (match_operand:P 1 "register_operand" "=D"))
15861 (clobber (match_operand:P 2 "register_operand" "=c"))]
15864 [(set_attr "type" "str")
15865 (set_attr "mode" "QI")
15866 (set (attr "prefix_rex")
15868 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15870 (const_string "*")))
15871 (set_attr "prefix_rep" "1")])
15873 (define_expand "strlen<mode>"
15874 [(set (match_operand:SWI48x 0 "register_operand" "")
15875 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15876 (match_operand:QI 2 "immediate_operand" "")
15877 (match_operand 3 "immediate_operand" "")]
15881 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15887 (define_expand "strlenqi_1"
15888 [(parallel [(set (match_operand 0 "register_operand" "")
15889 (match_operand 2 "" ""))
15890 (clobber (match_operand 1 "register_operand" ""))
15891 (clobber (reg:CC FLAGS_REG))])]
15893 "ix86_current_function_needs_cld = 1;")
15895 (define_insn "*strlenqi_1"
15896 [(set (match_operand:P 0 "register_operand" "=&c")
15897 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15898 (match_operand:QI 2 "register_operand" "a")
15899 (match_operand:P 3 "immediate_operand" "i")
15900 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15901 (clobber (match_operand:P 1 "register_operand" "=D"))
15902 (clobber (reg:CC FLAGS_REG))]
15905 [(set_attr "type" "str")
15906 (set_attr "mode" "QI")
15907 (set (attr "prefix_rex")
15909 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15911 (const_string "*")))
15912 (set_attr "prefix_rep" "1")])
15914 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15915 ;; handled in combine, but it is not currently up to the task.
15916 ;; When used for their truth value, the cmpstrn* expanders generate
15925 ;; The intermediate three instructions are unnecessary.
15927 ;; This one handles cmpstrn*_nz_1...
15930 (set (reg:CC FLAGS_REG)
15931 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15932 (mem:BLK (match_operand 5 "register_operand" ""))))
15933 (use (match_operand 6 "register_operand" ""))
15934 (use (match_operand:SI 3 "immediate_operand" ""))
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 (compare:CC (mem:BLK (match_dup 4))
15949 (mem:BLK (match_dup 5))))
15950 (use (match_dup 6))
15951 (use (match_dup 3))
15952 (clobber (match_dup 0))
15953 (clobber (match_dup 1))
15954 (clobber (match_dup 2))])])
15956 ;; ...and this one handles cmpstrn*_1.
15959 (set (reg:CC FLAGS_REG)
15960 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15962 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15963 (mem:BLK (match_operand 5 "register_operand" "")))
15965 (use (match_operand:SI 3 "immediate_operand" ""))
15966 (use (reg:CC FLAGS_REG))
15967 (clobber (match_operand 0 "register_operand" ""))
15968 (clobber (match_operand 1 "register_operand" ""))
15969 (clobber (match_operand 2 "register_operand" ""))])
15970 (set (match_operand:QI 7 "register_operand" "")
15971 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15972 (set (match_operand:QI 8 "register_operand" "")
15973 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15974 (set (reg FLAGS_REG)
15975 (compare (match_dup 7) (match_dup 8)))
15977 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15979 (set (reg:CC FLAGS_REG)
15980 (if_then_else:CC (ne (match_dup 6)
15982 (compare:CC (mem:BLK (match_dup 4))
15983 (mem:BLK (match_dup 5)))
15985 (use (match_dup 3))
15986 (use (reg:CC FLAGS_REG))
15987 (clobber (match_dup 0))
15988 (clobber (match_dup 1))
15989 (clobber (match_dup 2))])])
15991 ;; Conditional move instructions.
15993 (define_expand "mov<mode>cc"
15994 [(set (match_operand:SWIM 0 "register_operand" "")
15995 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15996 (match_operand:SWIM 2 "general_operand" "")
15997 (match_operand:SWIM 3 "general_operand" "")))]
15999 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16001 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16002 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16003 ;; So just document what we're doing explicitly.
16005 (define_expand "x86_mov<mode>cc_0_m1"
16007 [(set (match_operand:SWI48 0 "register_operand" "")
16008 (if_then_else:SWI48
16009 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16010 [(match_operand 1 "flags_reg_operand" "")
16014 (clobber (reg:CC FLAGS_REG))])])
16016 (define_insn "*x86_mov<mode>cc_0_m1"
16017 [(set (match_operand:SWI48 0 "register_operand" "=r")
16018 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16019 [(reg FLAGS_REG) (const_int 0)])
16022 (clobber (reg:CC FLAGS_REG))]
16024 "sbb{<imodesuffix>}\t%0, %0"
16025 ; Since we don't have the proper number of operands for an alu insn,
16026 ; fill in all the blanks.
16027 [(set_attr "type" "alu")
16028 (set_attr "use_carry" "1")
16029 (set_attr "pent_pair" "pu")
16030 (set_attr "memory" "none")
16031 (set_attr "imm_disp" "false")
16032 (set_attr "mode" "<MODE>")
16033 (set_attr "length_immediate" "0")])
16035 (define_insn "*x86_mov<mode>cc_0_m1_se"
16036 [(set (match_operand:SWI48 0 "register_operand" "=r")
16037 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16038 [(reg FLAGS_REG) (const_int 0)])
16041 (clobber (reg:CC FLAGS_REG))]
16043 "sbb{<imodesuffix>}\t%0, %0"
16044 [(set_attr "type" "alu")
16045 (set_attr "use_carry" "1")
16046 (set_attr "pent_pair" "pu")
16047 (set_attr "memory" "none")
16048 (set_attr "imm_disp" "false")
16049 (set_attr "mode" "<MODE>")
16050 (set_attr "length_immediate" "0")])
16052 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16053 [(set (match_operand:SWI48 0 "register_operand" "=r")
16054 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16055 [(reg FLAGS_REG) (const_int 0)])))]
16057 "sbb{<imodesuffix>}\t%0, %0"
16058 [(set_attr "type" "alu")
16059 (set_attr "use_carry" "1")
16060 (set_attr "pent_pair" "pu")
16061 (set_attr "memory" "none")
16062 (set_attr "imm_disp" "false")
16063 (set_attr "mode" "<MODE>")
16064 (set_attr "length_immediate" "0")])
16066 (define_insn "*mov<mode>cc_noc"
16067 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16068 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16069 [(reg FLAGS_REG) (const_int 0)])
16070 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16071 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16072 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16074 cmov%O2%C1\t{%2, %0|%0, %2}
16075 cmov%O2%c1\t{%3, %0|%0, %3}"
16076 [(set_attr "type" "icmov")
16077 (set_attr "mode" "<MODE>")])
16079 (define_insn_and_split "*movqicc_noc"
16080 [(set (match_operand:QI 0 "register_operand" "=r,r")
16081 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16082 [(match_operand 4 "flags_reg_operand" "")
16084 (match_operand:QI 2 "register_operand" "r,0")
16085 (match_operand:QI 3 "register_operand" "0,r")))]
16086 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16088 "&& reload_completed"
16089 [(set (match_dup 0)
16090 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16093 "operands[0] = gen_lowpart (SImode, operands[0]);
16094 operands[2] = gen_lowpart (SImode, operands[2]);
16095 operands[3] = gen_lowpart (SImode, operands[3]);"
16096 [(set_attr "type" "icmov")
16097 (set_attr "mode" "SI")])
16099 (define_expand "mov<mode>cc"
16100 [(set (match_operand:X87MODEF 0 "register_operand" "")
16101 (if_then_else:X87MODEF
16102 (match_operand 1 "ix86_fp_comparison_operator" "")
16103 (match_operand:X87MODEF 2 "register_operand" "")
16104 (match_operand:X87MODEF 3 "register_operand" "")))]
16105 "(TARGET_80387 && TARGET_CMOVE)
16106 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16107 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16109 (define_insn "*movxfcc_1"
16110 [(set (match_operand:XF 0 "register_operand" "=f,f")
16111 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16112 [(reg FLAGS_REG) (const_int 0)])
16113 (match_operand:XF 2 "register_operand" "f,0")
16114 (match_operand:XF 3 "register_operand" "0,f")))]
16115 "TARGET_80387 && TARGET_CMOVE"
16117 fcmov%F1\t{%2, %0|%0, %2}
16118 fcmov%f1\t{%3, %0|%0, %3}"
16119 [(set_attr "type" "fcmov")
16120 (set_attr "mode" "XF")])
16122 (define_insn "*movdfcc_1_rex64"
16123 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16124 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16125 [(reg FLAGS_REG) (const_int 0)])
16126 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16127 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16128 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16129 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16131 fcmov%F1\t{%2, %0|%0, %2}
16132 fcmov%f1\t{%3, %0|%0, %3}
16133 cmov%O2%C1\t{%2, %0|%0, %2}
16134 cmov%O2%c1\t{%3, %0|%0, %3}"
16135 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16136 (set_attr "mode" "DF,DF,DI,DI")])
16138 (define_insn "*movdfcc_1"
16139 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16140 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16141 [(reg FLAGS_REG) (const_int 0)])
16142 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16143 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16144 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16145 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16147 fcmov%F1\t{%2, %0|%0, %2}
16148 fcmov%f1\t{%3, %0|%0, %3}
16151 [(set_attr "type" "fcmov,fcmov,multi,multi")
16152 (set_attr "mode" "DF,DF,DI,DI")])
16155 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16156 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16157 [(match_operand 4 "flags_reg_operand" "")
16159 (match_operand:DF 2 "nonimmediate_operand" "")
16160 (match_operand:DF 3 "nonimmediate_operand" "")))]
16161 "!TARGET_64BIT && reload_completed"
16162 [(set (match_dup 2)
16163 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16167 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16171 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16172 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16175 (define_insn "*movsfcc_1_387"
16176 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16177 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16178 [(reg FLAGS_REG) (const_int 0)])
16179 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16180 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16181 "TARGET_80387 && TARGET_CMOVE
16182 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16184 fcmov%F1\t{%2, %0|%0, %2}
16185 fcmov%f1\t{%3, %0|%0, %3}
16186 cmov%O2%C1\t{%2, %0|%0, %2}
16187 cmov%O2%c1\t{%3, %0|%0, %3}"
16188 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16189 (set_attr "mode" "SF,SF,SI,SI")])
16191 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16192 ;; the scalar versions to have only XMM registers as operands.
16194 ;; XOP conditional move
16195 (define_insn "*xop_pcmov_<mode>"
16196 [(set (match_operand:MODEF 0 "register_operand" "=x")
16197 (if_then_else:MODEF
16198 (match_operand:MODEF 1 "register_operand" "x")
16199 (match_operand:MODEF 2 "register_operand" "x")
16200 (match_operand:MODEF 3 "register_operand" "x")))]
16202 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16203 [(set_attr "type" "sse4arg")])
16205 ;; These versions of the min/max patterns are intentionally ignorant of
16206 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16207 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16208 ;; are undefined in this condition, we're certain this is correct.
16210 (define_insn "<code><mode>3"
16211 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16213 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16214 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16215 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16217 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16218 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16219 [(set_attr "isa" "noavx,avx")
16220 (set_attr "prefix" "orig,vex")
16221 (set_attr "type" "sseadd")
16222 (set_attr "mode" "<MODE>")])
16224 ;; These versions of the min/max patterns implement exactly the operations
16225 ;; min = (op1 < op2 ? op1 : op2)
16226 ;; max = (!(op1 < op2) ? op1 : op2)
16227 ;; Their operands are not commutative, and thus they may be used in the
16228 ;; presence of -0.0 and NaN.
16230 (define_insn "*ieee_smin<mode>3"
16231 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16233 [(match_operand:MODEF 1 "register_operand" "0,x")
16234 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16236 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16238 min<ssemodesuffix>\t{%2, %0|%0, %2}
16239 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16240 [(set_attr "isa" "noavx,avx")
16241 (set_attr "prefix" "orig,vex")
16242 (set_attr "type" "sseadd")
16243 (set_attr "mode" "<MODE>")])
16245 (define_insn "*ieee_smax<mode>3"
16246 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16248 [(match_operand:MODEF 1 "register_operand" "0,x")
16249 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16251 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16253 max<ssemodesuffix>\t{%2, %0|%0, %2}
16254 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16255 [(set_attr "isa" "noavx,avx")
16256 (set_attr "prefix" "orig,vex")
16257 (set_attr "type" "sseadd")
16258 (set_attr "mode" "<MODE>")])
16260 ;; Make two stack loads independent:
16262 ;; fld %st(0) -> fld bb
16263 ;; fmul bb fmul %st(1), %st
16265 ;; Actually we only match the last two instructions for simplicity.
16267 [(set (match_operand 0 "fp_register_operand" "")
16268 (match_operand 1 "fp_register_operand" ""))
16270 (match_operator 2 "binary_fp_operator"
16272 (match_operand 3 "memory_operand" "")]))]
16273 "REGNO (operands[0]) != REGNO (operands[1])"
16274 [(set (match_dup 0) (match_dup 3))
16275 (set (match_dup 0) (match_dup 4))]
16277 ;; The % modifier is not operational anymore in peephole2's, so we have to
16278 ;; swap the operands manually in the case of addition and multiplication.
16279 "if (COMMUTATIVE_ARITH_P (operands[2]))
16280 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16281 GET_MODE (operands[2]),
16282 operands[0], operands[1]);
16284 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16285 GET_MODE (operands[2]),
16286 operands[1], operands[0]);")
16288 ;; Conditional addition patterns
16289 (define_expand "add<mode>cc"
16290 [(match_operand:SWI 0 "register_operand" "")
16291 (match_operand 1 "ordered_comparison_operator" "")
16292 (match_operand:SWI 2 "register_operand" "")
16293 (match_operand:SWI 3 "const_int_operand" "")]
16295 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16297 ;; Misc patterns (?)
16299 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16300 ;; Otherwise there will be nothing to keep
16302 ;; [(set (reg ebp) (reg esp))]
16303 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16304 ;; (clobber (eflags)]
16305 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16307 ;; in proper program order.
16309 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16310 [(set (match_operand:P 0 "register_operand" "=r,r")
16311 (plus:P (match_operand:P 1 "register_operand" "0,r")
16312 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16313 (clobber (reg:CC FLAGS_REG))
16314 (clobber (mem:BLK (scratch)))]
16317 switch (get_attr_type (insn))
16320 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16323 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16324 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16325 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16327 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16330 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16331 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16334 [(set (attr "type")
16335 (cond [(and (eq_attr "alternative" "0")
16336 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16337 (const_string "alu")
16338 (match_operand:<MODE> 2 "const0_operand" "")
16339 (const_string "imov")
16341 (const_string "lea")))
16342 (set (attr "length_immediate")
16343 (cond [(eq_attr "type" "imov")
16345 (and (eq_attr "type" "alu")
16346 (match_operand 2 "const128_operand" ""))
16349 (const_string "*")))
16350 (set_attr "mode" "<MODE>")])
16352 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16353 [(set (match_operand:P 0 "register_operand" "=r")
16354 (minus:P (match_operand:P 1 "register_operand" "0")
16355 (match_operand:P 2 "register_operand" "r")))
16356 (clobber (reg:CC FLAGS_REG))
16357 (clobber (mem:BLK (scratch)))]
16359 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16360 [(set_attr "type" "alu")
16361 (set_attr "mode" "<MODE>")])
16363 (define_insn "allocate_stack_worker_probe_<mode>"
16364 [(set (match_operand:P 0 "register_operand" "=a")
16365 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16366 UNSPECV_STACK_PROBE))
16367 (clobber (reg:CC FLAGS_REG))]
16368 "ix86_target_stack_probe ()"
16369 "call\t___chkstk_ms"
16370 [(set_attr "type" "multi")
16371 (set_attr "length" "5")])
16373 (define_expand "allocate_stack"
16374 [(match_operand 0 "register_operand" "")
16375 (match_operand 1 "general_operand" "")]
16376 "ix86_target_stack_probe ()"
16380 #ifndef CHECK_STACK_LIMIT
16381 #define CHECK_STACK_LIMIT 0
16384 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16385 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16387 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16388 stack_pointer_rtx, 0, OPTAB_DIRECT);
16389 if (x != stack_pointer_rtx)
16390 emit_move_insn (stack_pointer_rtx, x);
16394 x = copy_to_mode_reg (Pmode, operands[1]);
16396 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16398 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16399 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16400 stack_pointer_rtx, 0, OPTAB_DIRECT);
16401 if (x != stack_pointer_rtx)
16402 emit_move_insn (stack_pointer_rtx, x);
16405 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16409 ;; Use IOR for stack probes, this is shorter.
16410 (define_expand "probe_stack"
16411 [(match_operand 0 "memory_operand" "")]
16414 rtx (*gen_ior3) (rtx, rtx, rtx);
16416 gen_ior3 = (GET_MODE (operands[0]) == DImode
16417 ? gen_iordi3 : gen_iorsi3);
16419 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16423 (define_insn "adjust_stack_and_probe<mode>"
16424 [(set (match_operand:P 0 "register_operand" "=r")
16425 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16426 UNSPECV_PROBE_STACK_RANGE))
16427 (set (reg:P SP_REG)
16428 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16429 (clobber (reg:CC FLAGS_REG))
16430 (clobber (mem:BLK (scratch)))]
16432 "* return output_adjust_stack_and_probe (operands[0]);"
16433 [(set_attr "type" "multi")])
16435 (define_insn "probe_stack_range<mode>"
16436 [(set (match_operand:P 0 "register_operand" "=r")
16437 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16438 (match_operand:P 2 "const_int_operand" "n")]
16439 UNSPECV_PROBE_STACK_RANGE))
16440 (clobber (reg:CC FLAGS_REG))]
16442 "* return output_probe_stack_range (operands[0], operands[2]);"
16443 [(set_attr "type" "multi")])
16445 (define_expand "builtin_setjmp_receiver"
16446 [(label_ref (match_operand 0 "" ""))]
16447 "!TARGET_64BIT && flag_pic"
16453 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16454 rtx label_rtx = gen_label_rtx ();
16455 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16456 xops[0] = xops[1] = picreg;
16457 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16458 ix86_expand_binary_operator (MINUS, SImode, xops);
16462 emit_insn (gen_set_got (pic_offset_table_rtx));
16466 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16469 [(set (match_operand 0 "register_operand" "")
16470 (match_operator 3 "promotable_binary_operator"
16471 [(match_operand 1 "register_operand" "")
16472 (match_operand 2 "aligned_operand" "")]))
16473 (clobber (reg:CC FLAGS_REG))]
16474 "! TARGET_PARTIAL_REG_STALL && reload_completed
16475 && ((GET_MODE (operands[0]) == HImode
16476 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16477 /* ??? next two lines just !satisfies_constraint_K (...) */
16478 || !CONST_INT_P (operands[2])
16479 || satisfies_constraint_K (operands[2])))
16480 || (GET_MODE (operands[0]) == QImode
16481 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16482 [(parallel [(set (match_dup 0)
16483 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16484 (clobber (reg:CC FLAGS_REG))])]
16485 "operands[0] = gen_lowpart (SImode, operands[0]);
16486 operands[1] = gen_lowpart (SImode, operands[1]);
16487 if (GET_CODE (operands[3]) != ASHIFT)
16488 operands[2] = gen_lowpart (SImode, operands[2]);
16489 PUT_MODE (operands[3], SImode);")
16491 ; Promote the QImode tests, as i386 has encoding of the AND
16492 ; instruction with 32-bit sign-extended immediate and thus the
16493 ; instruction size is unchanged, except in the %eax case for
16494 ; which it is increased by one byte, hence the ! optimize_size.
16496 [(set (match_operand 0 "flags_reg_operand" "")
16497 (match_operator 2 "compare_operator"
16498 [(and (match_operand 3 "aligned_operand" "")
16499 (match_operand 4 "const_int_operand" ""))
16501 (set (match_operand 1 "register_operand" "")
16502 (and (match_dup 3) (match_dup 4)))]
16503 "! TARGET_PARTIAL_REG_STALL && reload_completed
16504 && optimize_insn_for_speed_p ()
16505 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16506 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16507 /* Ensure that the operand will remain sign-extended immediate. */
16508 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16509 [(parallel [(set (match_dup 0)
16510 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16513 (and:SI (match_dup 3) (match_dup 4)))])]
16516 = gen_int_mode (INTVAL (operands[4])
16517 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16518 operands[1] = gen_lowpart (SImode, operands[1]);
16519 operands[3] = gen_lowpart (SImode, operands[3]);
16522 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16523 ; the TEST instruction with 32-bit sign-extended immediate and thus
16524 ; the instruction size would at least double, which is not what we
16525 ; want even with ! optimize_size.
16527 [(set (match_operand 0 "flags_reg_operand" "")
16528 (match_operator 1 "compare_operator"
16529 [(and (match_operand:HI 2 "aligned_operand" "")
16530 (match_operand:HI 3 "const_int_operand" ""))
16532 "! TARGET_PARTIAL_REG_STALL && reload_completed
16533 && ! TARGET_FAST_PREFIX
16534 && optimize_insn_for_speed_p ()
16535 /* Ensure that the operand will remain sign-extended immediate. */
16536 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16537 [(set (match_dup 0)
16538 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16542 = gen_int_mode (INTVAL (operands[3])
16543 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16544 operands[2] = gen_lowpart (SImode, operands[2]);
16548 [(set (match_operand 0 "register_operand" "")
16549 (neg (match_operand 1 "register_operand" "")))
16550 (clobber (reg:CC FLAGS_REG))]
16551 "! TARGET_PARTIAL_REG_STALL && reload_completed
16552 && (GET_MODE (operands[0]) == HImode
16553 || (GET_MODE (operands[0]) == QImode
16554 && (TARGET_PROMOTE_QImode
16555 || optimize_insn_for_size_p ())))"
16556 [(parallel [(set (match_dup 0)
16557 (neg:SI (match_dup 1)))
16558 (clobber (reg:CC FLAGS_REG))])]
16559 "operands[0] = gen_lowpart (SImode, operands[0]);
16560 operands[1] = gen_lowpart (SImode, operands[1]);")
16563 [(set (match_operand 0 "register_operand" "")
16564 (not (match_operand 1 "register_operand" "")))]
16565 "! TARGET_PARTIAL_REG_STALL && reload_completed
16566 && (GET_MODE (operands[0]) == HImode
16567 || (GET_MODE (operands[0]) == QImode
16568 && (TARGET_PROMOTE_QImode
16569 || optimize_insn_for_size_p ())))"
16570 [(set (match_dup 0)
16571 (not:SI (match_dup 1)))]
16572 "operands[0] = gen_lowpart (SImode, operands[0]);
16573 operands[1] = gen_lowpart (SImode, operands[1]);")
16576 [(set (match_operand 0 "register_operand" "")
16577 (if_then_else (match_operator 1 "ordered_comparison_operator"
16578 [(reg FLAGS_REG) (const_int 0)])
16579 (match_operand 2 "register_operand" "")
16580 (match_operand 3 "register_operand" "")))]
16581 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16582 && (GET_MODE (operands[0]) == HImode
16583 || (GET_MODE (operands[0]) == QImode
16584 && (TARGET_PROMOTE_QImode
16585 || optimize_insn_for_size_p ())))"
16586 [(set (match_dup 0)
16587 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16588 "operands[0] = gen_lowpart (SImode, operands[0]);
16589 operands[2] = gen_lowpart (SImode, operands[2]);
16590 operands[3] = gen_lowpart (SImode, operands[3]);")
16592 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16593 ;; transform a complex memory operation into two memory to register operations.
16595 ;; Don't push memory operands
16597 [(set (match_operand:SWI 0 "push_operand" "")
16598 (match_operand:SWI 1 "memory_operand" ""))
16599 (match_scratch:SWI 2 "<r>")]
16600 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16601 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16602 [(set (match_dup 2) (match_dup 1))
16603 (set (match_dup 0) (match_dup 2))])
16605 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16608 [(set (match_operand:SF 0 "push_operand" "")
16609 (match_operand:SF 1 "memory_operand" ""))
16610 (match_scratch:SF 2 "r")]
16611 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16612 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16613 [(set (match_dup 2) (match_dup 1))
16614 (set (match_dup 0) (match_dup 2))])
16616 ;; Don't move an immediate directly to memory when the instruction
16619 [(match_scratch:SWI124 1 "<r>")
16620 (set (match_operand:SWI124 0 "memory_operand" "")
16622 "optimize_insn_for_speed_p ()
16623 && !TARGET_USE_MOV0
16624 && TARGET_SPLIT_LONG_MOVES
16625 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16626 && peep2_regno_dead_p (0, FLAGS_REG)"
16627 [(parallel [(set (match_dup 2) (const_int 0))
16628 (clobber (reg:CC FLAGS_REG))])
16629 (set (match_dup 0) (match_dup 1))]
16630 "operands[2] = gen_lowpart (SImode, operands[1]);")
16633 [(match_scratch:SWI124 2 "<r>")
16634 (set (match_operand:SWI124 0 "memory_operand" "")
16635 (match_operand:SWI124 1 "immediate_operand" ""))]
16636 "optimize_insn_for_speed_p ()
16637 && TARGET_SPLIT_LONG_MOVES
16638 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16639 [(set (match_dup 2) (match_dup 1))
16640 (set (match_dup 0) (match_dup 2))])
16642 ;; Don't compare memory with zero, load and use a test instead.
16644 [(set (match_operand 0 "flags_reg_operand" "")
16645 (match_operator 1 "compare_operator"
16646 [(match_operand:SI 2 "memory_operand" "")
16648 (match_scratch:SI 3 "r")]
16649 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16650 [(set (match_dup 3) (match_dup 2))
16651 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16653 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16654 ;; Don't split NOTs with a displacement operand, because resulting XOR
16655 ;; will not be pairable anyway.
16657 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16658 ;; represented using a modRM byte. The XOR replacement is long decoded,
16659 ;; so this split helps here as well.
16661 ;; Note: Can't do this as a regular split because we can't get proper
16662 ;; lifetime information then.
16665 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16666 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16667 "optimize_insn_for_speed_p ()
16668 && ((TARGET_NOT_UNPAIRABLE
16669 && (!MEM_P (operands[0])
16670 || !memory_displacement_operand (operands[0], <MODE>mode)))
16671 || (TARGET_NOT_VECTORMODE
16672 && long_memory_operand (operands[0], <MODE>mode)))
16673 && peep2_regno_dead_p (0, FLAGS_REG)"
16674 [(parallel [(set (match_dup 0)
16675 (xor:SWI124 (match_dup 1) (const_int -1)))
16676 (clobber (reg:CC FLAGS_REG))])])
16678 ;; Non pairable "test imm, reg" instructions can be translated to
16679 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16680 ;; byte opcode instead of two, have a short form for byte operands),
16681 ;; so do it for other CPUs as well. Given that the value was dead,
16682 ;; this should not create any new dependencies. Pass on the sub-word
16683 ;; versions if we're concerned about partial register stalls.
16686 [(set (match_operand 0 "flags_reg_operand" "")
16687 (match_operator 1 "compare_operator"
16688 [(and:SI (match_operand:SI 2 "register_operand" "")
16689 (match_operand:SI 3 "immediate_operand" ""))
16691 "ix86_match_ccmode (insn, CCNOmode)
16692 && (true_regnum (operands[2]) != AX_REG
16693 || satisfies_constraint_K (operands[3]))
16694 && peep2_reg_dead_p (1, operands[2])"
16696 [(set (match_dup 0)
16697 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16700 (and:SI (match_dup 2) (match_dup 3)))])])
16702 ;; We don't need to handle HImode case, because it will be promoted to SImode
16703 ;; on ! TARGET_PARTIAL_REG_STALL
16706 [(set (match_operand 0 "flags_reg_operand" "")
16707 (match_operator 1 "compare_operator"
16708 [(and:QI (match_operand:QI 2 "register_operand" "")
16709 (match_operand:QI 3 "immediate_operand" ""))
16711 "! TARGET_PARTIAL_REG_STALL
16712 && ix86_match_ccmode (insn, CCNOmode)
16713 && true_regnum (operands[2]) != AX_REG
16714 && peep2_reg_dead_p (1, operands[2])"
16716 [(set (match_dup 0)
16717 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16720 (and:QI (match_dup 2) (match_dup 3)))])])
16723 [(set (match_operand 0 "flags_reg_operand" "")
16724 (match_operator 1 "compare_operator"
16727 (match_operand 2 "ext_register_operand" "")
16730 (match_operand 3 "const_int_operand" ""))
16732 "! TARGET_PARTIAL_REG_STALL
16733 && ix86_match_ccmode (insn, CCNOmode)
16734 && true_regnum (operands[2]) != AX_REG
16735 && peep2_reg_dead_p (1, operands[2])"
16736 [(parallel [(set (match_dup 0)
16745 (set (zero_extract:SI (match_dup 2)
16753 (match_dup 3)))])])
16755 ;; Don't do logical operations with memory inputs.
16757 [(match_scratch:SI 2 "r")
16758 (parallel [(set (match_operand:SI 0 "register_operand" "")
16759 (match_operator:SI 3 "arith_or_logical_operator"
16761 (match_operand:SI 1 "memory_operand" "")]))
16762 (clobber (reg:CC FLAGS_REG))])]
16763 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16764 [(set (match_dup 2) (match_dup 1))
16765 (parallel [(set (match_dup 0)
16766 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16767 (clobber (reg:CC FLAGS_REG))])])
16770 [(match_scratch:SI 2 "r")
16771 (parallel [(set (match_operand:SI 0 "register_operand" "")
16772 (match_operator:SI 3 "arith_or_logical_operator"
16773 [(match_operand:SI 1 "memory_operand" "")
16775 (clobber (reg:CC FLAGS_REG))])]
16776 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16777 [(set (match_dup 2) (match_dup 1))
16778 (parallel [(set (match_dup 0)
16779 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16780 (clobber (reg:CC FLAGS_REG))])])
16782 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16783 ;; refers to the destination of the load!
16786 [(set (match_operand:SI 0 "register_operand" "")
16787 (match_operand:SI 1 "register_operand" ""))
16788 (parallel [(set (match_dup 0)
16789 (match_operator:SI 3 "commutative_operator"
16791 (match_operand:SI 2 "memory_operand" "")]))
16792 (clobber (reg:CC FLAGS_REG))])]
16793 "REGNO (operands[0]) != REGNO (operands[1])
16794 && GENERAL_REGNO_P (REGNO (operands[0]))
16795 && GENERAL_REGNO_P (REGNO (operands[1]))"
16796 [(set (match_dup 0) (match_dup 4))
16797 (parallel [(set (match_dup 0)
16798 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16799 (clobber (reg:CC FLAGS_REG))])]
16800 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16803 [(set (match_operand 0 "register_operand" "")
16804 (match_operand 1 "register_operand" ""))
16806 (match_operator 3 "commutative_operator"
16808 (match_operand 2 "memory_operand" "")]))]
16809 "REGNO (operands[0]) != REGNO (operands[1])
16810 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16811 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16812 [(set (match_dup 0) (match_dup 2))
16814 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16816 ; Don't do logical operations with memory outputs
16818 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16819 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16820 ; the same decoder scheduling characteristics as the original.
16823 [(match_scratch:SI 2 "r")
16824 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16825 (match_operator:SI 3 "arith_or_logical_operator"
16827 (match_operand:SI 1 "nonmemory_operand" "")]))
16828 (clobber (reg:CC FLAGS_REG))])]
16829 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16830 /* Do not split stack checking probes. */
16831 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16832 [(set (match_dup 2) (match_dup 0))
16833 (parallel [(set (match_dup 2)
16834 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16835 (clobber (reg:CC FLAGS_REG))])
16836 (set (match_dup 0) (match_dup 2))])
16839 [(match_scratch:SI 2 "r")
16840 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16841 (match_operator:SI 3 "arith_or_logical_operator"
16842 [(match_operand:SI 1 "nonmemory_operand" "")
16844 (clobber (reg:CC FLAGS_REG))])]
16845 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16846 /* Do not split stack checking probes. */
16847 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16848 [(set (match_dup 2) (match_dup 0))
16849 (parallel [(set (match_dup 2)
16850 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16851 (clobber (reg:CC FLAGS_REG))])
16852 (set (match_dup 0) (match_dup 2))])
16854 ;; Attempt to always use XOR for zeroing registers.
16856 [(set (match_operand 0 "register_operand" "")
16857 (match_operand 1 "const0_operand" ""))]
16858 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16859 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16860 && GENERAL_REG_P (operands[0])
16861 && peep2_regno_dead_p (0, FLAGS_REG)"
16862 [(parallel [(set (match_dup 0) (const_int 0))
16863 (clobber (reg:CC FLAGS_REG))])]
16864 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16867 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16869 "(GET_MODE (operands[0]) == QImode
16870 || GET_MODE (operands[0]) == HImode)
16871 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16872 && peep2_regno_dead_p (0, FLAGS_REG)"
16873 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16874 (clobber (reg:CC FLAGS_REG))])])
16876 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16878 [(set (match_operand:SWI248 0 "register_operand" "")
16880 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16881 && peep2_regno_dead_p (0, FLAGS_REG)"
16882 [(parallel [(set (match_dup 0) (const_int -1))
16883 (clobber (reg:CC FLAGS_REG))])]
16885 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16886 operands[0] = gen_lowpart (SImode, operands[0]);
16889 ;; Attempt to convert simple lea to add/shift.
16890 ;; These can be created by move expanders.
16893 [(set (match_operand:SWI48 0 "register_operand" "")
16894 (plus:SWI48 (match_dup 0)
16895 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16896 "peep2_regno_dead_p (0, FLAGS_REG)"
16897 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16898 (clobber (reg:CC FLAGS_REG))])])
16901 [(set (match_operand:SI 0 "register_operand" "")
16902 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16903 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16905 && peep2_regno_dead_p (0, FLAGS_REG)
16906 && REGNO (operands[0]) == REGNO (operands[1])"
16907 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16908 (clobber (reg:CC FLAGS_REG))])]
16909 "operands[2] = gen_lowpart (SImode, operands[2]);")
16912 [(set (match_operand:SWI48 0 "register_operand" "")
16913 (mult:SWI48 (match_dup 0)
16914 (match_operand:SWI48 1 "const_int_operand" "")))]
16915 "exact_log2 (INTVAL (operands[1])) >= 0
16916 && peep2_regno_dead_p (0, FLAGS_REG)"
16917 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16918 (clobber (reg:CC FLAGS_REG))])]
16919 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16922 [(set (match_operand:SI 0 "register_operand" "")
16923 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16924 (match_operand:DI 2 "const_int_operand" "")) 0))]
16926 && exact_log2 (INTVAL (operands[2])) >= 0
16927 && REGNO (operands[0]) == REGNO (operands[1])
16928 && peep2_regno_dead_p (0, FLAGS_REG)"
16929 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16930 (clobber (reg:CC FLAGS_REG))])]
16931 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16933 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16934 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16935 ;; On many CPUs it is also faster, since special hardware to avoid esp
16936 ;; dependencies is present.
16938 ;; While some of these conversions may be done using splitters, we use
16939 ;; peepholes in order to allow combine_stack_adjustments pass to see
16940 ;; nonobfuscated RTL.
16942 ;; Convert prologue esp subtractions to push.
16943 ;; We need register to push. In order to keep verify_flow_info happy we have
16945 ;; - use scratch and clobber it in order to avoid dependencies
16946 ;; - use already live register
16947 ;; We can't use the second way right now, since there is no reliable way how to
16948 ;; verify that given register is live. First choice will also most likely in
16949 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16950 ;; call clobbered registers are dead. We may want to use base pointer as an
16951 ;; alternative when no register is available later.
16954 [(match_scratch:P 1 "r")
16955 (parallel [(set (reg:P SP_REG)
16956 (plus:P (reg:P SP_REG)
16957 (match_operand:P 0 "const_int_operand" "")))
16958 (clobber (reg:CC FLAGS_REG))
16959 (clobber (mem:BLK (scratch)))])]
16960 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16961 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16962 [(clobber (match_dup 1))
16963 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16964 (clobber (mem:BLK (scratch)))])])
16967 [(match_scratch:P 1 "r")
16968 (parallel [(set (reg:P SP_REG)
16969 (plus:P (reg:P SP_REG)
16970 (match_operand:P 0 "const_int_operand" "")))
16971 (clobber (reg:CC FLAGS_REG))
16972 (clobber (mem:BLK (scratch)))])]
16973 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16974 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16975 [(clobber (match_dup 1))
16976 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16977 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16978 (clobber (mem:BLK (scratch)))])])
16980 ;; Convert esp subtractions to push.
16982 [(match_scratch:P 1 "r")
16983 (parallel [(set (reg:P SP_REG)
16984 (plus:P (reg:P SP_REG)
16985 (match_operand:P 0 "const_int_operand" "")))
16986 (clobber (reg:CC FLAGS_REG))])]
16987 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16988 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16989 [(clobber (match_dup 1))
16990 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16993 [(match_scratch:P 1 "r")
16994 (parallel [(set (reg:P SP_REG)
16995 (plus:P (reg:P SP_REG)
16996 (match_operand:P 0 "const_int_operand" "")))
16997 (clobber (reg:CC FLAGS_REG))])]
16998 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16999 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17000 [(clobber (match_dup 1))
17001 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17002 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17004 ;; Convert epilogue deallocator to pop.
17006 [(match_scratch:P 1 "r")
17007 (parallel [(set (reg:P SP_REG)
17008 (plus:P (reg:P SP_REG)
17009 (match_operand:P 0 "const_int_operand" "")))
17010 (clobber (reg:CC FLAGS_REG))
17011 (clobber (mem:BLK (scratch)))])]
17012 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17013 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17014 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17015 (clobber (mem:BLK (scratch)))])])
17017 ;; Two pops case is tricky, since pop causes dependency
17018 ;; on destination register. We use two registers if available.
17020 [(match_scratch:P 1 "r")
17021 (match_scratch:P 2 "r")
17022 (parallel [(set (reg:P SP_REG)
17023 (plus:P (reg:P SP_REG)
17024 (match_operand:P 0 "const_int_operand" "")))
17025 (clobber (reg:CC FLAGS_REG))
17026 (clobber (mem:BLK (scratch)))])]
17027 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17028 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17029 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17030 (clobber (mem:BLK (scratch)))])
17031 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17034 [(match_scratch:P 1 "r")
17035 (parallel [(set (reg:P SP_REG)
17036 (plus:P (reg:P SP_REG)
17037 (match_operand:P 0 "const_int_operand" "")))
17038 (clobber (reg:CC FLAGS_REG))
17039 (clobber (mem:BLK (scratch)))])]
17040 "optimize_insn_for_size_p ()
17041 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17042 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17043 (clobber (mem:BLK (scratch)))])
17044 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17046 ;; Convert esp additions to pop.
17048 [(match_scratch:P 1 "r")
17049 (parallel [(set (reg:P SP_REG)
17050 (plus:P (reg:P SP_REG)
17051 (match_operand:P 0 "const_int_operand" "")))
17052 (clobber (reg:CC FLAGS_REG))])]
17053 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17054 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17056 ;; Two pops case is tricky, since pop causes dependency
17057 ;; on destination register. We use two registers if available.
17059 [(match_scratch:P 1 "r")
17060 (match_scratch:P 2 "r")
17061 (parallel [(set (reg:P SP_REG)
17062 (plus:P (reg:P SP_REG)
17063 (match_operand:P 0 "const_int_operand" "")))
17064 (clobber (reg:CC FLAGS_REG))])]
17065 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17066 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17067 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17070 [(match_scratch:P 1 "r")
17071 (parallel [(set (reg:P SP_REG)
17072 (plus:P (reg:P SP_REG)
17073 (match_operand:P 0 "const_int_operand" "")))
17074 (clobber (reg:CC FLAGS_REG))])]
17075 "optimize_insn_for_size_p ()
17076 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17077 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17078 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17080 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17081 ;; required and register dies. Similarly for 128 to -128.
17083 [(set (match_operand 0 "flags_reg_operand" "")
17084 (match_operator 1 "compare_operator"
17085 [(match_operand 2 "register_operand" "")
17086 (match_operand 3 "const_int_operand" "")]))]
17087 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17088 && incdec_operand (operands[3], GET_MODE (operands[3])))
17089 || (!TARGET_FUSE_CMP_AND_BRANCH
17090 && INTVAL (operands[3]) == 128))
17091 && ix86_match_ccmode (insn, CCGCmode)
17092 && peep2_reg_dead_p (1, operands[2])"
17093 [(parallel [(set (match_dup 0)
17094 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17095 (clobber (match_dup 2))])])
17097 ;; Convert imul by three, five and nine into lea
17100 [(set (match_operand:SWI48 0 "register_operand" "")
17101 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17102 (match_operand:SWI48 2 "const_int_operand" "")))
17103 (clobber (reg:CC FLAGS_REG))])]
17104 "INTVAL (operands[2]) == 3
17105 || INTVAL (operands[2]) == 5
17106 || INTVAL (operands[2]) == 9"
17107 [(set (match_dup 0)
17108 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17110 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17114 [(set (match_operand:SWI48 0 "register_operand" "")
17115 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17116 (match_operand:SWI48 2 "const_int_operand" "")))
17117 (clobber (reg:CC FLAGS_REG))])]
17118 "optimize_insn_for_speed_p ()
17119 && (INTVAL (operands[2]) == 3
17120 || INTVAL (operands[2]) == 5
17121 || INTVAL (operands[2]) == 9)"
17122 [(set (match_dup 0) (match_dup 1))
17124 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17126 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17128 ;; imul $32bit_imm, mem, reg is vector decoded, while
17129 ;; imul $32bit_imm, reg, reg is direct decoded.
17131 [(match_scratch:SWI48 3 "r")
17132 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17133 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17134 (match_operand:SWI48 2 "immediate_operand" "")))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17137 && !satisfies_constraint_K (operands[2])"
17138 [(set (match_dup 3) (match_dup 1))
17139 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17140 (clobber (reg:CC FLAGS_REG))])])
17143 [(match_scratch:SI 3 "r")
17144 (parallel [(set (match_operand:DI 0 "register_operand" "")
17146 (mult:SI (match_operand:SI 1 "memory_operand" "")
17147 (match_operand:SI 2 "immediate_operand" ""))))
17148 (clobber (reg:CC FLAGS_REG))])]
17150 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17151 && !satisfies_constraint_K (operands[2])"
17152 [(set (match_dup 3) (match_dup 1))
17153 (parallel [(set (match_dup 0)
17154 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17155 (clobber (reg:CC FLAGS_REG))])])
17157 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17158 ;; Convert it into imul reg, reg
17159 ;; It would be better to force assembler to encode instruction using long
17160 ;; immediate, but there is apparently no way to do so.
17162 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17164 (match_operand:SWI248 1 "nonimmediate_operand" "")
17165 (match_operand:SWI248 2 "const_int_operand" "")))
17166 (clobber (reg:CC FLAGS_REG))])
17167 (match_scratch:SWI248 3 "r")]
17168 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17169 && satisfies_constraint_K (operands[2])"
17170 [(set (match_dup 3) (match_dup 2))
17171 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17172 (clobber (reg:CC FLAGS_REG))])]
17174 if (!rtx_equal_p (operands[0], operands[1]))
17175 emit_move_insn (operands[0], operands[1]);
17178 ;; After splitting up read-modify operations, array accesses with memory
17179 ;; operands might end up in form:
17181 ;; movl 4(%esp), %edx
17183 ;; instead of pre-splitting:
17185 ;; addl 4(%esp), %eax
17187 ;; movl 4(%esp), %edx
17188 ;; leal (%edx,%eax,4), %eax
17191 [(match_scratch:P 5 "r")
17192 (parallel [(set (match_operand 0 "register_operand" "")
17193 (ashift (match_operand 1 "register_operand" "")
17194 (match_operand 2 "const_int_operand" "")))
17195 (clobber (reg:CC FLAGS_REG))])
17196 (parallel [(set (match_operand 3 "register_operand" "")
17197 (plus (match_dup 0)
17198 (match_operand 4 "x86_64_general_operand" "")))
17199 (clobber (reg:CC FLAGS_REG))])]
17200 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17201 /* Validate MODE for lea. */
17202 && ((!TARGET_PARTIAL_REG_STALL
17203 && (GET_MODE (operands[0]) == QImode
17204 || GET_MODE (operands[0]) == HImode))
17205 || GET_MODE (operands[0]) == SImode
17206 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17207 && (rtx_equal_p (operands[0], operands[3])
17208 || peep2_reg_dead_p (2, operands[0]))
17209 /* We reorder load and the shift. */
17210 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17211 [(set (match_dup 5) (match_dup 4))
17212 (set (match_dup 0) (match_dup 1))]
17214 enum machine_mode op1mode = GET_MODE (operands[1]);
17215 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17216 int scale = 1 << INTVAL (operands[2]);
17217 rtx index = gen_lowpart (Pmode, operands[1]);
17218 rtx base = gen_lowpart (Pmode, operands[5]);
17219 rtx dest = gen_lowpart (mode, operands[3]);
17221 operands[1] = gen_rtx_PLUS (Pmode, base,
17222 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17223 operands[5] = base;
17225 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17226 if (op1mode != Pmode)
17227 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17228 operands[0] = dest;
17231 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17232 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17233 ;; caught for use by garbage collectors and the like. Using an insn that
17234 ;; maps to SIGILL makes it more likely the program will rightfully die.
17235 ;; Keeping with tradition, "6" is in honor of #UD.
17236 (define_insn "trap"
17237 [(trap_if (const_int 1) (const_int 6))]
17239 { return ASM_SHORT "0x0b0f"; }
17240 [(set_attr "length" "2")])
17242 (define_expand "prefetch"
17243 [(prefetch (match_operand 0 "address_operand" "")
17244 (match_operand:SI 1 "const_int_operand" "")
17245 (match_operand:SI 2 "const_int_operand" ""))]
17246 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17248 int rw = INTVAL (operands[1]);
17249 int locality = INTVAL (operands[2]);
17251 gcc_assert (rw == 0 || rw == 1);
17252 gcc_assert (locality >= 0 && locality <= 3);
17253 gcc_assert (GET_MODE (operands[0]) == Pmode
17254 || GET_MODE (operands[0]) == VOIDmode);
17256 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17257 supported by SSE counterpart or the SSE prefetch is not available
17258 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17260 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17261 operands[2] = GEN_INT (3);
17263 operands[1] = const0_rtx;
17266 (define_insn "*prefetch_sse_<mode>"
17267 [(prefetch (match_operand:P 0 "address_operand" "p")
17269 (match_operand:SI 1 "const_int_operand" ""))]
17270 "TARGET_PREFETCH_SSE"
17272 static const char * const patterns[4] = {
17273 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17276 int locality = INTVAL (operands[1]);
17277 gcc_assert (locality >= 0 && locality <= 3);
17279 return patterns[locality];
17281 [(set_attr "type" "sse")
17282 (set_attr "atom_sse_attr" "prefetch")
17283 (set (attr "length_address")
17284 (symbol_ref "memory_address_length (operands[0])"))
17285 (set_attr "memory" "none")])
17287 (define_insn "*prefetch_3dnow_<mode>"
17288 [(prefetch (match_operand:P 0 "address_operand" "p")
17289 (match_operand:SI 1 "const_int_operand" "n")
17293 if (INTVAL (operands[1]) == 0)
17294 return "prefetch\t%a0";
17296 return "prefetchw\t%a0";
17298 [(set_attr "type" "mmx")
17299 (set (attr "length_address")
17300 (symbol_ref "memory_address_length (operands[0])"))
17301 (set_attr "memory" "none")])
17303 (define_expand "stack_protect_set"
17304 [(match_operand 0 "memory_operand" "")
17305 (match_operand 1 "memory_operand" "")]
17308 rtx (*insn)(rtx, rtx);
17310 #ifdef TARGET_THREAD_SSP_OFFSET
17311 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17312 insn = (TARGET_64BIT
17313 ? gen_stack_tls_protect_set_di
17314 : gen_stack_tls_protect_set_si);
17316 insn = (TARGET_64BIT
17317 ? gen_stack_protect_set_di
17318 : gen_stack_protect_set_si);
17321 emit_insn (insn (operands[0], operands[1]));
17325 (define_insn "stack_protect_set_<mode>"
17326 [(set (match_operand:P 0 "memory_operand" "=m")
17327 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17328 (set (match_scratch:P 2 "=&r") (const_int 0))
17329 (clobber (reg:CC FLAGS_REG))]
17331 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17332 [(set_attr "type" "multi")])
17334 (define_insn "stack_tls_protect_set_<mode>"
17335 [(set (match_operand:P 0 "memory_operand" "=m")
17336 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17337 UNSPEC_SP_TLS_SET))
17338 (set (match_scratch:P 2 "=&r") (const_int 0))
17339 (clobber (reg:CC FLAGS_REG))]
17341 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17342 [(set_attr "type" "multi")])
17344 (define_expand "stack_protect_test"
17345 [(match_operand 0 "memory_operand" "")
17346 (match_operand 1 "memory_operand" "")
17347 (match_operand 2 "" "")]
17350 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17352 rtx (*insn)(rtx, rtx, rtx);
17354 #ifdef TARGET_THREAD_SSP_OFFSET
17355 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17356 insn = (TARGET_64BIT
17357 ? gen_stack_tls_protect_test_di
17358 : gen_stack_tls_protect_test_si);
17360 insn = (TARGET_64BIT
17361 ? gen_stack_protect_test_di
17362 : gen_stack_protect_test_si);
17365 emit_insn (insn (flags, operands[0], operands[1]));
17367 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17368 flags, const0_rtx, operands[2]));
17372 (define_insn "stack_protect_test_<mode>"
17373 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17374 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17375 (match_operand:P 2 "memory_operand" "m")]
17377 (clobber (match_scratch:P 3 "=&r"))]
17379 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17380 [(set_attr "type" "multi")])
17382 (define_insn "stack_tls_protect_test_<mode>"
17383 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17384 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17385 (match_operand:P 2 "const_int_operand" "i")]
17386 UNSPEC_SP_TLS_TEST))
17387 (clobber (match_scratch:P 3 "=r"))]
17389 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17390 [(set_attr "type" "multi")])
17392 (define_insn "sse4_2_crc32<mode>"
17393 [(set (match_operand:SI 0 "register_operand" "=r")
17395 [(match_operand:SI 1 "register_operand" "0")
17396 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17398 "TARGET_SSE4_2 || TARGET_CRC32"
17399 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17400 [(set_attr "type" "sselog1")
17401 (set_attr "prefix_rep" "1")
17402 (set_attr "prefix_extra" "1")
17403 (set (attr "prefix_data16")
17404 (if_then_else (match_operand:HI 2 "" "")
17406 (const_string "*")))
17407 (set (attr "prefix_rex")
17408 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17410 (const_string "*")))
17411 (set_attr "mode" "SI")])
17413 (define_insn "sse4_2_crc32di"
17414 [(set (match_operand:DI 0 "register_operand" "=r")
17416 [(match_operand:DI 1 "register_operand" "0")
17417 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17419 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17420 "crc32{q}\t{%2, %0|%0, %2}"
17421 [(set_attr "type" "sselog1")
17422 (set_attr "prefix_rep" "1")
17423 (set_attr "prefix_extra" "1")
17424 (set_attr "mode" "DI")])
17426 (define_expand "rdpmc"
17427 [(match_operand:DI 0 "register_operand" "")
17428 (match_operand:SI 1 "register_operand" "")]
17431 rtx reg = gen_reg_rtx (DImode);
17434 /* Force operand 1 into ECX. */
17435 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17436 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17437 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17442 rtvec vec = rtvec_alloc (2);
17443 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17444 rtx upper = gen_reg_rtx (DImode);
17445 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17446 gen_rtvec (1, const0_rtx),
17448 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17449 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17451 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17452 NULL, 1, OPTAB_DIRECT);
17453 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17457 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17458 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17462 (define_insn "*rdpmc"
17463 [(set (match_operand:DI 0 "register_operand" "=A")
17464 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17468 [(set_attr "type" "other")
17469 (set_attr "length" "2")])
17471 (define_insn "*rdpmc_rex64"
17472 [(set (match_operand:DI 0 "register_operand" "=a")
17473 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17475 (set (match_operand:DI 1 "register_operand" "=d")
17476 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17479 [(set_attr "type" "other")
17480 (set_attr "length" "2")])
17482 (define_expand "rdtsc"
17483 [(set (match_operand:DI 0 "register_operand" "")
17484 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17489 rtvec vec = rtvec_alloc (2);
17490 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17491 rtx upper = gen_reg_rtx (DImode);
17492 rtx lower = gen_reg_rtx (DImode);
17493 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17494 gen_rtvec (1, const0_rtx),
17496 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17497 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17499 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17500 NULL, 1, OPTAB_DIRECT);
17501 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17503 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17508 (define_insn "*rdtsc"
17509 [(set (match_operand:DI 0 "register_operand" "=A")
17510 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17513 [(set_attr "type" "other")
17514 (set_attr "length" "2")])
17516 (define_insn "*rdtsc_rex64"
17517 [(set (match_operand:DI 0 "register_operand" "=a")
17518 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17519 (set (match_operand:DI 1 "register_operand" "=d")
17520 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17523 [(set_attr "type" "other")
17524 (set_attr "length" "2")])
17526 (define_expand "rdtscp"
17527 [(match_operand:DI 0 "register_operand" "")
17528 (match_operand:SI 1 "memory_operand" "")]
17531 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17532 gen_rtvec (1, const0_rtx),
17534 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17535 gen_rtvec (1, const0_rtx),
17537 rtx reg = gen_reg_rtx (DImode);
17538 rtx tmp = gen_reg_rtx (SImode);
17542 rtvec vec = rtvec_alloc (3);
17543 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17544 rtx upper = gen_reg_rtx (DImode);
17545 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17546 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17547 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17549 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17550 NULL, 1, OPTAB_DIRECT);
17551 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17556 rtvec vec = rtvec_alloc (2);
17557 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17558 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17559 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17562 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17563 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17567 (define_insn "*rdtscp"
17568 [(set (match_operand:DI 0 "register_operand" "=A")
17569 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17570 (set (match_operand:SI 1 "register_operand" "=c")
17571 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17574 [(set_attr "type" "other")
17575 (set_attr "length" "3")])
17577 (define_insn "*rdtscp_rex64"
17578 [(set (match_operand:DI 0 "register_operand" "=a")
17579 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17580 (set (match_operand:DI 1 "register_operand" "=d")
17581 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17582 (set (match_operand:SI 2 "register_operand" "=c")
17583 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17586 [(set_attr "type" "other")
17587 (set_attr "length" "3")])
17589 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17591 ;; LWP instructions
17593 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17595 (define_expand "lwp_llwpcb"
17596 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17597 UNSPECV_LLWP_INTRINSIC)]
17600 (define_insn "*lwp_llwpcb<mode>1"
17601 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17602 UNSPECV_LLWP_INTRINSIC)]
17605 [(set_attr "type" "lwp")
17606 (set_attr "mode" "<MODE>")
17607 (set_attr "length" "5")])
17609 (define_expand "lwp_slwpcb"
17610 [(set (match_operand 0 "register_operand" "=r")
17611 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17616 insn = (TARGET_64BIT
17618 : gen_lwp_slwpcbsi);
17620 emit_insn (insn (operands[0]));
17624 (define_insn "lwp_slwpcb<mode>"
17625 [(set (match_operand:P 0 "register_operand" "=r")
17626 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17629 [(set_attr "type" "lwp")
17630 (set_attr "mode" "<MODE>")
17631 (set_attr "length" "5")])
17633 (define_expand "lwp_lwpval<mode>3"
17634 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17635 (match_operand:SI 2 "nonimmediate_operand" "rm")
17636 (match_operand:SI 3 "const_int_operand" "i")]
17637 UNSPECV_LWPVAL_INTRINSIC)]
17639 "/* Avoid unused variable warning. */
17642 (define_insn "*lwp_lwpval<mode>3_1"
17643 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17644 (match_operand:SI 1 "nonimmediate_operand" "rm")
17645 (match_operand:SI 2 "const_int_operand" "i")]
17646 UNSPECV_LWPVAL_INTRINSIC)]
17648 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17649 [(set_attr "type" "lwp")
17650 (set_attr "mode" "<MODE>")
17651 (set (attr "length")
17652 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17654 (define_expand "lwp_lwpins<mode>3"
17655 [(set (reg:CCC FLAGS_REG)
17656 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17657 (match_operand:SI 2 "nonimmediate_operand" "rm")
17658 (match_operand:SI 3 "const_int_operand" "i")]
17659 UNSPECV_LWPINS_INTRINSIC))
17660 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17661 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17664 (define_insn "*lwp_lwpins<mode>3_1"
17665 [(set (reg:CCC FLAGS_REG)
17666 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17667 (match_operand:SI 1 "nonimmediate_operand" "rm")
17668 (match_operand:SI 2 "const_int_operand" "i")]
17669 UNSPECV_LWPINS_INTRINSIC))]
17671 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17672 [(set_attr "type" "lwp")
17673 (set_attr "mode" "<MODE>")
17674 (set (attr "length")
17675 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17677 (define_insn "rdfsbase<mode>"
17678 [(set (match_operand:SWI48 0 "register_operand" "=r")
17679 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17680 "TARGET_64BIT && TARGET_FSGSBASE"
17682 [(set_attr "type" "other")
17683 (set_attr "prefix_extra" "2")])
17685 (define_insn "rdgsbase<mode>"
17686 [(set (match_operand:SWI48 0 "register_operand" "=r")
17687 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17688 "TARGET_64BIT && TARGET_FSGSBASE"
17690 [(set_attr "type" "other")
17691 (set_attr "prefix_extra" "2")])
17693 (define_insn "wrfsbase<mode>"
17694 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17696 "TARGET_64BIT && TARGET_FSGSBASE"
17698 [(set_attr "type" "other")
17699 (set_attr "prefix_extra" "2")])
17701 (define_insn "wrgsbase<mode>"
17702 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17704 "TARGET_64BIT && TARGET_FSGSBASE"
17706 [(set_attr "type" "other")
17707 (set_attr "prefix_extra" "2")])
17709 (define_insn "rdrand<mode>_1"
17710 [(set (match_operand:SWI248 0 "register_operand" "=r")
17711 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17712 (set (reg:CCC FLAGS_REG)
17713 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17716 [(set_attr "type" "other")
17717 (set_attr "prefix_extra" "1")])
17721 (include "sync.md")