1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
110 UNSPEC_CALL_NEEDS_VZEROUPPER
112 ;; For SSE/MMX support:
130 UNSPEC_MS_TO_SYSV_CALL
132 ;; Generic math support
134 UNSPEC_IEEE_MIN ; not commutative
135 UNSPEC_IEEE_MAX ; not commutative
137 ;; x87 Floating point
153 UNSPEC_FRNDINT_MASK_PM
157 ;; x87 Double output FP
189 ;; For SSE4.1 support
199 ;; For SSE4.2 support
206 UNSPEC_XOP_UNSIGNED_CMP
217 UNSPEC_AESKEYGENASSIST
219 ;; For PCLMUL support
235 ;; For RDRAND support
239 (define_c_enum "unspecv" [
242 UNSPECV_PROBE_STACK_RANGE
262 UNSPECV_LLWP_INTRINSIC
263 UNSPECV_SLWP_INTRINSIC
264 UNSPECV_LWPVAL_INTRINSIC
265 UNSPECV_LWPINS_INTRINSIC
270 UNSPECV_SPLIT_STACK_RETURN
273 ;; Constants to represent rounding modes in the ROUND instruction
282 ;; Constants to represent pcomtrue/pcomfalse variants
292 ;; Constants used in the XOP pperm instruction
294 [(PPERM_SRC 0x00) /* copy source */
295 (PPERM_INVERT 0x20) /* invert source */
296 (PPERM_REVERSE 0x40) /* bit reverse source */
297 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
298 (PPERM_ZERO 0x80) /* all 0's */
299 (PPERM_ONES 0xa0) /* all 1's */
300 (PPERM_SIGN 0xc0) /* propagate sign bit */
301 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
302 (PPERM_SRC1 0x00) /* use first source byte */
303 (PPERM_SRC2 0x10) /* use second source byte */
306 ;; Registers by name.
359 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
362 ;; In C guard expressions, put expressions which may be compile-time
363 ;; constants first. This allows for better optimization. For
364 ;; example, write "TARGET_64BIT && reload_completed", not
365 ;; "reload_completed && TARGET_64BIT".
369 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
370 atom,generic64,amdfam10,bdver1,btver1"
371 (const (symbol_ref "ix86_schedule")))
373 ;; A basic instruction type. Refinements due to arguments to be
374 ;; provided in other attributes.
377 alu,alu1,negnot,imov,imovx,lea,
378 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
379 icmp,test,ibr,setcc,icmov,
380 push,pop,call,callv,leave,
382 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
383 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
384 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
385 ssemuladd,sse4arg,lwp,
386 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
387 (const_string "other"))
389 ;; Main data type used by the insn
391 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
392 (const_string "unknown"))
394 ;; The CPU unit operations uses.
395 (define_attr "unit" "integer,i387,sse,mmx,unknown"
396 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
397 (const_string "i387")
398 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
399 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
400 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
402 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
404 (eq_attr "type" "other")
405 (const_string "unknown")]
406 (const_string "integer")))
408 ;; The (bounding maximum) length of an instruction immediate.
409 (define_attr "length_immediate" ""
410 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
413 (eq_attr "unit" "i387,sse,mmx")
415 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
417 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
418 (eq_attr "type" "imov,test")
419 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
420 (eq_attr "type" "call")
421 (if_then_else (match_operand 0 "constant_call_address_operand" "")
424 (eq_attr "type" "callv")
425 (if_then_else (match_operand 1 "constant_call_address_operand" "")
428 ;; We don't know the size before shorten_branches. Expect
429 ;; the instruction to fit for better scheduling.
430 (eq_attr "type" "ibr")
433 (symbol_ref "/* Update immediate_length and other attributes! */
434 gcc_unreachable (),1")))
436 ;; The (bounding maximum) length of an instruction address.
437 (define_attr "length_address" ""
438 (cond [(eq_attr "type" "str,other,multi,fxch")
440 (and (eq_attr "type" "call")
441 (match_operand 0 "constant_call_address_operand" ""))
443 (and (eq_attr "type" "callv")
444 (match_operand 1 "constant_call_address_operand" ""))
447 (symbol_ref "ix86_attr_length_address_default (insn)")))
449 ;; Set when length prefix is used.
450 (define_attr "prefix_data16" ""
451 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
453 (eq_attr "mode" "HI")
455 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
460 ;; Set when string REP prefix is used.
461 (define_attr "prefix_rep" ""
462 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
464 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
469 ;; Set when 0f opcode prefix is used.
470 (define_attr "prefix_0f" ""
472 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
473 (eq_attr "unit" "sse,mmx"))
477 ;; Set when REX opcode prefix is used.
478 (define_attr "prefix_rex" ""
479 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
481 (and (eq_attr "mode" "DI")
482 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
483 (eq_attr "unit" "!mmx")))
485 (and (eq_attr "mode" "QI")
486 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
489 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
492 (and (eq_attr "type" "imovx")
493 (match_operand:QI 1 "ext_QIreg_operand" ""))
498 ;; There are also additional prefixes in 3DNOW, SSSE3.
499 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
500 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
501 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
502 (define_attr "prefix_extra" ""
503 (cond [(eq_attr "type" "ssemuladd,sse4arg")
505 (eq_attr "type" "sseiadd1,ssecvt1")
510 ;; Prefix used: original, VEX or maybe VEX.
511 (define_attr "prefix" "orig,vex,maybe_vex"
512 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
514 (const_string "orig")))
516 ;; VEX W bit is used.
517 (define_attr "prefix_vex_w" "" (const_int 0))
519 ;; The length of VEX prefix
520 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
521 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
522 ;; still prefix_0f 1, with prefix_extra 1.
523 (define_attr "length_vex" ""
524 (if_then_else (and (eq_attr "prefix_0f" "1")
525 (eq_attr "prefix_extra" "0"))
526 (if_then_else (eq_attr "prefix_vex_w" "1")
527 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
528 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
529 (if_then_else (eq_attr "prefix_vex_w" "1")
530 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
531 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
533 ;; Set when modrm byte is used.
534 (define_attr "modrm" ""
535 (cond [(eq_attr "type" "str,leave")
537 (eq_attr "unit" "i387")
539 (and (eq_attr "type" "incdec")
540 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
541 (ior (match_operand:SI 1 "register_operand" "")
542 (match_operand:HI 1 "register_operand" ""))))
544 (and (eq_attr "type" "push")
545 (not (match_operand 1 "memory_operand" "")))
547 (and (eq_attr "type" "pop")
548 (not (match_operand 0 "memory_operand" "")))
550 (and (eq_attr "type" "imov")
551 (and (not (eq_attr "mode" "DI"))
552 (ior (and (match_operand 0 "register_operand" "")
553 (match_operand 1 "immediate_operand" ""))
554 (ior (and (match_operand 0 "ax_reg_operand" "")
555 (match_operand 1 "memory_displacement_only_operand" ""))
556 (and (match_operand 0 "memory_displacement_only_operand" "")
557 (match_operand 1 "ax_reg_operand" ""))))))
559 (and (eq_attr "type" "call")
560 (match_operand 0 "constant_call_address_operand" ""))
562 (and (eq_attr "type" "callv")
563 (match_operand 1 "constant_call_address_operand" ""))
565 (and (eq_attr "type" "alu,alu1,icmp,test")
566 (match_operand 0 "ax_reg_operand" ""))
567 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
571 ;; The (bounding maximum) length of an instruction in bytes.
572 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
573 ;; Later we may want to split them and compute proper length as for
575 (define_attr "length" ""
576 (cond [(eq_attr "type" "other,multi,fistp,frndint")
578 (eq_attr "type" "fcmp")
580 (eq_attr "unit" "i387")
582 (plus (attr "prefix_data16")
583 (attr "length_address")))
584 (ior (eq_attr "prefix" "vex")
585 (and (eq_attr "prefix" "maybe_vex")
586 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
587 (plus (attr "length_vex")
588 (plus (attr "length_immediate")
590 (attr "length_address"))))]
591 (plus (plus (attr "modrm")
592 (plus (attr "prefix_0f")
593 (plus (attr "prefix_rex")
594 (plus (attr "prefix_extra")
596 (plus (attr "prefix_rep")
597 (plus (attr "prefix_data16")
598 (plus (attr "length_immediate")
599 (attr "length_address")))))))
601 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
602 ;; `store' if there is a simple memory reference therein, or `unknown'
603 ;; if the instruction is complex.
605 (define_attr "memory" "none,load,store,both,unknown"
606 (cond [(eq_attr "type" "other,multi,str,lwp")
607 (const_string "unknown")
608 (eq_attr "type" "lea,fcmov,fpspc")
609 (const_string "none")
610 (eq_attr "type" "fistp,leave")
611 (const_string "both")
612 (eq_attr "type" "frndint")
613 (const_string "load")
614 (eq_attr "type" "push")
615 (if_then_else (match_operand 1 "memory_operand" "")
616 (const_string "both")
617 (const_string "store"))
618 (eq_attr "type" "pop")
619 (if_then_else (match_operand 0 "memory_operand" "")
620 (const_string "both")
621 (const_string "load"))
622 (eq_attr "type" "setcc")
623 (if_then_else (match_operand 0 "memory_operand" "")
624 (const_string "store")
625 (const_string "none"))
626 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
627 (if_then_else (ior (match_operand 0 "memory_operand" "")
628 (match_operand 1 "memory_operand" ""))
629 (const_string "load")
630 (const_string "none"))
631 (eq_attr "type" "ibr")
632 (if_then_else (match_operand 0 "memory_operand" "")
633 (const_string "load")
634 (const_string "none"))
635 (eq_attr "type" "call")
636 (if_then_else (match_operand 0 "constant_call_address_operand" "")
637 (const_string "none")
638 (const_string "load"))
639 (eq_attr "type" "callv")
640 (if_then_else (match_operand 1 "constant_call_address_operand" "")
641 (const_string "none")
642 (const_string "load"))
643 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
644 (match_operand 1 "memory_operand" ""))
645 (const_string "both")
646 (and (match_operand 0 "memory_operand" "")
647 (match_operand 1 "memory_operand" ""))
648 (const_string "both")
649 (match_operand 0 "memory_operand" "")
650 (const_string "store")
651 (match_operand 1 "memory_operand" "")
652 (const_string "load")
654 "!alu1,negnot,ishift1,
655 imov,imovx,icmp,test,bitmanip,
657 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
658 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
659 (match_operand 2 "memory_operand" ""))
660 (const_string "load")
661 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
662 (match_operand 3 "memory_operand" ""))
663 (const_string "load")
665 (const_string "none")))
667 ;; Indicates if an instruction has both an immediate and a displacement.
669 (define_attr "imm_disp" "false,true,unknown"
670 (cond [(eq_attr "type" "other,multi")
671 (const_string "unknown")
672 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
673 (and (match_operand 0 "memory_displacement_operand" "")
674 (match_operand 1 "immediate_operand" "")))
675 (const_string "true")
676 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
677 (and (match_operand 0 "memory_displacement_operand" "")
678 (match_operand 2 "immediate_operand" "")))
679 (const_string "true")
681 (const_string "false")))
683 ;; Indicates if an FP operation has an integer source.
685 (define_attr "fp_int_src" "false,true"
686 (const_string "false"))
688 ;; Defines rounding mode of an FP operation.
690 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
691 (const_string "any"))
693 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
694 (define_attr "use_carry" "0,1" (const_string "0"))
696 ;; Define attribute to indicate unaligned ssemov insns
697 (define_attr "movu" "0,1" (const_string "0"))
699 ;; Used to control the "enabled" attribute on a per-instruction basis.
700 (define_attr "isa" "base,noavx,avx"
701 (const_string "base"))
703 (define_attr "enabled" ""
704 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
705 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
709 ;; Describe a user's asm statement.
710 (define_asm_attributes
711 [(set_attr "length" "128")
712 (set_attr "type" "multi")])
714 (define_code_iterator plusminus [plus minus])
716 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
718 ;; Base name for define_insn
719 (define_code_attr plusminus_insn
720 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
721 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
723 ;; Base name for insn mnemonic.
724 (define_code_attr plusminus_mnemonic
725 [(plus "add") (ss_plus "adds") (us_plus "addus")
726 (minus "sub") (ss_minus "subs") (us_minus "subus")])
727 (define_code_attr plusminus_carry_mnemonic
728 [(plus "adc") (minus "sbb")])
730 ;; Mark commutative operators as such in constraints.
731 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
732 (minus "") (ss_minus "") (us_minus "")])
734 ;; Mapping of signed max and min
735 (define_code_iterator smaxmin [smax smin])
737 ;; Mapping of unsigned max and min
738 (define_code_iterator umaxmin [umax umin])
740 ;; Base name for integer and FP insn mnemonic
741 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
742 (umax "maxu") (umin "minu")])
743 (define_code_attr maxmin_float [(smax "max") (smin "min")])
745 ;; Mapping of logic operators
746 (define_code_iterator any_logic [and ior xor])
747 (define_code_iterator any_or [ior xor])
749 ;; Base name for insn mnemonic.
750 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
752 ;; Mapping of shift-right operators
753 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
755 ;; Base name for define_insn
756 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
758 ;; Base name for insn mnemonic.
759 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
761 ;; Mapping of rotate operators
762 (define_code_iterator any_rotate [rotate rotatert])
764 ;; Base name for define_insn
765 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
767 ;; Base name for insn mnemonic.
768 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
770 ;; Mapping of abs neg operators
771 (define_code_iterator absneg [abs neg])
773 ;; Base name for x87 insn mnemonic.
774 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
776 ;; Used in signed and unsigned widening multiplications.
777 (define_code_iterator any_extend [sign_extend zero_extend])
779 ;; Various insn prefixes for signed and unsigned operations.
780 (define_code_attr u [(sign_extend "") (zero_extend "u")
781 (div "") (udiv "u")])
782 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
784 ;; Used in signed and unsigned divisions.
785 (define_code_iterator any_div [div udiv])
787 ;; Instruction prefix for signed and unsigned operations.
788 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
789 (div "i") (udiv "")])
791 ;; 64bit single word integer modes.
792 (define_mode_iterator SWI1248x [QI HI SI DI])
794 ;; 64bit single word integer modes without QImode and HImode.
795 (define_mode_iterator SWI48x [SI DI])
797 ;; Single word integer modes.
798 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
800 ;; Single word integer modes without SImode and DImode.
801 (define_mode_iterator SWI12 [QI HI])
803 ;; Single word integer modes without DImode.
804 (define_mode_iterator SWI124 [QI HI SI])
806 ;; Single word integer modes without QImode and DImode.
807 (define_mode_iterator SWI24 [HI SI])
809 ;; Single word integer modes without QImode.
810 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
812 ;; Single word integer modes without QImode and HImode.
813 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
815 ;; All math-dependant single and double word integer modes.
816 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
817 (HI "TARGET_HIMODE_MATH")
818 SI DI (TI "TARGET_64BIT")])
820 ;; Math-dependant single word integer modes.
821 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
822 (HI "TARGET_HIMODE_MATH")
823 SI (DI "TARGET_64BIT")])
825 ;; Math-dependant single word integer modes without DImode.
826 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
827 (HI "TARGET_HIMODE_MATH")
830 ;; Math-dependant single word integer modes without QImode.
831 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
832 SI (DI "TARGET_64BIT")])
834 ;; Double word integer modes.
835 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
836 (TI "TARGET_64BIT")])
838 ;; Double word integer modes as mode attribute.
839 (define_mode_attr DWI [(SI "DI") (DI "TI")])
840 (define_mode_attr dwi [(SI "di") (DI "ti")])
842 ;; Half mode for double word integer modes.
843 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
844 (DI "TARGET_64BIT")])
846 ;; Instruction suffix for integer modes.
847 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
849 ;; Pointer size prefix for integer modes (Intel asm dialect)
850 (define_mode_attr iptrsize [(QI "BYTE")
855 ;; Register class for integer modes.
856 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
858 ;; Immediate operand constraint for integer modes.
859 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
861 ;; General operand constraint for word modes.
862 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
864 ;; Immediate operand constraint for double integer modes.
865 (define_mode_attr di [(SI "iF") (DI "e")])
867 ;; Immediate operand constraint for shifts.
868 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
870 ;; General operand predicate for integer modes.
871 (define_mode_attr general_operand
872 [(QI "general_operand")
873 (HI "general_operand")
874 (SI "general_operand")
875 (DI "x86_64_general_operand")
876 (TI "x86_64_general_operand")])
878 ;; General sign/zero extend operand predicate for integer modes.
879 (define_mode_attr general_szext_operand
880 [(QI "general_operand")
881 (HI "general_operand")
882 (SI "general_operand")
883 (DI "x86_64_szext_general_operand")])
885 ;; Immediate operand predicate for integer modes.
886 (define_mode_attr immediate_operand
887 [(QI "immediate_operand")
888 (HI "immediate_operand")
889 (SI "immediate_operand")
890 (DI "x86_64_immediate_operand")])
892 ;; Nonmemory operand predicate for integer modes.
893 (define_mode_attr nonmemory_operand
894 [(QI "nonmemory_operand")
895 (HI "nonmemory_operand")
896 (SI "nonmemory_operand")
897 (DI "x86_64_nonmemory_operand")])
899 ;; Operand predicate for shifts.
900 (define_mode_attr shift_operand
901 [(QI "nonimmediate_operand")
902 (HI "nonimmediate_operand")
903 (SI "nonimmediate_operand")
904 (DI "shiftdi_operand")
905 (TI "register_operand")])
907 ;; Operand predicate for shift argument.
908 (define_mode_attr shift_immediate_operand
909 [(QI "const_1_to_31_operand")
910 (HI "const_1_to_31_operand")
911 (SI "const_1_to_31_operand")
912 (DI "const_1_to_63_operand")])
914 ;; Input operand predicate for arithmetic left shifts.
915 (define_mode_attr ashl_input_operand
916 [(QI "nonimmediate_operand")
917 (HI "nonimmediate_operand")
918 (SI "nonimmediate_operand")
919 (DI "ashldi_input_operand")
920 (TI "reg_or_pm1_operand")])
922 ;; SSE and x87 SFmode and DFmode floating point modes
923 (define_mode_iterator MODEF [SF DF])
925 ;; All x87 floating point modes
926 (define_mode_iterator X87MODEF [SF DF XF])
928 ;; All integer modes handled by x87 fisttp operator.
929 (define_mode_iterator X87MODEI [HI SI DI])
931 ;; All integer modes handled by integer x87 operators.
932 (define_mode_iterator X87MODEI12 [HI SI])
934 ;; All integer modes handled by SSE cvtts?2si* operators.
935 (define_mode_iterator SSEMODEI24 [SI DI])
937 ;; SSE instruction suffix for various modes
938 (define_mode_attr ssemodesuffix
940 (V8SF "ps") (V4DF "pd")
941 (V4SF "ps") (V2DF "pd")
942 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
945 ;; SSE vector suffix for floating point modes
946 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
948 ;; SSE vector mode corresponding to a scalar mode
949 (define_mode_attr ssevecmode
950 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
952 ;; Instruction suffix for REX 64bit operators.
953 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
955 ;; This mode iterator allows :P to be used for patterns that operate on
956 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
957 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
959 ;; Scheduling descriptions
961 (include "pentium.md")
964 (include "athlon.md")
965 (include "bdver1.md")
971 ;; Operand and operator predicates and constraints
973 (include "predicates.md")
974 (include "constraints.md")
977 ;; Compare and branch/compare and store instructions.
979 (define_expand "cbranch<mode>4"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
982 (match_operand:SDWIM 2 "<general_operand>" "")))
983 (set (pc) (if_then_else
984 (match_operator 0 "ordered_comparison_operator"
985 [(reg:CC FLAGS_REG) (const_int 0)])
986 (label_ref (match_operand 3 "" ""))
990 if (MEM_P (operands[1]) && MEM_P (operands[2]))
991 operands[1] = force_reg (<MODE>mode, operands[1]);
992 ix86_expand_branch (GET_CODE (operands[0]),
993 operands[1], operands[2], operands[3]);
997 (define_expand "cstore<mode>4"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1000 (match_operand:SWIM 3 "<general_operand>" "")))
1001 (set (match_operand:QI 0 "register_operand" "")
1002 (match_operator 1 "ordered_comparison_operator"
1003 [(reg:CC FLAGS_REG) (const_int 0)]))]
1006 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1007 operands[2] = force_reg (<MODE>mode, operands[2]);
1008 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1009 operands[2], operands[3]);
1013 (define_expand "cmp<mode>_1"
1014 [(set (reg:CC FLAGS_REG)
1015 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1016 (match_operand:SWI48 1 "<general_operand>" "")))])
1018 (define_insn "*cmp<mode>_ccno_1"
1019 [(set (reg FLAGS_REG)
1020 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1021 (match_operand:SWI 1 "const0_operand" "")))]
1022 "ix86_match_ccmode (insn, CCNOmode)"
1024 test{<imodesuffix>}\t%0, %0
1025 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1026 [(set_attr "type" "test,icmp")
1027 (set_attr "length_immediate" "0,1")
1028 (set_attr "mode" "<MODE>")])
1030 (define_insn "*cmp<mode>_1"
1031 [(set (reg FLAGS_REG)
1032 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1033 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1034 "ix86_match_ccmode (insn, CCmode)"
1035 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "<MODE>")])
1039 (define_insn "*cmp<mode>_minus_1"
1040 [(set (reg FLAGS_REG)
1042 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1043 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1045 "ix86_match_ccmode (insn, CCGOCmode)"
1046 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1047 [(set_attr "type" "icmp")
1048 (set_attr "mode" "<MODE>")])
1050 (define_insn "*cmpqi_ext_1"
1051 [(set (reg FLAGS_REG)
1053 (match_operand:QI 0 "general_operand" "Qm")
1056 (match_operand 1 "ext_register_operand" "Q")
1058 (const_int 8)) 0)))]
1059 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1060 "cmp{b}\t{%h1, %0|%0, %h1}"
1061 [(set_attr "type" "icmp")
1062 (set_attr "mode" "QI")])
1064 (define_insn "*cmpqi_ext_1_rex64"
1065 [(set (reg FLAGS_REG)
1067 (match_operand:QI 0 "register_operand" "Q")
1070 (match_operand 1 "ext_register_operand" "Q")
1072 (const_int 8)) 0)))]
1073 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1074 "cmp{b}\t{%h1, %0|%0, %h1}"
1075 [(set_attr "type" "icmp")
1076 (set_attr "mode" "QI")])
1078 (define_insn "*cmpqi_ext_2"
1079 [(set (reg FLAGS_REG)
1083 (match_operand 0 "ext_register_operand" "Q")
1086 (match_operand:QI 1 "const0_operand" "")))]
1087 "ix86_match_ccmode (insn, CCNOmode)"
1089 [(set_attr "type" "test")
1090 (set_attr "length_immediate" "0")
1091 (set_attr "mode" "QI")])
1093 (define_expand "cmpqi_ext_3"
1094 [(set (reg:CC FLAGS_REG)
1098 (match_operand 0 "ext_register_operand" "")
1101 (match_operand:QI 1 "immediate_operand" "")))])
1103 (define_insn "*cmpqi_ext_3_insn"
1104 [(set (reg FLAGS_REG)
1108 (match_operand 0 "ext_register_operand" "Q")
1111 (match_operand:QI 1 "general_operand" "Qmn")))]
1112 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1113 "cmp{b}\t{%1, %h0|%h0, %1}"
1114 [(set_attr "type" "icmp")
1115 (set_attr "modrm" "1")
1116 (set_attr "mode" "QI")])
1118 (define_insn "*cmpqi_ext_3_insn_rex64"
1119 [(set (reg FLAGS_REG)
1123 (match_operand 0 "ext_register_operand" "Q")
1126 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1127 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1128 "cmp{b}\t{%1, %h0|%h0, %1}"
1129 [(set_attr "type" "icmp")
1130 (set_attr "modrm" "1")
1131 (set_attr "mode" "QI")])
1133 (define_insn "*cmpqi_ext_4"
1134 [(set (reg FLAGS_REG)
1138 (match_operand 0 "ext_register_operand" "Q")
1143 (match_operand 1 "ext_register_operand" "Q")
1145 (const_int 8)) 0)))]
1146 "ix86_match_ccmode (insn, CCmode)"
1147 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1148 [(set_attr "type" "icmp")
1149 (set_attr "mode" "QI")])
1151 ;; These implement float point compares.
1152 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1153 ;; which would allow mix and match FP modes on the compares. Which is what
1154 ;; the old patterns did, but with many more of them.
1156 (define_expand "cbranchxf4"
1157 [(set (reg:CC FLAGS_REG)
1158 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1159 (match_operand:XF 2 "nonmemory_operand" "")))
1160 (set (pc) (if_then_else
1161 (match_operator 0 "ix86_fp_comparison_operator"
1164 (label_ref (match_operand 3 "" ""))
1168 ix86_expand_branch (GET_CODE (operands[0]),
1169 operands[1], operands[2], operands[3]);
1173 (define_expand "cstorexf4"
1174 [(set (reg:CC FLAGS_REG)
1175 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1176 (match_operand:XF 3 "nonmemory_operand" "")))
1177 (set (match_operand:QI 0 "register_operand" "")
1178 (match_operator 1 "ix86_fp_comparison_operator"
1183 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1184 operands[2], operands[3]);
1188 (define_expand "cbranch<mode>4"
1189 [(set (reg:CC FLAGS_REG)
1190 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1191 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1192 (set (pc) (if_then_else
1193 (match_operator 0 "ix86_fp_comparison_operator"
1196 (label_ref (match_operand 3 "" ""))
1198 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1200 ix86_expand_branch (GET_CODE (operands[0]),
1201 operands[1], operands[2], operands[3]);
1205 (define_expand "cstore<mode>4"
1206 [(set (reg:CC FLAGS_REG)
1207 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1208 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1209 (set (match_operand:QI 0 "register_operand" "")
1210 (match_operator 1 "ix86_fp_comparison_operator"
1213 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1215 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1216 operands[2], operands[3]);
1220 (define_expand "cbranchcc4"
1221 [(set (pc) (if_then_else
1222 (match_operator 0 "comparison_operator"
1223 [(match_operand 1 "flags_reg_operand" "")
1224 (match_operand 2 "const0_operand" "")])
1225 (label_ref (match_operand 3 "" ""))
1229 ix86_expand_branch (GET_CODE (operands[0]),
1230 operands[1], operands[2], operands[3]);
1234 (define_expand "cstorecc4"
1235 [(set (match_operand:QI 0 "register_operand" "")
1236 (match_operator 1 "comparison_operator"
1237 [(match_operand 2 "flags_reg_operand" "")
1238 (match_operand 3 "const0_operand" "")]))]
1241 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1242 operands[2], operands[3]);
1247 ;; FP compares, step 1:
1248 ;; Set the FP condition codes.
1250 ;; CCFPmode compare with exceptions
1251 ;; CCFPUmode compare with no exceptions
1253 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1254 ;; used to manage the reg stack popping would not be preserved.
1256 (define_insn "*cmpfp_0"
1257 [(set (match_operand:HI 0 "register_operand" "=a")
1260 (match_operand 1 "register_operand" "f")
1261 (match_operand 2 "const0_operand" ""))]
1263 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1264 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1265 "* return output_fp_compare (insn, operands, 0, 0);"
1266 [(set_attr "type" "multi")
1267 (set_attr "unit" "i387")
1269 (cond [(match_operand:SF 1 "" "")
1271 (match_operand:DF 1 "" "")
1274 (const_string "XF")))])
1276 (define_insn_and_split "*cmpfp_0_cc"
1277 [(set (reg:CCFP FLAGS_REG)
1279 (match_operand 1 "register_operand" "f")
1280 (match_operand 2 "const0_operand" "")))
1281 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1282 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1283 && TARGET_SAHF && !TARGET_CMOVE
1284 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1286 "&& reload_completed"
1289 [(compare:CCFP (match_dup 1)(match_dup 2))]
1291 (set (reg:CC FLAGS_REG)
1292 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1294 [(set_attr "type" "multi")
1295 (set_attr "unit" "i387")
1297 (cond [(match_operand:SF 1 "" "")
1299 (match_operand:DF 1 "" "")
1302 (const_string "XF")))])
1304 (define_insn "*cmpfp_xf"
1305 [(set (match_operand:HI 0 "register_operand" "=a")
1308 (match_operand:XF 1 "register_operand" "f")
1309 (match_operand:XF 2 "register_operand" "f"))]
1312 "* return output_fp_compare (insn, operands, 0, 0);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "XF")])
1317 (define_insn_and_split "*cmpfp_xf_cc"
1318 [(set (reg:CCFP FLAGS_REG)
1320 (match_operand:XF 1 "register_operand" "f")
1321 (match_operand:XF 2 "register_operand" "f")))
1322 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1324 && TARGET_SAHF && !TARGET_CMOVE"
1326 "&& reload_completed"
1329 [(compare:CCFP (match_dup 1)(match_dup 2))]
1331 (set (reg:CC FLAGS_REG)
1332 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1334 [(set_attr "type" "multi")
1335 (set_attr "unit" "i387")
1336 (set_attr "mode" "XF")])
1338 (define_insn "*cmpfp_<mode>"
1339 [(set (match_operand:HI 0 "register_operand" "=a")
1342 (match_operand:MODEF 1 "register_operand" "f")
1343 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1346 "* return output_fp_compare (insn, operands, 0, 0);"
1347 [(set_attr "type" "multi")
1348 (set_attr "unit" "i387")
1349 (set_attr "mode" "<MODE>")])
1351 (define_insn_and_split "*cmpfp_<mode>_cc"
1352 [(set (reg:CCFP FLAGS_REG)
1354 (match_operand:MODEF 1 "register_operand" "f")
1355 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1356 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1358 && TARGET_SAHF && !TARGET_CMOVE"
1360 "&& reload_completed"
1363 [(compare:CCFP (match_dup 1)(match_dup 2))]
1365 (set (reg:CC FLAGS_REG)
1366 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1368 [(set_attr "type" "multi")
1369 (set_attr "unit" "i387")
1370 (set_attr "mode" "<MODE>")])
1372 (define_insn "*cmpfp_u"
1373 [(set (match_operand:HI 0 "register_operand" "=a")
1376 (match_operand 1 "register_operand" "f")
1377 (match_operand 2 "register_operand" "f"))]
1379 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1380 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1381 "* return output_fp_compare (insn, operands, 0, 1);"
1382 [(set_attr "type" "multi")
1383 (set_attr "unit" "i387")
1385 (cond [(match_operand:SF 1 "" "")
1387 (match_operand:DF 1 "" "")
1390 (const_string "XF")))])
1392 (define_insn_and_split "*cmpfp_u_cc"
1393 [(set (reg:CCFPU FLAGS_REG)
1395 (match_operand 1 "register_operand" "f")
1396 (match_operand 2 "register_operand" "f")))
1397 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1398 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1399 && TARGET_SAHF && !TARGET_CMOVE
1400 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1402 "&& reload_completed"
1405 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1407 (set (reg:CC FLAGS_REG)
1408 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1410 [(set_attr "type" "multi")
1411 (set_attr "unit" "i387")
1413 (cond [(match_operand:SF 1 "" "")
1415 (match_operand:DF 1 "" "")
1418 (const_string "XF")))])
1420 (define_insn "*cmpfp_<mode>"
1421 [(set (match_operand:HI 0 "register_operand" "=a")
1424 (match_operand 1 "register_operand" "f")
1425 (match_operator 3 "float_operator"
1426 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1428 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1430 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1431 "* return output_fp_compare (insn, operands, 0, 0);"
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set_attr "fp_int_src" "true")
1435 (set_attr "mode" "<MODE>")])
1437 (define_insn_and_split "*cmpfp_<mode>_cc"
1438 [(set (reg:CCFP FLAGS_REG)
1440 (match_operand 1 "register_operand" "f")
1441 (match_operator 3 "float_operator"
1442 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1443 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1444 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1445 && TARGET_SAHF && !TARGET_CMOVE
1446 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1447 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1449 "&& reload_completed"
1454 (match_op_dup 3 [(match_dup 2)]))]
1456 (set (reg:CC FLAGS_REG)
1457 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1459 [(set_attr "type" "multi")
1460 (set_attr "unit" "i387")
1461 (set_attr "fp_int_src" "true")
1462 (set_attr "mode" "<MODE>")])
1464 ;; FP compares, step 2
1465 ;; Move the fpsw to ax.
1467 (define_insn "x86_fnstsw_1"
1468 [(set (match_operand:HI 0 "register_operand" "=a")
1469 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1472 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1473 (set_attr "mode" "SI")
1474 (set_attr "unit" "i387")])
1476 ;; FP compares, step 3
1477 ;; Get ax into flags, general case.
1479 (define_insn "x86_sahf_1"
1480 [(set (reg:CC FLAGS_REG)
1481 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1485 #ifndef HAVE_AS_IX86_SAHF
1487 return ASM_BYTE "0x9e";
1492 [(set_attr "length" "1")
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")
1495 (set_attr "bdver1_decode" "direct")
1496 (set_attr "mode" "SI")])
1498 ;; Pentium Pro can do steps 1 through 3 in one go.
1499 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1500 (define_insn "*cmpfp_i_mixed"
1501 [(set (reg:CCFP FLAGS_REG)
1502 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1503 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1504 "TARGET_MIX_SSE_I387
1505 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1506 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507 "* return output_fp_compare (insn, operands, 1, 0);"
1508 [(set_attr "type" "fcmp,ssecomi")
1509 (set_attr "prefix" "orig,maybe_vex")
1511 (if_then_else (match_operand:SF 1 "" "")
1513 (const_string "DF")))
1514 (set (attr "prefix_rep")
1515 (if_then_else (eq_attr "type" "ssecomi")
1517 (const_string "*")))
1518 (set (attr "prefix_data16")
1519 (cond [(eq_attr "type" "fcmp")
1521 (eq_attr "mode" "DF")
1524 (const_string "0")))
1525 (set_attr "athlon_decode" "vector")
1526 (set_attr "amdfam10_decode" "direct")
1527 (set_attr "bdver1_decode" "double")])
1529 (define_insn "*cmpfp_i_sse"
1530 [(set (reg:CCFP FLAGS_REG)
1531 (compare:CCFP (match_operand 0 "register_operand" "x")
1532 (match_operand 1 "nonimmediate_operand" "xm")))]
1534 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1535 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1536 "* return output_fp_compare (insn, operands, 1, 0);"
1537 [(set_attr "type" "ssecomi")
1538 (set_attr "prefix" "maybe_vex")
1540 (if_then_else (match_operand:SF 1 "" "")
1542 (const_string "DF")))
1543 (set_attr "prefix_rep" "0")
1544 (set (attr "prefix_data16")
1545 (if_then_else (eq_attr "mode" "DF")
1547 (const_string "0")))
1548 (set_attr "athlon_decode" "vector")
1549 (set_attr "amdfam10_decode" "direct")
1550 (set_attr "bdver1_decode" "double")])
1552 (define_insn "*cmpfp_i_i387"
1553 [(set (reg:CCFP FLAGS_REG)
1554 (compare:CCFP (match_operand 0 "register_operand" "f")
1555 (match_operand 1 "register_operand" "f")))]
1556 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1558 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1559 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560 "* return output_fp_compare (insn, operands, 1, 0);"
1561 [(set_attr "type" "fcmp")
1563 (cond [(match_operand:SF 1 "" "")
1565 (match_operand:DF 1 "" "")
1568 (const_string "XF")))
1569 (set_attr "athlon_decode" "vector")
1570 (set_attr "amdfam10_decode" "direct")
1571 (set_attr "bdver1_decode" "double")])
1573 (define_insn "*cmpfp_iu_mixed"
1574 [(set (reg:CCFPU FLAGS_REG)
1575 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1576 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1577 "TARGET_MIX_SSE_I387
1578 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1579 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580 "* return output_fp_compare (insn, operands, 1, 1);"
1581 [(set_attr "type" "fcmp,ssecomi")
1582 (set_attr "prefix" "orig,maybe_vex")
1584 (if_then_else (match_operand:SF 1 "" "")
1586 (const_string "DF")))
1587 (set (attr "prefix_rep")
1588 (if_then_else (eq_attr "type" "ssecomi")
1590 (const_string "*")))
1591 (set (attr "prefix_data16")
1592 (cond [(eq_attr "type" "fcmp")
1594 (eq_attr "mode" "DF")
1597 (const_string "0")))
1598 (set_attr "athlon_decode" "vector")
1599 (set_attr "amdfam10_decode" "direct")
1600 (set_attr "bdver1_decode" "double")])
1602 (define_insn "*cmpfp_iu_sse"
1603 [(set (reg:CCFPU FLAGS_REG)
1604 (compare:CCFPU (match_operand 0 "register_operand" "x")
1605 (match_operand 1 "nonimmediate_operand" "xm")))]
1607 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1608 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1609 "* return output_fp_compare (insn, operands, 1, 1);"
1610 [(set_attr "type" "ssecomi")
1611 (set_attr "prefix" "maybe_vex")
1613 (if_then_else (match_operand:SF 1 "" "")
1615 (const_string "DF")))
1616 (set_attr "prefix_rep" "0")
1617 (set (attr "prefix_data16")
1618 (if_then_else (eq_attr "mode" "DF")
1620 (const_string "0")))
1621 (set_attr "athlon_decode" "vector")
1622 (set_attr "amdfam10_decode" "direct")
1623 (set_attr "bdver1_decode" "double")])
1625 (define_insn "*cmpfp_iu_387"
1626 [(set (reg:CCFPU FLAGS_REG)
1627 (compare:CCFPU (match_operand 0 "register_operand" "f")
1628 (match_operand 1 "register_operand" "f")))]
1629 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1631 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1632 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1633 "* return output_fp_compare (insn, operands, 1, 1);"
1634 [(set_attr "type" "fcmp")
1636 (cond [(match_operand:SF 1 "" "")
1638 (match_operand:DF 1 "" "")
1641 (const_string "XF")))
1642 (set_attr "athlon_decode" "vector")
1643 (set_attr "amdfam10_decode" "direct")
1644 (set_attr "bdver1_decode" "direct")])
1646 ;; Push/pop instructions.
1648 (define_insn "*push<mode>2"
1649 [(set (match_operand:DWI 0 "push_operand" "=<")
1650 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1655 [(set (match_operand:TI 0 "push_operand" "")
1656 (match_operand:TI 1 "general_operand" ""))]
1657 "TARGET_64BIT && reload_completed
1658 && !SSE_REG_P (operands[1])"
1660 "ix86_split_long_move (operands); DONE;")
1662 (define_insn "*pushdi2_rex64"
1663 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1664 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1669 [(set_attr "type" "push,multi")
1670 (set_attr "mode" "DI")])
1672 ;; Convert impossible pushes of immediate to existing instructions.
1673 ;; First try to get scratch register and go through it. In case this
1674 ;; fails, push sign extended lower part first and then overwrite
1675 ;; upper part by 32bit move.
1677 [(match_scratch:DI 2 "r")
1678 (set (match_operand:DI 0 "push_operand" "")
1679 (match_operand:DI 1 "immediate_operand" ""))]
1680 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1681 && !x86_64_immediate_operand (operands[1], DImode)"
1682 [(set (match_dup 2) (match_dup 1))
1683 (set (match_dup 0) (match_dup 2))])
1685 ;; We need to define this as both peepholer and splitter for case
1686 ;; peephole2 pass is not run.
1687 ;; "&& 1" is needed to keep it from matching the previous pattern.
1689 [(set (match_operand:DI 0 "push_operand" "")
1690 (match_operand:DI 1 "immediate_operand" ""))]
1691 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1692 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1693 [(set (match_dup 0) (match_dup 1))
1694 (set (match_dup 2) (match_dup 3))]
1696 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1698 operands[1] = gen_lowpart (DImode, operands[2]);
1699 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1704 [(set (match_operand:DI 0 "push_operand" "")
1705 (match_operand:DI 1 "immediate_operand" ""))]
1706 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1707 ? epilogue_completed : reload_completed)
1708 && !symbolic_operand (operands[1], DImode)
1709 && !x86_64_immediate_operand (operands[1], DImode)"
1710 [(set (match_dup 0) (match_dup 1))
1711 (set (match_dup 2) (match_dup 3))]
1713 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1715 operands[1] = gen_lowpart (DImode, operands[2]);
1716 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1721 [(set (match_operand:DI 0 "push_operand" "")
1722 (match_operand:DI 1 "general_operand" ""))]
1723 "!TARGET_64BIT && reload_completed
1724 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1726 "ix86_split_long_move (operands); DONE;")
1728 (define_insn "*pushsi2"
1729 [(set (match_operand:SI 0 "push_operand" "=<")
1730 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1733 [(set_attr "type" "push")
1734 (set_attr "mode" "SI")])
1736 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1737 ;; "push a byte/word". But actually we use pushl, which has the effect
1738 ;; of rounding the amount pushed up to a word.
1740 ;; For TARGET_64BIT we always round up to 8 bytes.
1741 (define_insn "*push<mode>2_rex64"
1742 [(set (match_operand:SWI124 0 "push_operand" "=X")
1743 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1746 [(set_attr "type" "push")
1747 (set_attr "mode" "DI")])
1749 (define_insn "*push<mode>2"
1750 [(set (match_operand:SWI12 0 "push_operand" "=X")
1751 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1754 [(set_attr "type" "push")
1755 (set_attr "mode" "SI")])
1757 (define_insn "*push<mode>2_prologue"
1758 [(set (match_operand:P 0 "push_operand" "=<")
1759 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1760 (clobber (mem:BLK (scratch)))]
1762 "push{<imodesuffix>}\t%1"
1763 [(set_attr "type" "push")
1764 (set_attr "mode" "<MODE>")])
1766 (define_insn "*pop<mode>1"
1767 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1768 (match_operand:P 1 "pop_operand" ">"))]
1770 "pop{<imodesuffix>}\t%0"
1771 [(set_attr "type" "pop")
1772 (set_attr "mode" "<MODE>")])
1774 (define_insn "*pop<mode>1_epilogue"
1775 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1776 (match_operand:P 1 "pop_operand" ">"))
1777 (clobber (mem:BLK (scratch)))]
1779 "pop{<imodesuffix>}\t%0"
1780 [(set_attr "type" "pop")
1781 (set_attr "mode" "<MODE>")])
1783 ;; Move instructions.
1785 (define_expand "movoi"
1786 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1787 (match_operand:OI 1 "general_operand" ""))]
1789 "ix86_expand_move (OImode, operands); DONE;")
1791 (define_expand "movti"
1792 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1793 (match_operand:TI 1 "nonimmediate_operand" ""))]
1794 "TARGET_64BIT || TARGET_SSE"
1797 ix86_expand_move (TImode, operands);
1798 else if (push_operand (operands[0], TImode))
1799 ix86_expand_push (TImode, operands[1]);
1801 ix86_expand_vector_move (TImode, operands);
1805 ;; This expands to what emit_move_complex would generate if we didn't
1806 ;; have a movti pattern. Having this avoids problems with reload on
1807 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1808 ;; to have around all the time.
1809 (define_expand "movcdi"
1810 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1811 (match_operand:CDI 1 "general_operand" ""))]
1814 if (push_operand (operands[0], CDImode))
1815 emit_move_complex_push (CDImode, operands[0], operands[1]);
1817 emit_move_complex_parts (operands[0], operands[1]);
1821 (define_expand "mov<mode>"
1822 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1823 (match_operand:SWI1248x 1 "general_operand" ""))]
1825 "ix86_expand_move (<MODE>mode, operands); DONE;")
1827 (define_insn "*mov<mode>_xor"
1828 [(set (match_operand:SWI48 0 "register_operand" "=r")
1829 (match_operand:SWI48 1 "const0_operand" ""))
1830 (clobber (reg:CC FLAGS_REG))]
1833 [(set_attr "type" "alu1")
1834 (set_attr "mode" "SI")
1835 (set_attr "length_immediate" "0")])
1837 (define_insn "*mov<mode>_or"
1838 [(set (match_operand:SWI48 0 "register_operand" "=r")
1839 (match_operand:SWI48 1 "const_int_operand" ""))
1840 (clobber (reg:CC FLAGS_REG))]
1842 && operands[1] == constm1_rtx"
1843 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1844 [(set_attr "type" "alu1")
1845 (set_attr "mode" "<MODE>")
1846 (set_attr "length_immediate" "1")])
1848 (define_insn "*movoi_internal_avx"
1849 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1850 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1851 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1853 switch (which_alternative)
1856 return "vxorps\t%0, %0, %0";
1859 if (misaligned_operand (operands[0], OImode)
1860 || misaligned_operand (operands[1], OImode))
1861 return "vmovdqu\t{%1, %0|%0, %1}";
1863 return "vmovdqa\t{%1, %0|%0, %1}";
1868 [(set_attr "type" "sselog1,ssemov,ssemov")
1869 (set_attr "prefix" "vex")
1870 (set_attr "mode" "OI")])
1872 (define_insn "*movti_internal_rex64"
1873 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1874 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1875 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1877 switch (which_alternative)
1883 if (get_attr_mode (insn) == MODE_V4SF)
1884 return "%vxorps\t%0, %d0";
1886 return "%vpxor\t%0, %d0";
1889 /* TDmode values are passed as TImode on the stack. Moving them
1890 to stack may result in unaligned memory access. */
1891 if (misaligned_operand (operands[0], TImode)
1892 || misaligned_operand (operands[1], TImode))
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovups\t{%1, %0|%0, %1}";
1897 return "%vmovdqu\t{%1, %0|%0, %1}";
1901 if (get_attr_mode (insn) == MODE_V4SF)
1902 return "%vmovaps\t{%1, %0|%0, %1}";
1904 return "%vmovdqa\t{%1, %0|%0, %1}";
1910 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1911 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1913 (cond [(eq_attr "alternative" "2,3")
1915 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1917 (const_string "V4SF")
1918 (const_string "TI"))
1919 (eq_attr "alternative" "4")
1921 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1923 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1925 (const_string "V4SF")
1926 (const_string "TI"))]
1927 (const_string "DI")))])
1930 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1931 (match_operand:TI 1 "general_operand" ""))]
1933 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1935 "ix86_split_long_move (operands); DONE;")
1937 (define_insn "*movti_internal_sse"
1938 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1939 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1940 "TARGET_SSE && !TARGET_64BIT
1941 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943 switch (which_alternative)
1946 if (get_attr_mode (insn) == MODE_V4SF)
1947 return "%vxorps\t%0, %d0";
1949 return "%vpxor\t%0, %d0";
1952 /* TDmode values are passed as TImode on the stack. Moving them
1953 to stack may result in unaligned memory access. */
1954 if (misaligned_operand (operands[0], TImode)
1955 || misaligned_operand (operands[1], TImode))
1957 if (get_attr_mode (insn) == MODE_V4SF)
1958 return "%vmovups\t{%1, %0|%0, %1}";
1960 return "%vmovdqu\t{%1, %0|%0, %1}";
1964 if (get_attr_mode (insn) == MODE_V4SF)
1965 return "%vmovaps\t{%1, %0|%0, %1}";
1967 return "%vmovdqa\t{%1, %0|%0, %1}";
1973 [(set_attr "type" "sselog1,ssemov,ssemov")
1974 (set_attr "prefix" "maybe_vex")
1976 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1977 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1979 (const_string "V4SF")
1980 (and (eq_attr "alternative" "2")
1981 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1983 (const_string "V4SF")]
1984 (const_string "TI")))])
1986 (define_insn "*movdi_internal_rex64"
1987 [(set (match_operand:DI 0 "nonimmediate_operand"
1988 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1989 (match_operand:DI 1 "general_operand"
1990 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1991 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1993 switch (get_attr_type (insn))
1996 if (SSE_REG_P (operands[0]))
1997 return "movq2dq\t{%1, %0|%0, %1}";
1999 return "movdq2q\t{%1, %0|%0, %1}";
2002 if (get_attr_mode (insn) == MODE_TI)
2003 return "%vmovdqa\t{%1, %0|%0, %1}";
2004 /* Handle broken assemblers that require movd instead of movq. */
2005 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2006 return "%vmovd\t{%1, %0|%0, %1}";
2008 return "%vmovq\t{%1, %0|%0, %1}";
2011 /* Handle broken assemblers that require movd instead of movq. */
2012 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2013 return "movd\t{%1, %0|%0, %1}";
2015 return "movq\t{%1, %0|%0, %1}";
2018 return "%vpxor\t%0, %d0";
2021 return "pxor\t%0, %0";
2027 return "lea{q}\t{%a1, %0|%0, %a1}";
2030 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2031 if (get_attr_mode (insn) == MODE_SI)
2032 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2033 else if (which_alternative == 2)
2034 return "movabs{q}\t{%1, %0|%0, %1}";
2036 return "mov{q}\t{%1, %0|%0, %1}";
2040 (cond [(eq_attr "alternative" "5")
2041 (const_string "mmx")
2042 (eq_attr "alternative" "6,7,8,9,10")
2043 (const_string "mmxmov")
2044 (eq_attr "alternative" "11")
2045 (const_string "sselog1")
2046 (eq_attr "alternative" "12,13,14,15,16")
2047 (const_string "ssemov")
2048 (eq_attr "alternative" "17,18")
2049 (const_string "ssecvt")
2050 (eq_attr "alternative" "4")
2051 (const_string "multi")
2052 (match_operand:DI 1 "pic_32bit_operand" "")
2053 (const_string "lea")
2055 (const_string "imov")))
2058 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2060 (const_string "*")))
2061 (set (attr "length_immediate")
2063 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2065 (const_string "*")))
2066 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2067 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2068 (set (attr "prefix")
2069 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2070 (const_string "maybe_vex")
2071 (const_string "orig")))
2072 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2074 ;; Convert impossible stores of immediate to existing instructions.
2075 ;; First try to get scratch register and go through it. In case this
2076 ;; fails, move by 32bit parts.
2078 [(match_scratch:DI 2 "r")
2079 (set (match_operand:DI 0 "memory_operand" "")
2080 (match_operand:DI 1 "immediate_operand" ""))]
2081 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2082 && !x86_64_immediate_operand (operands[1], DImode)"
2083 [(set (match_dup 2) (match_dup 1))
2084 (set (match_dup 0) (match_dup 2))])
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 ;; "&& 1" is needed to keep it from matching the previous pattern.
2090 [(set (match_operand:DI 0 "memory_operand" "")
2091 (match_operand:DI 1 "immediate_operand" ""))]
2092 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2093 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2094 [(set (match_dup 2) (match_dup 3))
2095 (set (match_dup 4) (match_dup 5))]
2096 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2099 [(set (match_operand:DI 0 "memory_operand" "")
2100 (match_operand:DI 1 "immediate_operand" ""))]
2101 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2102 ? epilogue_completed : reload_completed)
2103 && !symbolic_operand (operands[1], DImode)
2104 && !x86_64_immediate_operand (operands[1], DImode)"
2105 [(set (match_dup 2) (match_dup 3))
2106 (set (match_dup 4) (match_dup 5))]
2107 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2109 (define_insn "*movdi_internal"
2110 [(set (match_operand:DI 0 "nonimmediate_operand"
2111 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2112 (match_operand:DI 1 "general_operand"
2113 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2114 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2119 movq\t{%1, %0|%0, %1}
2120 movq\t{%1, %0|%0, %1}
2122 %vmovq\t{%1, %0|%0, %1}
2123 %vmovdqa\t{%1, %0|%0, %1}
2124 %vmovq\t{%1, %0|%0, %1}
2126 movlps\t{%1, %0|%0, %1}
2127 movaps\t{%1, %0|%0, %1}
2128 movlps\t{%1, %0|%0, %1}"
2130 (if_then_else (eq_attr "alternative" "9,10,11,12")
2131 (const_string "noavx")
2132 (const_string "base")))
2133 (set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2134 (set (attr "prefix")
2135 (if_then_else (eq_attr "alternative" "5,6,7,8")
2136 (const_string "maybe_vex")
2137 (const_string "orig")))
2138 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2141 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2142 (match_operand:DI 1 "general_operand" ""))]
2143 "!TARGET_64BIT && reload_completed
2144 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2145 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2147 "ix86_split_long_move (operands); DONE;")
2149 (define_insn "*movsi_internal"
2150 [(set (match_operand:SI 0 "nonimmediate_operand"
2151 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2152 (match_operand:SI 1 "general_operand"
2153 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2154 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2156 switch (get_attr_type (insn))
2159 if (get_attr_mode (insn) == MODE_TI)
2160 return "%vpxor\t%0, %d0";
2161 return "%vxorps\t%0, %d0";
2164 switch (get_attr_mode (insn))
2167 return "%vmovdqa\t{%1, %0|%0, %1}";
2169 return "%vmovaps\t{%1, %0|%0, %1}";
2171 return "%vmovd\t{%1, %0|%0, %1}";
2173 return "%vmovss\t{%1, %0|%0, %1}";
2179 return "pxor\t%0, %0";
2182 if (get_attr_mode (insn) == MODE_DI)
2183 return "movq\t{%1, %0|%0, %1}";
2184 return "movd\t{%1, %0|%0, %1}";
2187 return "lea{l}\t{%a1, %0|%0, %a1}";
2190 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2191 return "mov{l}\t{%1, %0|%0, %1}";
2195 (cond [(eq_attr "alternative" "2")
2196 (const_string "mmx")
2197 (eq_attr "alternative" "3,4,5")
2198 (const_string "mmxmov")
2199 (eq_attr "alternative" "6")
2200 (const_string "sselog1")
2201 (eq_attr "alternative" "7,8,9,10,11")
2202 (const_string "ssemov")
2203 (match_operand:DI 1 "pic_32bit_operand" "")
2204 (const_string "lea")
2206 (const_string "imov")))
2207 (set (attr "prefix")
2208 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2209 (const_string "orig")
2210 (const_string "maybe_vex")))
2211 (set (attr "prefix_data16")
2212 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2214 (const_string "*")))
2216 (cond [(eq_attr "alternative" "2,3")
2218 (eq_attr "alternative" "6,7")
2220 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2221 (const_string "V4SF")
2222 (const_string "TI"))
2223 (and (eq_attr "alternative" "8,9,10,11")
2224 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2227 (const_string "SI")))])
2229 (define_insn "*movhi_internal"
2230 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2231 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2232 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2234 switch (get_attr_type (insn))
2237 /* movzwl is faster than movw on p2 due to partial word stalls,
2238 though not as fast as an aligned movl. */
2239 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2241 if (get_attr_mode (insn) == MODE_SI)
2242 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2244 return "mov{w}\t{%1, %0|%0, %1}";
2248 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2250 (const_string "imov")
2251 (and (eq_attr "alternative" "0")
2252 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2254 (eq (symbol_ref "TARGET_HIMODE_MATH")
2256 (const_string "imov")
2257 (and (eq_attr "alternative" "1,2")
2258 (match_operand:HI 1 "aligned_operand" ""))
2259 (const_string "imov")
2260 (and (ne (symbol_ref "TARGET_MOVX")
2262 (eq_attr "alternative" "0,2"))
2263 (const_string "imovx")
2265 (const_string "imov")))
2267 (cond [(eq_attr "type" "imovx")
2269 (and (eq_attr "alternative" "1,2")
2270 (match_operand:HI 1 "aligned_operand" ""))
2272 (and (eq_attr "alternative" "0")
2273 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2275 (eq (symbol_ref "TARGET_HIMODE_MATH")
2279 (const_string "HI")))])
2281 ;; Situation is quite tricky about when to choose full sized (SImode) move
2282 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2283 ;; partial register dependency machines (such as AMD Athlon), where QImode
2284 ;; moves issue extra dependency and for partial register stalls machines
2285 ;; that don't use QImode patterns (and QImode move cause stall on the next
2288 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2289 ;; register stall machines with, where we use QImode instructions, since
2290 ;; partial register stall can be caused there. Then we use movzx.
2291 (define_insn "*movqi_internal"
2292 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2293 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2294 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2296 switch (get_attr_type (insn))
2299 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2300 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2302 if (get_attr_mode (insn) == MODE_SI)
2303 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2305 return "mov{b}\t{%1, %0|%0, %1}";
2309 (cond [(and (eq_attr "alternative" "5")
2310 (not (match_operand:QI 1 "aligned_operand" "")))
2311 (const_string "imovx")
2312 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2314 (const_string "imov")
2315 (and (eq_attr "alternative" "3")
2316 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2318 (eq (symbol_ref "TARGET_QIMODE_MATH")
2320 (const_string "imov")
2321 (eq_attr "alternative" "3,5")
2322 (const_string "imovx")
2323 (and (ne (symbol_ref "TARGET_MOVX")
2325 (eq_attr "alternative" "2"))
2326 (const_string "imovx")
2328 (const_string "imov")))
2330 (cond [(eq_attr "alternative" "3,4,5")
2332 (eq_attr "alternative" "6")
2334 (eq_attr "type" "imovx")
2336 (and (eq_attr "type" "imov")
2337 (and (eq_attr "alternative" "0,1")
2338 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2340 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2342 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2345 ;; Avoid partial register stalls when not using QImode arithmetic
2346 (and (eq_attr "type" "imov")
2347 (and (eq_attr "alternative" "0,1")
2348 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2350 (eq (symbol_ref "TARGET_QIMODE_MATH")
2354 (const_string "QI")))])
2356 ;; Stores and loads of ax to arbitrary constant address.
2357 ;; We fake an second form of instruction to force reload to load address
2358 ;; into register when rax is not available
2359 (define_insn "*movabs<mode>_1"
2360 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2361 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2362 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2364 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2365 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2366 [(set_attr "type" "imov")
2367 (set_attr "modrm" "0,*")
2368 (set_attr "length_address" "8,0")
2369 (set_attr "length_immediate" "0,*")
2370 (set_attr "memory" "store")
2371 (set_attr "mode" "<MODE>")])
2373 (define_insn "*movabs<mode>_2"
2374 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2375 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2376 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2378 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2379 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2380 [(set_attr "type" "imov")
2381 (set_attr "modrm" "0,*")
2382 (set_attr "length_address" "8,0")
2383 (set_attr "length_immediate" "0")
2384 (set_attr "memory" "load")
2385 (set_attr "mode" "<MODE>")])
2387 (define_insn "*swap<mode>"
2388 [(set (match_operand:SWI48 0 "register_operand" "+r")
2389 (match_operand:SWI48 1 "register_operand" "+r"))
2393 "xchg{<imodesuffix>}\t%1, %0"
2394 [(set_attr "type" "imov")
2395 (set_attr "mode" "<MODE>")
2396 (set_attr "pent_pair" "np")
2397 (set_attr "athlon_decode" "vector")
2398 (set_attr "amdfam10_decode" "double")
2399 (set_attr "bdver1_decode" "double")])
2401 (define_insn "*swap<mode>_1"
2402 [(set (match_operand:SWI12 0 "register_operand" "+r")
2403 (match_operand:SWI12 1 "register_operand" "+r"))
2406 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2408 [(set_attr "type" "imov")
2409 (set_attr "mode" "SI")
2410 (set_attr "pent_pair" "np")
2411 (set_attr "athlon_decode" "vector")
2412 (set_attr "amdfam10_decode" "double")
2413 (set_attr "bdver1_decode" "double")])
2415 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2416 ;; is disabled for AMDFAM10
2417 (define_insn "*swap<mode>_2"
2418 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2419 (match_operand:SWI12 1 "register_operand" "+<r>"))
2422 "TARGET_PARTIAL_REG_STALL"
2423 "xchg{<imodesuffix>}\t%1, %0"
2424 [(set_attr "type" "imov")
2425 (set_attr "mode" "<MODE>")
2426 (set_attr "pent_pair" "np")
2427 (set_attr "athlon_decode" "vector")])
2429 (define_expand "movstrict<mode>"
2430 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2431 (match_operand:SWI12 1 "general_operand" ""))]
2434 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2436 if (GET_CODE (operands[0]) == SUBREG
2437 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2439 /* Don't generate memory->memory moves, go through a register */
2440 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2441 operands[1] = force_reg (<MODE>mode, operands[1]);
2444 (define_insn "*movstrict<mode>_1"
2445 [(set (strict_low_part
2446 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2447 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2448 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2449 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2450 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2451 [(set_attr "type" "imov")
2452 (set_attr "mode" "<MODE>")])
2454 (define_insn "*movstrict<mode>_xor"
2455 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2456 (match_operand:SWI12 1 "const0_operand" ""))
2457 (clobber (reg:CC FLAGS_REG))]
2459 "xor{<imodesuffix>}\t%0, %0"
2460 [(set_attr "type" "alu1")
2461 (set_attr "mode" "<MODE>")
2462 (set_attr "length_immediate" "0")])
2464 (define_insn "*mov<mode>_extv_1"
2465 [(set (match_operand:SWI24 0 "register_operand" "=R")
2466 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2470 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2471 [(set_attr "type" "imovx")
2472 (set_attr "mode" "SI")])
2474 (define_insn "*movqi_extv_1_rex64"
2475 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2476 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2481 switch (get_attr_type (insn))
2484 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2486 return "mov{b}\t{%h1, %0|%0, %h1}";
2490 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2491 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2492 (ne (symbol_ref "TARGET_MOVX")
2494 (const_string "imovx")
2495 (const_string "imov")))
2497 (if_then_else (eq_attr "type" "imovx")
2499 (const_string "QI")))])
2501 (define_insn "*movqi_extv_1"
2502 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2503 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2508 switch (get_attr_type (insn))
2511 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2513 return "mov{b}\t{%h1, %0|%0, %h1}";
2517 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2518 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2519 (ne (symbol_ref "TARGET_MOVX")
2521 (const_string "imovx")
2522 (const_string "imov")))
2524 (if_then_else (eq_attr "type" "imovx")
2526 (const_string "QI")))])
2528 (define_insn "*mov<mode>_extzv_1"
2529 [(set (match_operand:SWI48 0 "register_operand" "=R")
2530 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2534 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535 [(set_attr "type" "imovx")
2536 (set_attr "mode" "SI")])
2538 (define_insn "*movqi_extzv_2_rex64"
2539 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2541 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2546 switch (get_attr_type (insn))
2549 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2551 return "mov{b}\t{%h1, %0|%0, %h1}";
2555 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2556 (ne (symbol_ref "TARGET_MOVX")
2558 (const_string "imovx")
2559 (const_string "imov")))
2561 (if_then_else (eq_attr "type" "imovx")
2563 (const_string "QI")))])
2565 (define_insn "*movqi_extzv_2"
2566 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2568 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2573 switch (get_attr_type (insn))
2576 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2578 return "mov{b}\t{%h1, %0|%0, %h1}";
2582 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2583 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2584 (ne (symbol_ref "TARGET_MOVX")
2586 (const_string "imovx")
2587 (const_string "imov")))
2589 (if_then_else (eq_attr "type" "imovx")
2591 (const_string "QI")))])
2593 (define_expand "mov<mode>_insv_1"
2594 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2597 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2599 (define_insn "*mov<mode>_insv_1_rex64"
2600 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2603 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2605 "mov{b}\t{%b1, %h0|%h0, %b1}"
2606 [(set_attr "type" "imov")
2607 (set_attr "mode" "QI")])
2609 (define_insn "*movsi_insv_1"
2610 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2613 (match_operand:SI 1 "general_operand" "Qmn"))]
2615 "mov{b}\t{%b1, %h0|%h0, %b1}"
2616 [(set_attr "type" "imov")
2617 (set_attr "mode" "QI")])
2619 (define_insn "*movqi_insv_2"
2620 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2623 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2626 "mov{b}\t{%h1, %h0|%h0, %h1}"
2627 [(set_attr "type" "imov")
2628 (set_attr "mode" "QI")])
2630 ;; Floating point push instructions.
2632 (define_insn "*pushtf"
2633 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2634 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2637 /* This insn should be already split before reg-stack. */
2640 [(set_attr "type" "multi")
2641 (set_attr "unit" "sse,*,*")
2642 (set_attr "mode" "TF,SI,SI")])
2645 [(set (match_operand:TF 0 "push_operand" "")
2646 (match_operand:TF 1 "sse_reg_operand" ""))]
2647 "TARGET_SSE2 && reload_completed"
2648 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2649 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2652 [(set (match_operand:TF 0 "push_operand" "")
2653 (match_operand:TF 1 "general_operand" ""))]
2654 "TARGET_SSE2 && reload_completed
2655 && !SSE_REG_P (operands[1])"
2657 "ix86_split_long_move (operands); DONE;")
2659 (define_insn "*pushxf"
2660 [(set (match_operand:XF 0 "push_operand" "=<,<")
2661 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2662 "optimize_function_for_speed_p (cfun)"
2664 /* This insn should be already split before reg-stack. */
2667 [(set_attr "type" "multi")
2668 (set_attr "unit" "i387,*")
2669 (set_attr "mode" "XF,SI")])
2671 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2672 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2673 ;; Pushing using integer instructions is longer except for constants
2674 ;; and direct memory references (assuming that any given constant is pushed
2675 ;; only once, but this ought to be handled elsewhere).
2677 (define_insn "*pushxf_nointeger"
2678 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2679 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2680 "optimize_function_for_size_p (cfun)"
2682 /* This insn should be already split before reg-stack. */
2685 [(set_attr "type" "multi")
2686 (set_attr "unit" "i387,*,*")
2687 (set_attr "mode" "XF,SI,SI")])
2690 [(set (match_operand:XF 0 "push_operand" "")
2691 (match_operand:XF 1 "fp_register_operand" ""))]
2693 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2694 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2695 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2698 [(set (match_operand:XF 0 "push_operand" "")
2699 (match_operand:XF 1 "general_operand" ""))]
2701 && !FP_REG_P (operands[1])"
2703 "ix86_split_long_move (operands); DONE;")
2705 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2706 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2707 ;; On the average, pushdf using integers can be still shorter.
2709 (define_insn "*pushdf"
2710 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2711 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2714 /* This insn should be already split before reg-stack. */
2717 [(set_attr "type" "multi")
2718 (set_attr "unit" "i387,*,*")
2719 (set_attr "mode" "DF,SI,DF")])
2721 ;; %%% Kill this when call knows how to work this out.
2723 [(set (match_operand:DF 0 "push_operand" "")
2724 (match_operand:DF 1 "any_fp_register_operand" ""))]
2726 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2727 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2730 [(set (match_operand:DF 0 "push_operand" "")
2731 (match_operand:DF 1 "general_operand" ""))]
2733 && !ANY_FP_REG_P (operands[1])"
2735 "ix86_split_long_move (operands); DONE;")
2737 (define_insn "*pushsf_rex64"
2738 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2739 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2742 /* Anything else should be already split before reg-stack. */
2743 gcc_assert (which_alternative == 1);
2744 return "push{q}\t%q1";
2746 [(set_attr "type" "multi,push,multi")
2747 (set_attr "unit" "i387,*,*")
2748 (set_attr "mode" "SF,DI,SF")])
2750 (define_insn "*pushsf"
2751 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2752 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2755 /* Anything else should be already split before reg-stack. */
2756 gcc_assert (which_alternative == 1);
2757 return "push{l}\t%1";
2759 [(set_attr "type" "multi,push,multi")
2760 (set_attr "unit" "i387,*,*")
2761 (set_attr "mode" "SF,SI,SF")])
2764 [(set (match_operand:SF 0 "push_operand" "")
2765 (match_operand:SF 1 "memory_operand" ""))]
2767 && MEM_P (operands[1])
2768 && (operands[2] = find_constant_src (insn))"
2772 ;; %%% Kill this when call knows how to work this out.
2774 [(set (match_operand:SF 0 "push_operand" "")
2775 (match_operand:SF 1 "any_fp_register_operand" ""))]
2777 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2781 ;; Floating point move instructions.
2783 (define_expand "movtf"
2784 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2785 (match_operand:TF 1 "nonimmediate_operand" ""))]
2788 ix86_expand_move (TFmode, operands);
2792 (define_expand "mov<mode>"
2793 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2794 (match_operand:X87MODEF 1 "general_operand" ""))]
2796 "ix86_expand_move (<MODE>mode, operands); DONE;")
2798 (define_insn "*movtf_internal"
2799 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2800 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2802 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2804 switch (which_alternative)
2808 if (get_attr_mode (insn) == MODE_V4SF)
2809 return "%vmovaps\t{%1, %0|%0, %1}";
2811 return "%vmovdqa\t{%1, %0|%0, %1}";
2814 return standard_sse_constant_opcode (insn, operands[1]);
2824 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2825 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2827 (cond [(eq_attr "alternative" "0,2")
2829 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2831 (const_string "V4SF")
2832 (const_string "TI"))
2833 (eq_attr "alternative" "1")
2835 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2837 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2839 (const_string "V4SF")
2840 (const_string "TI"))]
2841 (const_string "DI")))])
2844 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2845 (match_operand:TF 1 "general_operand" ""))]
2847 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2849 "ix86_split_long_move (operands); DONE;")
2851 (define_insn "*movxf_internal"
2852 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,Yx*r ,o")
2853 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2854 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2855 && (!can_create_pseudo_p ()
2856 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2857 || GET_CODE (operands[1]) != CONST_DOUBLE
2858 || (optimize_function_for_size_p (cfun)
2859 && standard_80387_constant_p (operands[1]) > 0)
2860 || memory_operand (operands[0], XFmode))"
2862 switch (which_alternative)
2866 return output_387_reg_move (insn, operands);
2869 return standard_80387_constant_opcode (operands[1]);
2877 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2878 (set_attr "mode" "XF,XF,XF,SI,SI")])
2881 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2882 (match_operand:XF 1 "general_operand" ""))]
2884 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2885 && ! (FP_REG_P (operands[0]) ||
2886 (GET_CODE (operands[0]) == SUBREG
2887 && FP_REG_P (SUBREG_REG (operands[0]))))
2888 && ! (FP_REG_P (operands[1]) ||
2889 (GET_CODE (operands[1]) == SUBREG
2890 && FP_REG_P (SUBREG_REG (operands[1]))))"
2892 "ix86_split_long_move (operands); DONE;")
2894 (define_insn "*movdf_internal_rex64"
2895 [(set (match_operand:DF 0 "nonimmediate_operand"
2896 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2897 (match_operand:DF 1 "general_operand"
2898 "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2899 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2900 && (!can_create_pseudo_p ()
2901 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2902 || GET_CODE (operands[1]) != CONST_DOUBLE
2903 || (optimize_function_for_size_p (cfun)
2904 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2905 && standard_80387_constant_p (operands[1]) > 0)
2906 || (TARGET_SSE2 && TARGET_SSE_MATH
2907 && standard_sse_constant_p (operands[1]))))
2908 || memory_operand (operands[0], DFmode))"
2910 switch (which_alternative)
2914 return output_387_reg_move (insn, operands);
2917 return standard_80387_constant_opcode (operands[1]);
2921 return "mov{q}\t{%1, %0|%0, %1}";
2924 return "movabs{q}\t{%1, %0|%0, %1}";
2930 return standard_sse_constant_opcode (insn, operands[1]);
2935 switch (get_attr_mode (insn))
2938 return "%vmovaps\t{%1, %0|%0, %1}";
2940 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2941 return "%vmovaps\t{%1, %0|%0, %1}";
2943 return "%vmovapd\t{%1, %0|%0, %1}";
2945 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946 return "%vmovaps\t{%1, %0|%0, %1}";
2948 return "%vmovdqa\t{%1, %0|%0, %1}";
2950 return "%vmovq\t{%1, %0|%0, %1}";
2952 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2953 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2955 return "%vmovsd\t{%1, %0|%0, %1}";
2957 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2959 return "%vmovlps\t{%1, %d0|%d0, %1}";
2966 /* Handle broken assemblers that require movd instead of movq. */
2967 return "%vmovd\t{%1, %0|%0, %1}";
2973 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2976 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2978 (const_string "*")))
2979 (set (attr "length_immediate")
2981 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2983 (const_string "*")))
2984 (set (attr "prefix")
2985 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2986 (const_string "orig")
2987 (const_string "maybe_vex")))
2988 (set (attr "prefix_data16")
2989 (if_then_else (eq_attr "mode" "V1DF")
2991 (const_string "*")))
2993 (cond [(eq_attr "alternative" "0,1,2")
2995 (eq_attr "alternative" "3,4,5,6,11,12")
2998 /* For SSE1, we have many fewer alternatives. */
2999 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3000 (cond [(eq_attr "alternative" "7,8")
3001 (const_string "V4SF")
3003 (const_string "V2SF"))
3005 /* xorps is one byte shorter. */
3006 (eq_attr "alternative" "7")
3007 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3009 (const_string "V4SF")
3010 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3014 (const_string "V2DF"))
3016 /* For architectures resolving dependencies on
3017 whole SSE registers use APD move to break dependency
3018 chains, otherwise use short move to avoid extra work.
3020 movaps encodes one byte shorter. */
3021 (eq_attr "alternative" "8")
3023 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3025 (const_string "V4SF")
3026 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3028 (const_string "V2DF")
3030 (const_string "DF"))
3031 /* For architectures resolving dependencies on register
3032 parts we may avoid extra work to zero out upper part
3034 (eq_attr "alternative" "9")
3036 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3038 (const_string "V1DF")
3039 (const_string "DF"))
3041 (const_string "DF")))])
3043 ;; Possible store forwarding (partial memory) stall in alternative 4.
3044 (define_insn "*movdf_internal"
3045 [(set (match_operand:DF 0 "nonimmediate_operand"
3046 "=f,m,f,Yd*r ,o ,Y2*x,Y2*x,Y2*x,m ")
3047 (match_operand:DF 1 "general_operand"
3048 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3049 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3050 && (!can_create_pseudo_p ()
3051 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3052 || GET_CODE (operands[1]) != CONST_DOUBLE
3053 || (!TARGET_INTEGER_DFMODE_MOVES
3054 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3055 && standard_80387_constant_p (operands[1]) > 0)
3056 || (TARGET_SSE2 && TARGET_SSE_MATH
3057 && standard_sse_constant_p (operands[1])))
3058 && !memory_operand (operands[0], DFmode))
3059 || ((TARGET_INTEGER_DFMODE_MOVES
3060 || !TARGET_MEMORY_MISMATCH_STALL)
3061 && memory_operand (operands[0], DFmode)))"
3063 switch (which_alternative)
3067 return output_387_reg_move (insn, operands);
3070 return standard_80387_constant_opcode (operands[1]);
3077 return standard_sse_constant_opcode (insn, operands[1]);
3082 switch (get_attr_mode (insn))
3085 return "%vmovaps\t{%1, %0|%0, %1}";
3087 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3088 return "%vmovaps\t{%1, %0|%0, %1}";
3090 return "%vmovapd\t{%1, %0|%0, %1}";
3092 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093 return "%vmovaps\t{%1, %0|%0, %1}";
3095 return "%vmovdqa\t{%1, %0|%0, %1}";
3097 return "%vmovq\t{%1, %0|%0, %1}";
3099 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3100 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3102 return "%vmovsd\t{%1, %0|%0, %1}";
3104 if (TARGET_AVX && REG_P (operands[0]))
3105 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3107 return "%vmovlpd\t{%1, %0|%0, %1}";
3109 if (TARGET_AVX && REG_P (operands[0]))
3110 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3112 return "%vmovlps\t{%1, %0|%0, %1}";
3121 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3122 (set (attr "prefix")
3123 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3124 (const_string "orig")
3125 (const_string "maybe_vex")))
3126 (set (attr "prefix_data16")
3127 (if_then_else (eq_attr "mode" "V1DF")
3129 (const_string "*")))
3131 (cond [(eq_attr "alternative" "0,1,2")
3133 (eq_attr "alternative" "3,4")
3136 /* For SSE1, we have many fewer alternatives. */
3137 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3138 (cond [(eq_attr "alternative" "5,6")
3139 (const_string "V4SF")
3141 (const_string "V2SF"))
3143 /* xorps is one byte shorter. */
3144 (eq_attr "alternative" "5")
3145 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3147 (const_string "V4SF")
3148 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3152 (const_string "V2DF"))
3154 /* For architectures resolving dependencies on
3155 whole SSE registers use APD move to break dependency
3156 chains, otherwise use short move to avoid extra work.
3158 movaps encodes one byte shorter. */
3159 (eq_attr "alternative" "6")
3161 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3163 (const_string "V4SF")
3164 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3166 (const_string "V2DF")
3168 (const_string "DF"))
3169 /* For architectures resolving dependencies on register
3170 parts we may avoid extra work to zero out upper part
3172 (eq_attr "alternative" "7")
3174 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3176 (const_string "V1DF")
3177 (const_string "DF"))
3179 (const_string "DF")))])
3182 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3183 (match_operand:DF 1 "general_operand" ""))]
3185 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3186 && ! (ANY_FP_REG_P (operands[0]) ||
3187 (GET_CODE (operands[0]) == SUBREG
3188 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3189 && ! (ANY_FP_REG_P (operands[1]) ||
3190 (GET_CODE (operands[1]) == SUBREG
3191 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3193 "ix86_split_long_move (operands); DONE;")
3195 (define_insn "*movsf_internal"
3196 [(set (match_operand:SF 0 "nonimmediate_operand"
3197 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3198 (match_operand:SF 1 "general_operand"
3199 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3200 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3201 && (!can_create_pseudo_p ()
3202 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3203 || GET_CODE (operands[1]) != CONST_DOUBLE
3204 || (optimize_function_for_size_p (cfun)
3205 && ((!TARGET_SSE_MATH
3206 && standard_80387_constant_p (operands[1]) > 0)
3208 && standard_sse_constant_p (operands[1]))))
3209 || memory_operand (operands[0], SFmode))"
3211 switch (which_alternative)
3215 return output_387_reg_move (insn, operands);
3218 return standard_80387_constant_opcode (operands[1]);
3222 return "mov{l}\t{%1, %0|%0, %1}";
3225 return standard_sse_constant_opcode (insn, operands[1]);
3228 if (get_attr_mode (insn) == MODE_V4SF)
3229 return "%vmovaps\t{%1, %0|%0, %1}";
3231 return "%vmovss\t{%1, %d0|%d0, %1}";
3233 if (TARGET_AVX && REG_P (operands[1]))
3234 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3236 return "%vmovss\t{%1, %0|%0, %1}";
3238 return "%vmovss\t{%1, %0|%0, %1}";
3240 case 9: case 10: case 14: case 15:
3241 return "movd\t{%1, %0|%0, %1}";
3244 return "movq\t{%1, %0|%0, %1}";
3247 return "%vmovd\t{%1, %0|%0, %1}";
3253 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3254 (set (attr "prefix")
3255 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3256 (const_string "maybe_vex")
3257 (const_string "orig")))
3259 (cond [(eq_attr "alternative" "3,4,9,10")
3261 (eq_attr "alternative" "5")
3263 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3265 (ne (symbol_ref "TARGET_SSE2")
3267 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3270 (const_string "V4SF"))
3271 /* For architectures resolving dependencies on
3272 whole SSE registers use APS move to break dependency
3273 chains, otherwise use short move to avoid extra work.
3275 Do the same for architectures resolving dependencies on
3276 the parts. While in DF mode it is better to always handle
3277 just register parts, the SF mode is different due to lack
3278 of instructions to load just part of the register. It is
3279 better to maintain the whole registers in single format
3280 to avoid problems on using packed logical operations. */
3281 (eq_attr "alternative" "6")
3283 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3285 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3287 (const_string "V4SF")
3288 (const_string "SF"))
3289 (eq_attr "alternative" "11")
3290 (const_string "DI")]
3291 (const_string "SF")))])
3294 [(set (match_operand 0 "register_operand" "")
3295 (match_operand 1 "memory_operand" ""))]
3297 && MEM_P (operands[1])
3298 && (GET_MODE (operands[0]) == TFmode
3299 || GET_MODE (operands[0]) == XFmode
3300 || GET_MODE (operands[0]) == DFmode
3301 || GET_MODE (operands[0]) == SFmode)
3302 && (operands[2] = find_constant_src (insn))"
3303 [(set (match_dup 0) (match_dup 2))]
3305 rtx c = operands[2];
3306 rtx r = operands[0];
3308 if (GET_CODE (r) == SUBREG)
3313 if (!standard_sse_constant_p (c))
3316 else if (FP_REG_P (r))
3318 if (!standard_80387_constant_p (c))
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))
3353 else if (MMX_REG_P (r))
3357 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3359 [(set (match_operand:X87MODEF 0 "register_operand" "")
3360 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3361 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3362 && (standard_80387_constant_p (operands[1]) == 8
3363 || standard_80387_constant_p (operands[1]) == 9)"
3364 [(set (match_dup 0)(match_dup 1))
3366 (neg:X87MODEF (match_dup 0)))]
3370 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3371 if (real_isnegzero (&r))
3372 operands[1] = CONST0_RTX (<MODE>mode);
3374 operands[1] = CONST1_RTX (<MODE>mode);
3377 (define_insn "swapxf"
3378 [(set (match_operand:XF 0 "register_operand" "+f")
3379 (match_operand:XF 1 "register_operand" "+f"))
3384 if (STACK_TOP_P (operands[0]))
3389 [(set_attr "type" "fxch")
3390 (set_attr "mode" "XF")])
3392 (define_insn "*swap<mode>"
3393 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3394 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3397 "TARGET_80387 || reload_completed"
3399 if (STACK_TOP_P (operands[0]))
3404 [(set_attr "type" "fxch")
3405 (set_attr "mode" "<MODE>")])
3407 ;; Zero extension instructions
3409 (define_expand "zero_extendsidi2"
3410 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3411 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3416 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3421 (define_insn "*zero_extendsidi2_rex64"
3422 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3424 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3427 mov\t{%k1, %k0|%k0, %k1}
3429 movd\t{%1, %0|%0, %1}
3430 movd\t{%1, %0|%0, %1}
3431 %vmovd\t{%1, %0|%0, %1}
3432 %vmovd\t{%1, %0|%0, %1}"
3433 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3434 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3435 (set_attr "prefix_0f" "0,*,*,*,*,*")
3436 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3439 [(set (match_operand:DI 0 "memory_operand" "")
3440 (zero_extend:DI (match_dup 0)))]
3442 [(set (match_dup 4) (const_int 0))]
3443 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3445 ;; %%% Kill me once multi-word ops are sane.
3446 (define_insn "zero_extendsidi2_1"
3447 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3449 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3450 (clobber (reg:CC FLAGS_REG))]
3456 movd\t{%1, %0|%0, %1}
3457 movd\t{%1, %0|%0, %1}
3458 %vmovd\t{%1, %0|%0, %1}
3459 %vmovd\t{%1, %0|%0, %1}"
3460 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3461 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3462 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3465 [(set (match_operand:DI 0 "register_operand" "")
3466 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3467 (clobber (reg:CC FLAGS_REG))]
3468 "!TARGET_64BIT && reload_completed
3469 && true_regnum (operands[0]) == true_regnum (operands[1])"
3470 [(set (match_dup 4) (const_int 0))]
3471 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3474 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3475 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3476 (clobber (reg:CC FLAGS_REG))]
3477 "!TARGET_64BIT && reload_completed
3478 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3479 [(set (match_dup 3) (match_dup 1))
3480 (set (match_dup 4) (const_int 0))]
3481 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3483 (define_insn "zero_extend<mode>di2"
3484 [(set (match_operand:DI 0 "register_operand" "=r")
3486 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3488 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3489 [(set_attr "type" "imovx")
3490 (set_attr "mode" "SI")])
3492 (define_expand "zero_extendhisi2"
3493 [(set (match_operand:SI 0 "register_operand" "")
3494 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3497 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3499 operands[1] = force_reg (HImode, operands[1]);
3500 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3505 (define_insn_and_split "zero_extendhisi2_and"
3506 [(set (match_operand:SI 0 "register_operand" "=r")
3507 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3508 (clobber (reg:CC FLAGS_REG))]
3509 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3511 "&& reload_completed"
3512 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3513 (clobber (reg:CC FLAGS_REG))])]
3515 [(set_attr "type" "alu1")
3516 (set_attr "mode" "SI")])
3518 (define_insn "*zero_extendhisi2_movzwl"
3519 [(set (match_operand:SI 0 "register_operand" "=r")
3520 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3521 "!TARGET_ZERO_EXTEND_WITH_AND
3522 || optimize_function_for_size_p (cfun)"
3523 "movz{wl|x}\t{%1, %0|%0, %1}"
3524 [(set_attr "type" "imovx")
3525 (set_attr "mode" "SI")])
3527 (define_expand "zero_extendqi<mode>2"
3529 [(set (match_operand:SWI24 0 "register_operand" "")
3530 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3531 (clobber (reg:CC FLAGS_REG))])])
3533 (define_insn "*zero_extendqi<mode>2_and"
3534 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3535 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3536 (clobber (reg:CC FLAGS_REG))]
3537 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3539 [(set_attr "type" "alu1")
3540 (set_attr "mode" "<MODE>")])
3542 ;; When source and destination does not overlap, clear destination
3543 ;; first and then do the movb
3545 [(set (match_operand:SWI24 0 "register_operand" "")
3546 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3547 (clobber (reg:CC FLAGS_REG))]
3549 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3550 && ANY_QI_REG_P (operands[0])
3551 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3552 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3553 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3555 operands[2] = gen_lowpart (QImode, operands[0]);
3556 ix86_expand_clear (operands[0]);
3559 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3560 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3561 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3562 (clobber (reg:CC FLAGS_REG))]
3563 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3565 [(set_attr "type" "imovx,alu1")
3566 (set_attr "mode" "<MODE>")])
3568 ;; For the movzbl case strip only the clobber
3570 [(set (match_operand:SWI24 0 "register_operand" "")
3571 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3572 (clobber (reg:CC FLAGS_REG))]
3574 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3575 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3577 (zero_extend:SWI24 (match_dup 1)))])
3579 ; zero extend to SImode to avoid partial register stalls
3580 (define_insn "*zero_extendqi<mode>2_movzbl"
3581 [(set (match_operand:SWI24 0 "register_operand" "=r")
3582 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3584 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3585 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3586 [(set_attr "type" "imovx")
3587 (set_attr "mode" "SI")])
3589 ;; Rest is handled by single and.
3591 [(set (match_operand:SWI24 0 "register_operand" "")
3592 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3593 (clobber (reg:CC FLAGS_REG))]
3595 && true_regnum (operands[0]) == true_regnum (operands[1])"
3596 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3597 (clobber (reg:CC FLAGS_REG))])])
3599 ;; Sign extension instructions
3601 (define_expand "extendsidi2"
3602 [(set (match_operand:DI 0 "register_operand" "")
3603 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3608 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3613 (define_insn "*extendsidi2_rex64"
3614 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3615 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3619 movs{lq|x}\t{%1, %0|%0, %1}"
3620 [(set_attr "type" "imovx")
3621 (set_attr "mode" "DI")
3622 (set_attr "prefix_0f" "0")
3623 (set_attr "modrm" "0,1")])
3625 (define_insn "extendsidi2_1"
3626 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3627 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3628 (clobber (reg:CC FLAGS_REG))
3629 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3633 ;; Extend to memory case when source register does die.
3635 [(set (match_operand:DI 0 "memory_operand" "")
3636 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3637 (clobber (reg:CC FLAGS_REG))
3638 (clobber (match_operand:SI 2 "register_operand" ""))]
3640 && dead_or_set_p (insn, operands[1])
3641 && !reg_mentioned_p (operands[1], operands[0]))"
3642 [(set (match_dup 3) (match_dup 1))
3643 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3644 (clobber (reg:CC FLAGS_REG))])
3645 (set (match_dup 4) (match_dup 1))]
3646 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3648 ;; Extend to memory case when source register does not die.
3650 [(set (match_operand:DI 0 "memory_operand" "")
3651 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3652 (clobber (reg:CC FLAGS_REG))
3653 (clobber (match_operand:SI 2 "register_operand" ""))]
3657 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3659 emit_move_insn (operands[3], operands[1]);
3661 /* Generate a cltd if possible and doing so it profitable. */
3662 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3663 && true_regnum (operands[1]) == AX_REG
3664 && true_regnum (operands[2]) == DX_REG)
3666 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3670 emit_move_insn (operands[2], operands[1]);
3671 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3673 emit_move_insn (operands[4], operands[2]);
3677 ;; Extend to register case. Optimize case where source and destination
3678 ;; registers match and cases where we can use cltd.
3680 [(set (match_operand:DI 0 "register_operand" "")
3681 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3682 (clobber (reg:CC FLAGS_REG))
3683 (clobber (match_scratch:SI 2 ""))]
3687 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3689 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3690 emit_move_insn (operands[3], operands[1]);
3692 /* Generate a cltd if possible and doing so it profitable. */
3693 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3694 && true_regnum (operands[3]) == AX_REG
3695 && true_regnum (operands[4]) == DX_REG)
3697 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3701 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3702 emit_move_insn (operands[4], operands[1]);
3704 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3708 (define_insn "extend<mode>di2"
3709 [(set (match_operand:DI 0 "register_operand" "=r")
3711 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3713 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3714 [(set_attr "type" "imovx")
3715 (set_attr "mode" "DI")])
3717 (define_insn "extendhisi2"
3718 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3719 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3722 switch (get_attr_prefix_0f (insn))
3725 return "{cwtl|cwde}";
3727 return "movs{wl|x}\t{%1, %0|%0, %1}";
3730 [(set_attr "type" "imovx")
3731 (set_attr "mode" "SI")
3732 (set (attr "prefix_0f")
3733 ;; movsx is short decodable while cwtl is vector decoded.
3734 (if_then_else (and (eq_attr "cpu" "!k6")
3735 (eq_attr "alternative" "0"))
3737 (const_string "1")))
3739 (if_then_else (eq_attr "prefix_0f" "0")
3741 (const_string "1")))])
3743 (define_insn "*extendhisi2_zext"
3744 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3747 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3750 switch (get_attr_prefix_0f (insn))
3753 return "{cwtl|cwde}";
3755 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3758 [(set_attr "type" "imovx")
3759 (set_attr "mode" "SI")
3760 (set (attr "prefix_0f")
3761 ;; movsx is short decodable while cwtl is vector decoded.
3762 (if_then_else (and (eq_attr "cpu" "!k6")
3763 (eq_attr "alternative" "0"))
3765 (const_string "1")))
3767 (if_then_else (eq_attr "prefix_0f" "0")
3769 (const_string "1")))])
3771 (define_insn "extendqisi2"
3772 [(set (match_operand:SI 0 "register_operand" "=r")
3773 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3775 "movs{bl|x}\t{%1, %0|%0, %1}"
3776 [(set_attr "type" "imovx")
3777 (set_attr "mode" "SI")])
3779 (define_insn "*extendqisi2_zext"
3780 [(set (match_operand:DI 0 "register_operand" "=r")
3782 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3784 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3785 [(set_attr "type" "imovx")
3786 (set_attr "mode" "SI")])
3788 (define_insn "extendqihi2"
3789 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3790 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3793 switch (get_attr_prefix_0f (insn))
3796 return "{cbtw|cbw}";
3798 return "movs{bw|x}\t{%1, %0|%0, %1}";
3801 [(set_attr "type" "imovx")
3802 (set_attr "mode" "HI")
3803 (set (attr "prefix_0f")
3804 ;; movsx is short decodable while cwtl is vector decoded.
3805 (if_then_else (and (eq_attr "cpu" "!k6")
3806 (eq_attr "alternative" "0"))
3808 (const_string "1")))
3810 (if_then_else (eq_attr "prefix_0f" "0")
3812 (const_string "1")))])
3814 ;; Conversions between float and double.
3816 ;; These are all no-ops in the model used for the 80387.
3817 ;; So just emit moves.
3819 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3821 [(set (match_operand:DF 0 "push_operand" "")
3822 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3824 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3825 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3828 [(set (match_operand:XF 0 "push_operand" "")
3829 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3831 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3832 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3833 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3835 (define_expand "extendsfdf2"
3836 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3837 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3838 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3840 /* ??? Needed for compress_float_constant since all fp constants
3841 are TARGET_LEGITIMATE_CONSTANT_P. */
3842 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3844 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3845 && standard_80387_constant_p (operands[1]) > 0)
3847 operands[1] = simplify_const_unary_operation
3848 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3849 emit_move_insn_1 (operands[0], operands[1]);
3852 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3856 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3858 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3860 We do the conversion post reload to avoid producing of 128bit spills
3861 that might lead to ICE on 32bit target. The sequence unlikely combine
3864 [(set (match_operand:DF 0 "register_operand" "")
3866 (match_operand:SF 1 "nonimmediate_operand" "")))]
3867 "TARGET_USE_VECTOR_FP_CONVERTS
3868 && optimize_insn_for_speed_p ()
3869 && reload_completed && SSE_REG_P (operands[0])"
3874 (parallel [(const_int 0) (const_int 1)]))))]
3876 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3877 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3878 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3879 Try to avoid move when unpacking can be done in source. */
3880 if (REG_P (operands[1]))
3882 /* If it is unsafe to overwrite upper half of source, we need
3883 to move to destination and unpack there. */
3884 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3885 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3886 && true_regnum (operands[0]) != true_regnum (operands[1]))
3888 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3889 emit_move_insn (tmp, operands[1]);
3892 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3893 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3897 emit_insn (gen_vec_setv4sf_0 (operands[3],
3898 CONST0_RTX (V4SFmode), operands[1]));
3901 (define_insn "*extendsfdf2_mixed"
3902 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3904 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3905 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3907 switch (which_alternative)
3911 return output_387_reg_move (insn, operands);
3914 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3920 [(set_attr "type" "fmov,fmov,ssecvt")
3921 (set_attr "prefix" "orig,orig,maybe_vex")
3922 (set_attr "mode" "SF,XF,DF")])
3924 (define_insn "*extendsfdf2_sse"
3925 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3926 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3927 "TARGET_SSE2 && TARGET_SSE_MATH"
3928 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3929 [(set_attr "type" "ssecvt")
3930 (set_attr "prefix" "maybe_vex")
3931 (set_attr "mode" "DF")])
3933 (define_insn "*extendsfdf2_i387"
3934 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3935 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3937 "* return output_387_reg_move (insn, operands);"
3938 [(set_attr "type" "fmov")
3939 (set_attr "mode" "SF,XF")])
3941 (define_expand "extend<mode>xf2"
3942 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3943 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3946 /* ??? Needed for compress_float_constant since all fp constants
3947 are TARGET_LEGITIMATE_CONSTANT_P. */
3948 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3950 if (standard_80387_constant_p (operands[1]) > 0)
3952 operands[1] = simplify_const_unary_operation
3953 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3954 emit_move_insn_1 (operands[0], operands[1]);
3957 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3961 (define_insn "*extend<mode>xf2_i387"
3962 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3964 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3966 "* return output_387_reg_move (insn, operands);"
3967 [(set_attr "type" "fmov")
3968 (set_attr "mode" "<MODE>,XF")])
3970 ;; %%% This seems bad bad news.
3971 ;; This cannot output into an f-reg because there is no way to be sure
3972 ;; of truncating in that case. Otherwise this is just like a simple move
3973 ;; insn. So we pretend we can output to a reg in order to get better
3974 ;; register preferencing, but we really use a stack slot.
3976 ;; Conversion from DFmode to SFmode.
3978 (define_expand "truncdfsf2"
3979 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3981 (match_operand:DF 1 "nonimmediate_operand" "")))]
3982 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3984 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3986 else if (flag_unsafe_math_optimizations)
3990 enum ix86_stack_slot slot = (virtuals_instantiated
3993 rtx temp = assign_386_stack_local (SFmode, slot);
3994 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3999 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4001 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4003 We do the conversion post reload to avoid producing of 128bit spills
4004 that might lead to ICE on 32bit target. The sequence unlikely combine
4007 [(set (match_operand:SF 0 "register_operand" "")
4009 (match_operand:DF 1 "nonimmediate_operand" "")))]
4010 "TARGET_USE_VECTOR_FP_CONVERTS
4011 && optimize_insn_for_speed_p ()
4012 && reload_completed && SSE_REG_P (operands[0])"
4015 (float_truncate:V2SF
4019 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4020 operands[3] = CONST0_RTX (V2SFmode);
4021 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4022 /* Use movsd for loading from memory, unpcklpd for registers.
4023 Try to avoid move when unpacking can be done in source, or SSE3
4024 movddup is available. */
4025 if (REG_P (operands[1]))
4028 && true_regnum (operands[0]) != true_regnum (operands[1])
4029 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4030 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4032 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4033 emit_move_insn (tmp, operands[1]);
4036 else if (!TARGET_SSE3)
4037 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4038 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4041 emit_insn (gen_sse2_loadlpd (operands[4],
4042 CONST0_RTX (V2DFmode), operands[1]));
4045 (define_expand "truncdfsf2_with_temp"
4046 [(parallel [(set (match_operand:SF 0 "" "")
4047 (float_truncate:SF (match_operand:DF 1 "" "")))
4048 (clobber (match_operand:SF 2 "" ""))])])
4050 (define_insn "*truncdfsf_fast_mixed"
4051 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4053 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4054 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4056 switch (which_alternative)
4059 return output_387_reg_move (insn, operands);
4061 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4066 [(set_attr "type" "fmov,ssecvt")
4067 (set_attr "prefix" "orig,maybe_vex")
4068 (set_attr "mode" "SF")])
4070 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4071 ;; because nothing we do here is unsafe.
4072 (define_insn "*truncdfsf_fast_sse"
4073 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4075 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4076 "TARGET_SSE2 && TARGET_SSE_MATH"
4077 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4078 [(set_attr "type" "ssecvt")
4079 (set_attr "prefix" "maybe_vex")
4080 (set_attr "mode" "SF")])
4082 (define_insn "*truncdfsf_fast_i387"
4083 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4085 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4086 "TARGET_80387 && flag_unsafe_math_optimizations"
4087 "* return output_387_reg_move (insn, operands);"
4088 [(set_attr "type" "fmov")
4089 (set_attr "mode" "SF")])
4091 (define_insn "*truncdfsf_mixed"
4092 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4094 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4095 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4096 "TARGET_MIX_SSE_I387"
4098 switch (which_alternative)
4101 return output_387_reg_move (insn, operands);
4103 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4109 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4110 (set_attr "unit" "*,*,i387,i387,i387")
4111 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4112 (set_attr "mode" "SF")])
4114 (define_insn "*truncdfsf_i387"
4115 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4117 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4118 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4121 switch (which_alternative)
4124 return output_387_reg_move (insn, operands);
4130 [(set_attr "type" "fmov,multi,multi,multi")
4131 (set_attr "unit" "*,i387,i387,i387")
4132 (set_attr "mode" "SF")])
4134 (define_insn "*truncdfsf2_i387_1"
4135 [(set (match_operand:SF 0 "memory_operand" "=m")
4137 (match_operand:DF 1 "register_operand" "f")))]
4139 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4140 && !TARGET_MIX_SSE_I387"
4141 "* return output_387_reg_move (insn, operands);"
4142 [(set_attr "type" "fmov")
4143 (set_attr "mode" "SF")])
4146 [(set (match_operand:SF 0 "register_operand" "")
4148 (match_operand:DF 1 "fp_register_operand" "")))
4149 (clobber (match_operand 2 "" ""))]
4151 [(set (match_dup 2) (match_dup 1))
4152 (set (match_dup 0) (match_dup 2))]
4153 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4155 ;; Conversion from XFmode to {SF,DF}mode
4157 (define_expand "truncxf<mode>2"
4158 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4159 (float_truncate:MODEF
4160 (match_operand:XF 1 "register_operand" "")))
4161 (clobber (match_dup 2))])]
4164 if (flag_unsafe_math_optimizations)
4166 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4167 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4168 if (reg != operands[0])
4169 emit_move_insn (operands[0], reg);
4174 enum ix86_stack_slot slot = (virtuals_instantiated
4177 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4181 (define_insn "*truncxfsf2_mixed"
4182 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4184 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4185 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4188 gcc_assert (!which_alternative);
4189 return output_387_reg_move (insn, operands);
4191 [(set_attr "type" "fmov,multi,multi,multi")
4192 (set_attr "unit" "*,i387,i387,i387")
4193 (set_attr "mode" "SF")])
4195 (define_insn "*truncxfdf2_mixed"
4196 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4198 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4199 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4202 gcc_assert (!which_alternative);
4203 return output_387_reg_move (insn, operands);
4205 [(set_attr "type" "fmov,multi,multi,multi")
4206 (set_attr "unit" "*,i387,i387,i387")
4207 (set_attr "mode" "DF")])
4209 (define_insn "truncxf<mode>2_i387_noop"
4210 [(set (match_operand:MODEF 0 "register_operand" "=f")
4211 (float_truncate:MODEF
4212 (match_operand:XF 1 "register_operand" "f")))]
4213 "TARGET_80387 && flag_unsafe_math_optimizations"
4214 "* return output_387_reg_move (insn, operands);"
4215 [(set_attr "type" "fmov")
4216 (set_attr "mode" "<MODE>")])
4218 (define_insn "*truncxf<mode>2_i387"
4219 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4220 (float_truncate:MODEF
4221 (match_operand:XF 1 "register_operand" "f")))]
4223 "* return output_387_reg_move (insn, operands);"
4224 [(set_attr "type" "fmov")
4225 (set_attr "mode" "<MODE>")])
4228 [(set (match_operand:MODEF 0 "register_operand" "")
4229 (float_truncate:MODEF
4230 (match_operand:XF 1 "register_operand" "")))
4231 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4232 "TARGET_80387 && reload_completed"
4233 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4234 (set (match_dup 0) (match_dup 2))])
4237 [(set (match_operand:MODEF 0 "memory_operand" "")
4238 (float_truncate:MODEF
4239 (match_operand:XF 1 "register_operand" "")))
4240 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4242 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4244 ;; Signed conversion to DImode.
4246 (define_expand "fix_truncxfdi2"
4247 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248 (fix:DI (match_operand:XF 1 "register_operand" "")))
4249 (clobber (reg:CC FLAGS_REG))])]
4254 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4259 (define_expand "fix_trunc<mode>di2"
4260 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4262 (clobber (reg:CC FLAGS_REG))])]
4263 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4266 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4268 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4271 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4273 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275 if (out != operands[0])
4276 emit_move_insn (operands[0], out);
4281 ;; Signed conversion to SImode.
4283 (define_expand "fix_truncxfsi2"
4284 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285 (fix:SI (match_operand:XF 1 "register_operand" "")))
4286 (clobber (reg:CC FLAGS_REG))])]
4291 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4296 (define_expand "fix_trunc<mode>si2"
4297 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4299 (clobber (reg:CC FLAGS_REG))])]
4300 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4303 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4305 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4308 if (SSE_FLOAT_MODE_P (<MODE>mode))
4310 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312 if (out != operands[0])
4313 emit_move_insn (operands[0], out);
4318 ;; Signed conversion to HImode.
4320 (define_expand "fix_trunc<mode>hi2"
4321 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323 (clobber (reg:CC FLAGS_REG))])]
4325 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4329 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4334 ;; Unsigned conversion to SImode.
4336 (define_expand "fixuns_trunc<mode>si2"
4338 [(set (match_operand:SI 0 "register_operand" "")
4340 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4342 (clobber (match_scratch:<ssevecmode> 3 ""))
4343 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4344 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4346 enum machine_mode mode = <MODE>mode;
4347 enum machine_mode vecmode = <ssevecmode>mode;
4348 REAL_VALUE_TYPE TWO31r;
4351 if (optimize_insn_for_size_p ())
4354 real_ldexp (&TWO31r, &dconst1, 31);
4355 two31 = const_double_from_real_value (TWO31r, mode);
4356 two31 = ix86_build_const_vector (vecmode, true, two31);
4357 operands[2] = force_reg (vecmode, two31);
4360 (define_insn_and_split "*fixuns_trunc<mode>_1"
4361 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4363 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4364 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4365 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4366 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4367 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4368 && optimize_function_for_speed_p (cfun)"
4370 "&& reload_completed"
4373 ix86_split_convert_uns_si_sse (operands);
4377 ;; Unsigned conversion to HImode.
4378 ;; Without these patterns, we'll try the unsigned SI conversion which
4379 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4381 (define_expand "fixuns_trunc<mode>hi2"
4383 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4384 (set (match_operand:HI 0 "nonimmediate_operand" "")
4385 (subreg:HI (match_dup 2) 0))]
4386 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4387 "operands[2] = gen_reg_rtx (SImode);")
4389 ;; When SSE is available, it is always faster to use it!
4390 (define_insn "fix_trunc<mode>di_sse"
4391 [(set (match_operand:DI 0 "register_operand" "=r,r")
4392 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4393 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4394 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4395 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4396 [(set_attr "type" "sseicvt")
4397 (set_attr "prefix" "maybe_vex")
4398 (set_attr "prefix_rex" "1")
4399 (set_attr "mode" "<MODE>")
4400 (set_attr "athlon_decode" "double,vector")
4401 (set_attr "amdfam10_decode" "double,double")
4402 (set_attr "bdver1_decode" "double,double")])
4404 (define_insn "fix_trunc<mode>si_sse"
4405 [(set (match_operand:SI 0 "register_operand" "=r,r")
4406 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4407 "SSE_FLOAT_MODE_P (<MODE>mode)
4408 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4409 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4410 [(set_attr "type" "sseicvt")
4411 (set_attr "prefix" "maybe_vex")
4412 (set_attr "mode" "<MODE>")
4413 (set_attr "athlon_decode" "double,vector")
4414 (set_attr "amdfam10_decode" "double,double")
4415 (set_attr "bdver1_decode" "double,double")])
4417 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4419 [(set (match_operand:MODEF 0 "register_operand" "")
4420 (match_operand:MODEF 1 "memory_operand" ""))
4421 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4422 (fix:SSEMODEI24 (match_dup 0)))]
4423 "TARGET_SHORTEN_X87_SSE
4424 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4425 && peep2_reg_dead_p (2, operands[0])"
4426 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4428 ;; Avoid vector decoded forms of the instruction.
4430 [(match_scratch:DF 2 "Y2")
4431 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4432 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4433 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4434 [(set (match_dup 2) (match_dup 1))
4435 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4438 [(match_scratch:SF 2 "x")
4439 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4440 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4441 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4442 [(set (match_dup 2) (match_dup 1))
4443 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4445 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4446 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4447 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4448 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4450 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4451 && (TARGET_64BIT || <MODE>mode != DImode))
4453 && can_create_pseudo_p ()"
4458 if (memory_operand (operands[0], VOIDmode))
4459 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4462 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4463 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4469 [(set_attr "type" "fisttp")
4470 (set_attr "mode" "<MODE>")])
4472 (define_insn "fix_trunc<mode>_i387_fisttp"
4473 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4474 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4475 (clobber (match_scratch:XF 2 "=&1f"))]
4476 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4478 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4479 && (TARGET_64BIT || <MODE>mode != DImode))
4480 && TARGET_SSE_MATH)"
4481 "* return output_fix_trunc (insn, operands, 1);"
4482 [(set_attr "type" "fisttp")
4483 (set_attr "mode" "<MODE>")])
4485 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4486 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4487 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4488 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4489 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4490 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4492 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && (TARGET_64BIT || <MODE>mode != DImode))
4494 && TARGET_SSE_MATH)"
4496 [(set_attr "type" "fisttp")
4497 (set_attr "mode" "<MODE>")])
4500 [(set (match_operand:X87MODEI 0 "register_operand" "")
4501 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4502 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4503 (clobber (match_scratch 3 ""))]
4505 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4506 (clobber (match_dup 3))])
4507 (set (match_dup 0) (match_dup 2))])
4510 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4511 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4512 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4513 (clobber (match_scratch 3 ""))]
4515 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4516 (clobber (match_dup 3))])])
4518 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4519 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4520 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4521 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4522 ;; function in i386.c.
4523 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4524 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4525 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4526 (clobber (reg:CC FLAGS_REG))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && (TARGET_64BIT || <MODE>mode != DImode))
4531 && can_create_pseudo_p ()"
4536 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4538 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4539 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4540 if (memory_operand (operands[0], VOIDmode))
4541 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4542 operands[2], operands[3]));
4545 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4546 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4547 operands[2], operands[3],
4552 [(set_attr "type" "fistp")
4553 (set_attr "i387_cw" "trunc")
4554 (set_attr "mode" "<MODE>")])
4556 (define_insn "fix_truncdi_i387"
4557 [(set (match_operand:DI 0 "memory_operand" "=m")
4558 (fix:DI (match_operand 1 "register_operand" "f")))
4559 (use (match_operand:HI 2 "memory_operand" "m"))
4560 (use (match_operand:HI 3 "memory_operand" "m"))
4561 (clobber (match_scratch:XF 4 "=&1f"))]
4562 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4565 "* return output_fix_trunc (insn, operands, 0);"
4566 [(set_attr "type" "fistp")
4567 (set_attr "i387_cw" "trunc")
4568 (set_attr "mode" "DI")])
4570 (define_insn "fix_truncdi_i387_with_temp"
4571 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4572 (fix:DI (match_operand 1 "register_operand" "f,f")))
4573 (use (match_operand:HI 2 "memory_operand" "m,m"))
4574 (use (match_operand:HI 3 "memory_operand" "m,m"))
4575 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4576 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4577 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4579 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4581 [(set_attr "type" "fistp")
4582 (set_attr "i387_cw" "trunc")
4583 (set_attr "mode" "DI")])
4586 [(set (match_operand:DI 0 "register_operand" "")
4587 (fix:DI (match_operand 1 "register_operand" "")))
4588 (use (match_operand:HI 2 "memory_operand" ""))
4589 (use (match_operand:HI 3 "memory_operand" ""))
4590 (clobber (match_operand:DI 4 "memory_operand" ""))
4591 (clobber (match_scratch 5 ""))]
4593 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4596 (clobber (match_dup 5))])
4597 (set (match_dup 0) (match_dup 4))])
4600 [(set (match_operand:DI 0 "memory_operand" "")
4601 (fix:DI (match_operand 1 "register_operand" "")))
4602 (use (match_operand:HI 2 "memory_operand" ""))
4603 (use (match_operand:HI 3 "memory_operand" ""))
4604 (clobber (match_operand:DI 4 "memory_operand" ""))
4605 (clobber (match_scratch 5 ""))]
4607 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4610 (clobber (match_dup 5))])])
4612 (define_insn "fix_trunc<mode>_i387"
4613 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4614 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4615 (use (match_operand:HI 2 "memory_operand" "m"))
4616 (use (match_operand:HI 3 "memory_operand" "m"))]
4617 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4619 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4620 "* return output_fix_trunc (insn, operands, 0);"
4621 [(set_attr "type" "fistp")
4622 (set_attr "i387_cw" "trunc")
4623 (set_attr "mode" "<MODE>")])
4625 (define_insn "fix_trunc<mode>_i387_with_temp"
4626 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4627 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4628 (use (match_operand:HI 2 "memory_operand" "m,m"))
4629 (use (match_operand:HI 3 "memory_operand" "m,m"))
4630 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4631 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4633 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4635 [(set_attr "type" "fistp")
4636 (set_attr "i387_cw" "trunc")
4637 (set_attr "mode" "<MODE>")])
4640 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4641 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4642 (use (match_operand:HI 2 "memory_operand" ""))
4643 (use (match_operand:HI 3 "memory_operand" ""))
4644 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4646 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4648 (use (match_dup 3))])
4649 (set (match_dup 0) (match_dup 4))])
4652 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4653 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4654 (use (match_operand:HI 2 "memory_operand" ""))
4655 (use (match_operand:HI 3 "memory_operand" ""))
4656 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4658 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4660 (use (match_dup 3))])])
4662 (define_insn "x86_fnstcw_1"
4663 [(set (match_operand:HI 0 "memory_operand" "=m")
4664 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4667 [(set (attr "length")
4668 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4669 (set_attr "mode" "HI")
4670 (set_attr "unit" "i387")
4671 (set_attr "bdver1_decode" "vector")])
4673 (define_insn "x86_fldcw_1"
4674 [(set (reg:HI FPCR_REG)
4675 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4678 [(set (attr "length")
4679 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4680 (set_attr "mode" "HI")
4681 (set_attr "unit" "i387")
4682 (set_attr "athlon_decode" "vector")
4683 (set_attr "amdfam10_decode" "vector")
4684 (set_attr "bdver1_decode" "vector")])
4686 ;; Conversion between fixed point and floating point.
4688 ;; Even though we only accept memory inputs, the backend _really_
4689 ;; wants to be able to do this between registers.
4691 (define_expand "floathi<mode>2"
4692 [(set (match_operand:X87MODEF 0 "register_operand" "")
4693 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696 || TARGET_MIX_SSE_I387)")
4698 ;; Pre-reload splitter to add memory clobber to the pattern.
4699 (define_insn_and_split "*floathi<mode>2_1"
4700 [(set (match_operand:X87MODEF 0 "register_operand" "")
4701 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4703 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4704 || TARGET_MIX_SSE_I387)
4705 && can_create_pseudo_p ()"
4708 [(parallel [(set (match_dup 0)
4709 (float:X87MODEF (match_dup 1)))
4710 (clobber (match_dup 2))])]
4711 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4713 (define_insn "*floathi<mode>2_i387_with_temp"
4714 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4715 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4716 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719 || TARGET_MIX_SSE_I387)"
4721 [(set_attr "type" "fmov,multi")
4722 (set_attr "mode" "<MODE>")
4723 (set_attr "unit" "*,i387")
4724 (set_attr "fp_int_src" "true")])
4726 (define_insn "*floathi<mode>2_i387"
4727 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4728 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4731 || TARGET_MIX_SSE_I387)"
4733 [(set_attr "type" "fmov")
4734 (set_attr "mode" "<MODE>")
4735 (set_attr "fp_int_src" "true")])
4738 [(set (match_operand:X87MODEF 0 "register_operand" "")
4739 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4740 (clobber (match_operand:HI 2 "memory_operand" ""))]
4742 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4743 || TARGET_MIX_SSE_I387)
4744 && reload_completed"
4745 [(set (match_dup 2) (match_dup 1))
4746 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4749 [(set (match_operand:X87MODEF 0 "register_operand" "")
4750 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4751 (clobber (match_operand:HI 2 "memory_operand" ""))]
4753 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4754 || TARGET_MIX_SSE_I387)
4755 && reload_completed"
4756 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4758 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4759 [(set (match_operand:X87MODEF 0 "register_operand" "")
4761 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4763 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4764 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4766 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4767 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4768 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4770 rtx reg = gen_reg_rtx (XFmode);
4771 rtx (*insn)(rtx, rtx);
4773 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4775 if (<X87MODEF:MODE>mode == SFmode)
4776 insn = gen_truncxfsf2;
4777 else if (<X87MODEF:MODE>mode == DFmode)
4778 insn = gen_truncxfdf2;
4782 emit_insn (insn (operands[0], reg));
4787 ;; Pre-reload splitter to add memory clobber to the pattern.
4788 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4789 [(set (match_operand:X87MODEF 0 "register_operand" "")
4790 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4792 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4793 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4794 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4795 || TARGET_MIX_SSE_I387))
4796 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4797 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4798 && ((<SSEMODEI24:MODE>mode == SImode
4799 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4800 && optimize_function_for_speed_p (cfun)
4801 && flag_trapping_math)
4802 || !(TARGET_INTER_UNIT_CONVERSIONS
4803 || optimize_function_for_size_p (cfun)))))
4804 && can_create_pseudo_p ()"
4807 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4808 (clobber (match_dup 2))])]
4810 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4812 /* Avoid store forwarding (partial memory) stall penalty
4813 by passing DImode value through XMM registers. */
4814 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4815 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4816 && optimize_function_for_speed_p (cfun))
4818 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4825 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4826 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4828 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4829 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4830 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4831 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4833 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4834 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4835 (set_attr "unit" "*,i387,*,*,*")
4836 (set_attr "athlon_decode" "*,*,double,direct,double")
4837 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4838 (set_attr "bdver1_decode" "*,*,double,direct,double")
4839 (set_attr "fp_int_src" "true")])
4841 (define_insn "*floatsi<mode>2_vector_mixed"
4842 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4843 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4844 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4845 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4849 [(set_attr "type" "fmov,sseicvt")
4850 (set_attr "mode" "<MODE>,<ssevecmode>")
4851 (set_attr "unit" "i387,*")
4852 (set_attr "athlon_decode" "*,direct")
4853 (set_attr "amdfam10_decode" "*,double")
4854 (set_attr "bdver1_decode" "*,direct")
4855 (set_attr "fp_int_src" "true")])
4857 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4858 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4860 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4861 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4862 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4863 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4865 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4866 (set_attr "mode" "<MODEF:MODE>")
4867 (set_attr "unit" "*,i387,*,*")
4868 (set_attr "athlon_decode" "*,*,double,direct")
4869 (set_attr "amdfam10_decode" "*,*,vector,double")
4870 (set_attr "bdver1_decode" "*,*,double,direct")
4871 (set_attr "fp_int_src" "true")])
4874 [(set (match_operand:MODEF 0 "register_operand" "")
4875 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4876 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4877 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4878 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4879 && TARGET_INTER_UNIT_CONVERSIONS
4881 && (SSE_REG_P (operands[0])
4882 || (GET_CODE (operands[0]) == SUBREG
4883 && SSE_REG_P (operands[0])))"
4884 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4887 [(set (match_operand:MODEF 0 "register_operand" "")
4888 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4889 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4890 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4891 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4892 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4894 && (SSE_REG_P (operands[0])
4895 || (GET_CODE (operands[0]) == SUBREG
4896 && SSE_REG_P (operands[0])))"
4897 [(set (match_dup 2) (match_dup 1))
4898 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4900 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
4901 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4903 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
4904 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4905 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4906 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4909 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
4910 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4911 [(set_attr "type" "fmov,sseicvt,sseicvt")
4912 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4913 (set_attr "mode" "<MODEF:MODE>")
4914 (set (attr "prefix_rex")
4916 (and (eq_attr "prefix" "maybe_vex")
4917 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4919 (const_string "*")))
4920 (set_attr "unit" "i387,*,*")
4921 (set_attr "athlon_decode" "*,double,direct")
4922 (set_attr "amdfam10_decode" "*,vector,double")
4923 (set_attr "bdver1_decode" "*,double,direct")
4924 (set_attr "fp_int_src" "true")])
4926 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
4927 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4929 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
4930 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4931 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4935 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4936 [(set_attr "type" "fmov,sseicvt")
4937 (set_attr "prefix" "orig,maybe_vex")
4938 (set_attr "mode" "<MODEF:MODE>")
4939 (set (attr "prefix_rex")
4941 (and (eq_attr "prefix" "maybe_vex")
4942 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4944 (const_string "*")))
4945 (set_attr "athlon_decode" "*,direct")
4946 (set_attr "amdfam10_decode" "*,double")
4947 (set_attr "bdver1_decode" "*,direct")
4948 (set_attr "fp_int_src" "true")])
4950 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4951 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4953 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4954 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4955 "TARGET_SSE2 && TARGET_SSE_MATH
4956 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4958 [(set_attr "type" "sseicvt")
4959 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4960 (set_attr "athlon_decode" "double,direct,double")
4961 (set_attr "amdfam10_decode" "vector,double,double")
4962 (set_attr "bdver1_decode" "double,direct,double")
4963 (set_attr "fp_int_src" "true")])
4965 (define_insn "*floatsi<mode>2_vector_sse"
4966 [(set (match_operand:MODEF 0 "register_operand" "=x")
4967 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4968 "TARGET_SSE2 && TARGET_SSE_MATH
4969 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4971 [(set_attr "type" "sseicvt")
4972 (set_attr "mode" "<MODE>")
4973 (set_attr "athlon_decode" "direct")
4974 (set_attr "amdfam10_decode" "double")
4975 (set_attr "bdver1_decode" "direct")
4976 (set_attr "fp_int_src" "true")])
4979 [(set (match_operand:MODEF 0 "register_operand" "")
4980 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4981 (clobber (match_operand:SI 2 "memory_operand" ""))]
4982 "TARGET_SSE2 && TARGET_SSE_MATH
4983 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4985 && (SSE_REG_P (operands[0])
4986 || (GET_CODE (operands[0]) == SUBREG
4987 && SSE_REG_P (operands[0])))"
4990 rtx op1 = operands[1];
4992 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4994 if (GET_CODE (op1) == SUBREG)
4995 op1 = SUBREG_REG (op1);
4997 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4999 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5000 emit_insn (gen_sse2_loadld (operands[4],
5001 CONST0_RTX (V4SImode), operands[1]));
5003 /* We can ignore possible trapping value in the
5004 high part of SSE register for non-trapping math. */
5005 else if (SSE_REG_P (op1) && !flag_trapping_math)
5006 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5009 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5010 emit_move_insn (operands[2], operands[1]);
5011 emit_insn (gen_sse2_loadld (operands[4],
5012 CONST0_RTX (V4SImode), operands[2]));
5015 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5020 [(set (match_operand:MODEF 0 "register_operand" "")
5021 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5022 (clobber (match_operand:SI 2 "memory_operand" ""))]
5023 "TARGET_SSE2 && TARGET_SSE_MATH
5024 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5026 && (SSE_REG_P (operands[0])
5027 || (GET_CODE (operands[0]) == SUBREG
5028 && SSE_REG_P (operands[0])))"
5031 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5033 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5035 emit_insn (gen_sse2_loadld (operands[4],
5036 CONST0_RTX (V4SImode), operands[1]));
5038 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5043 [(set (match_operand:MODEF 0 "register_operand" "")
5044 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5045 "TARGET_SSE2 && TARGET_SSE_MATH
5046 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5048 && (SSE_REG_P (operands[0])
5049 || (GET_CODE (operands[0]) == SUBREG
5050 && SSE_REG_P (operands[0])))"
5053 rtx op1 = operands[1];
5055 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5057 if (GET_CODE (op1) == SUBREG)
5058 op1 = SUBREG_REG (op1);
5060 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5062 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5063 emit_insn (gen_sse2_loadld (operands[4],
5064 CONST0_RTX (V4SImode), operands[1]));
5066 /* We can ignore possible trapping value in the
5067 high part of SSE register for non-trapping math. */
5068 else if (SSE_REG_P (op1) && !flag_trapping_math)
5069 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5073 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5078 [(set (match_operand:MODEF 0 "register_operand" "")
5079 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5080 "TARGET_SSE2 && TARGET_SSE_MATH
5081 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5083 && (SSE_REG_P (operands[0])
5084 || (GET_CODE (operands[0]) == SUBREG
5085 && SSE_REG_P (operands[0])))"
5088 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5090 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5092 emit_insn (gen_sse2_loadld (operands[4],
5093 CONST0_RTX (V4SImode), operands[1]));
5095 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5099 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5100 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5102 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5103 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5104 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5105 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5107 [(set_attr "type" "sseicvt")
5108 (set_attr "mode" "<MODEF:MODE>")
5109 (set_attr "athlon_decode" "double,direct")
5110 (set_attr "amdfam10_decode" "vector,double")
5111 (set_attr "bdver1_decode" "double,direct")
5112 (set_attr "fp_int_src" "true")])
5114 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5115 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5117 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5118 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5119 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5120 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5121 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5122 [(set_attr "type" "sseicvt")
5123 (set_attr "prefix" "maybe_vex")
5124 (set_attr "mode" "<MODEF:MODE>")
5125 (set (attr "prefix_rex")
5127 (and (eq_attr "prefix" "maybe_vex")
5128 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5130 (const_string "*")))
5131 (set_attr "athlon_decode" "double,direct")
5132 (set_attr "amdfam10_decode" "vector,double")
5133 (set_attr "bdver1_decode" "double,direct")
5134 (set_attr "fp_int_src" "true")])
5137 [(set (match_operand:MODEF 0 "register_operand" "")
5138 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5139 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5140 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5141 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5142 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5144 && (SSE_REG_P (operands[0])
5145 || (GET_CODE (operands[0]) == SUBREG
5146 && SSE_REG_P (operands[0])))"
5147 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5149 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5150 [(set (match_operand:MODEF 0 "register_operand" "=x")
5152 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5153 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5154 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5155 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5156 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5157 [(set_attr "type" "sseicvt")
5158 (set_attr "prefix" "maybe_vex")
5159 (set_attr "mode" "<MODEF:MODE>")
5160 (set (attr "prefix_rex")
5162 (and (eq_attr "prefix" "maybe_vex")
5163 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5165 (const_string "*")))
5166 (set_attr "athlon_decode" "direct")
5167 (set_attr "amdfam10_decode" "double")
5168 (set_attr "bdver1_decode" "direct")
5169 (set_attr "fp_int_src" "true")])
5172 [(set (match_operand:MODEF 0 "register_operand" "")
5173 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5174 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5175 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5176 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5177 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5179 && (SSE_REG_P (operands[0])
5180 || (GET_CODE (operands[0]) == SUBREG
5181 && SSE_REG_P (operands[0])))"
5182 [(set (match_dup 2) (match_dup 1))
5183 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5186 [(set (match_operand:MODEF 0 "register_operand" "")
5187 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5188 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5189 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5190 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5192 && (SSE_REG_P (operands[0])
5193 || (GET_CODE (operands[0]) == SUBREG
5194 && SSE_REG_P (operands[0])))"
5195 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5197 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5198 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5200 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5201 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5203 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5207 [(set_attr "type" "fmov,multi")
5208 (set_attr "mode" "<X87MODEF:MODE>")
5209 (set_attr "unit" "*,i387")
5210 (set_attr "fp_int_src" "true")])
5212 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5213 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5215 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5217 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5219 [(set_attr "type" "fmov")
5220 (set_attr "mode" "<X87MODEF:MODE>")
5221 (set_attr "fp_int_src" "true")])
5224 [(set (match_operand:X87MODEF 0 "register_operand" "")
5225 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5226 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5228 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5230 && FP_REG_P (operands[0])"
5231 [(set (match_dup 2) (match_dup 1))
5232 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5235 [(set (match_operand:X87MODEF 0 "register_operand" "")
5236 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5237 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5239 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5241 && FP_REG_P (operands[0])"
5242 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5244 ;; Avoid store forwarding (partial memory) stall penalty
5245 ;; by passing DImode value through XMM registers. */
5247 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5248 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5250 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5251 (clobber (match_scratch:V4SI 3 "=X,x"))
5252 (clobber (match_scratch:V4SI 4 "=X,x"))
5253 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5254 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5255 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5256 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5258 [(set_attr "type" "multi")
5259 (set_attr "mode" "<X87MODEF:MODE>")
5260 (set_attr "unit" "i387")
5261 (set_attr "fp_int_src" "true")])
5264 [(set (match_operand:X87MODEF 0 "register_operand" "")
5265 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5266 (clobber (match_scratch:V4SI 3 ""))
5267 (clobber (match_scratch:V4SI 4 ""))
5268 (clobber (match_operand:DI 2 "memory_operand" ""))]
5269 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5270 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5271 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5273 && FP_REG_P (operands[0])"
5274 [(set (match_dup 2) (match_dup 3))
5275 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5277 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5278 Assemble the 64-bit DImode value in an xmm register. */
5279 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5280 gen_rtx_SUBREG (SImode, operands[1], 0)));
5281 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5282 gen_rtx_SUBREG (SImode, operands[1], 4)));
5283 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5286 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5290 [(set (match_operand:X87MODEF 0 "register_operand" "")
5291 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5292 (clobber (match_scratch:V4SI 3 ""))
5293 (clobber (match_scratch:V4SI 4 ""))
5294 (clobber (match_operand:DI 2 "memory_operand" ""))]
5295 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5296 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5297 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5299 && FP_REG_P (operands[0])"
5300 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5302 ;; Avoid store forwarding (partial memory) stall penalty by extending
5303 ;; SImode value to DImode through XMM register instead of pushing two
5304 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5305 ;; targets benefit from this optimization. Also note that fild
5306 ;; loads from memory only.
5308 (define_insn "*floatunssi<mode>2_1"
5309 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5310 (unsigned_float:X87MODEF
5311 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5312 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5313 (clobber (match_scratch:SI 3 "=X,x"))]
5315 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5318 [(set_attr "type" "multi")
5319 (set_attr "mode" "<MODE>")])
5322 [(set (match_operand:X87MODEF 0 "register_operand" "")
5323 (unsigned_float:X87MODEF
5324 (match_operand:SI 1 "register_operand" "")))
5325 (clobber (match_operand:DI 2 "memory_operand" ""))
5326 (clobber (match_scratch:SI 3 ""))]
5328 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5330 && reload_completed"
5331 [(set (match_dup 2) (match_dup 1))
5333 (float:X87MODEF (match_dup 2)))]
5334 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5337 [(set (match_operand:X87MODEF 0 "register_operand" "")
5338 (unsigned_float:X87MODEF
5339 (match_operand:SI 1 "memory_operand" "")))
5340 (clobber (match_operand:DI 2 "memory_operand" ""))
5341 (clobber (match_scratch:SI 3 ""))]
5343 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5345 && reload_completed"
5346 [(set (match_dup 2) (match_dup 3))
5348 (float:X87MODEF (match_dup 2)))]
5350 emit_move_insn (operands[3], operands[1]);
5351 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5354 (define_expand "floatunssi<mode>2"
5356 [(set (match_operand:X87MODEF 0 "register_operand" "")
5357 (unsigned_float:X87MODEF
5358 (match_operand:SI 1 "nonimmediate_operand" "")))
5359 (clobber (match_dup 2))
5360 (clobber (match_scratch:SI 3 ""))])]
5362 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5364 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5366 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5368 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5373 enum ix86_stack_slot slot = (virtuals_instantiated
5376 operands[2] = assign_386_stack_local (DImode, slot);
5380 (define_expand "floatunsdisf2"
5381 [(use (match_operand:SF 0 "register_operand" ""))
5382 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5383 "TARGET_64BIT && TARGET_SSE_MATH"
5384 "x86_emit_floatuns (operands); DONE;")
5386 (define_expand "floatunsdidf2"
5387 [(use (match_operand:DF 0 "register_operand" ""))
5388 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5389 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5390 && TARGET_SSE2 && TARGET_SSE_MATH"
5393 x86_emit_floatuns (operands);
5395 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5401 (define_expand "add<mode>3"
5402 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5403 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5404 (match_operand:SDWIM 2 "<general_operand>" "")))]
5406 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5408 (define_insn_and_split "*add<dwi>3_doubleword"
5409 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5411 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5412 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5413 (clobber (reg:CC FLAGS_REG))]
5414 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5417 [(parallel [(set (reg:CC FLAGS_REG)
5418 (unspec:CC [(match_dup 1) (match_dup 2)]
5421 (plus:DWIH (match_dup 1) (match_dup 2)))])
5422 (parallel [(set (match_dup 3)
5426 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5428 (clobber (reg:CC FLAGS_REG))])]
5429 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5431 (define_insn "*add<mode>3_cc"
5432 [(set (reg:CC FLAGS_REG)
5434 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5435 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5437 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5438 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5439 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5440 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5441 [(set_attr "type" "alu")
5442 (set_attr "mode" "<MODE>")])
5444 (define_insn "addqi3_cc"
5445 [(set (reg:CC FLAGS_REG)
5447 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5448 (match_operand:QI 2 "general_operand" "qn,qm")]
5450 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5451 (plus:QI (match_dup 1) (match_dup 2)))]
5452 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5453 "add{b}\t{%2, %0|%0, %2}"
5454 [(set_attr "type" "alu")
5455 (set_attr "mode" "QI")])
5457 (define_insn "*lea_1"
5458 [(set (match_operand:P 0 "register_operand" "=r")
5459 (match_operand:P 1 "no_seg_address_operand" "p"))]
5461 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5462 [(set_attr "type" "lea")
5463 (set_attr "mode" "<MODE>")])
5465 (define_insn "*lea_2"
5466 [(set (match_operand:SI 0 "register_operand" "=r")
5467 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5469 "lea{l}\t{%a1, %0|%0, %a1}"
5470 [(set_attr "type" "lea")
5471 (set_attr "mode" "SI")])
5473 (define_insn "*lea_2_zext"
5474 [(set (match_operand:DI 0 "register_operand" "=r")
5476 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5478 "lea{l}\t{%a1, %k0|%k0, %a1}"
5479 [(set_attr "type" "lea")
5480 (set_attr "mode" "SI")])
5482 (define_insn "*add<mode>_1"
5483 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5485 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5486 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5487 (clobber (reg:CC FLAGS_REG))]
5488 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5490 switch (get_attr_type (insn))
5496 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5497 if (operands[2] == const1_rtx)
5498 return "inc{<imodesuffix>}\t%0";
5501 gcc_assert (operands[2] == constm1_rtx);
5502 return "dec{<imodesuffix>}\t%0";
5506 /* For most processors, ADD is faster than LEA. This alternative
5507 was added to use ADD as much as possible. */
5508 if (which_alternative == 2)
5511 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5514 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5516 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5518 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5522 (cond [(eq_attr "alternative" "3")
5523 (const_string "lea")
5524 (match_operand:SWI48 2 "incdec_operand" "")
5525 (const_string "incdec")
5527 (const_string "alu")))
5528 (set (attr "length_immediate")
5530 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5532 (const_string "*")))
5533 (set_attr "mode" "<MODE>")])
5535 ;; It may seem that nonimmediate operand is proper one for operand 1.
5536 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5537 ;; we take care in ix86_binary_operator_ok to not allow two memory
5538 ;; operands so proper swapping will be done in reload. This allow
5539 ;; patterns constructed from addsi_1 to match.
5541 (define_insn "*addsi_1_zext"
5542 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5544 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5545 (match_operand:SI 2 "general_operand" "g,0,li"))))
5546 (clobber (reg:CC FLAGS_REG))]
5547 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5549 switch (get_attr_type (insn))
5555 if (operands[2] == const1_rtx)
5556 return "inc{l}\t%k0";
5559 gcc_assert (operands[2] == constm1_rtx);
5560 return "dec{l}\t%k0";
5564 /* For most processors, ADD is faster than LEA. This alternative
5565 was added to use ADD as much as possible. */
5566 if (which_alternative == 1)
5569 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5572 if (x86_maybe_negate_const_int (&operands[2], SImode))
5573 return "sub{l}\t{%2, %k0|%k0, %2}";
5575 return "add{l}\t{%2, %k0|%k0, %2}";
5579 (cond [(eq_attr "alternative" "2")
5580 (const_string "lea")
5581 (match_operand:SI 2 "incdec_operand" "")
5582 (const_string "incdec")
5584 (const_string "alu")))
5585 (set (attr "length_immediate")
5587 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5589 (const_string "*")))
5590 (set_attr "mode" "SI")])
5592 (define_insn "*addhi_1"
5593 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5594 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5595 (match_operand:HI 2 "general_operand" "rn,rm")))
5596 (clobber (reg:CC FLAGS_REG))]
5597 "TARGET_PARTIAL_REG_STALL
5598 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5600 switch (get_attr_type (insn))
5603 if (operands[2] == const1_rtx)
5604 return "inc{w}\t%0";
5607 gcc_assert (operands[2] == constm1_rtx);
5608 return "dec{w}\t%0";
5612 if (x86_maybe_negate_const_int (&operands[2], HImode))
5613 return "sub{w}\t{%2, %0|%0, %2}";
5615 return "add{w}\t{%2, %0|%0, %2}";
5619 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5620 (const_string "incdec")
5621 (const_string "alu")))
5622 (set (attr "length_immediate")
5624 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5626 (const_string "*")))
5627 (set_attr "mode" "HI")])
5629 (define_insn "*addhi_1_lea"
5630 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5631 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5632 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5633 (clobber (reg:CC FLAGS_REG))]
5634 "!TARGET_PARTIAL_REG_STALL
5635 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5637 switch (get_attr_type (insn))
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 if (operands[2] == const1_rtx)
5645 return "inc{w}\t%0";
5648 gcc_assert (operands[2] == constm1_rtx);
5649 return "dec{w}\t%0";
5653 /* For most processors, ADD is faster than LEA. This alternative
5654 was added to use ADD as much as possible. */
5655 if (which_alternative == 2)
5658 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5661 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5662 if (x86_maybe_negate_const_int (&operands[2], HImode))
5663 return "sub{w}\t{%2, %0|%0, %2}";
5665 return "add{w}\t{%2, %0|%0, %2}";
5669 (cond [(eq_attr "alternative" "3")
5670 (const_string "lea")
5671 (match_operand:HI 2 "incdec_operand" "")
5672 (const_string "incdec")
5674 (const_string "alu")))
5675 (set (attr "length_immediate")
5677 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5679 (const_string "*")))
5680 (set_attr "mode" "HI,HI,HI,SI")])
5682 ;; %%% Potential partial reg stall on alternative 2. What to do?
5683 (define_insn "*addqi_1"
5684 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5685 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5686 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5687 (clobber (reg:CC FLAGS_REG))]
5688 "TARGET_PARTIAL_REG_STALL
5689 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5691 int widen = (which_alternative == 2);
5692 switch (get_attr_type (insn))
5695 if (operands[2] == const1_rtx)
5696 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5699 gcc_assert (operands[2] == constm1_rtx);
5700 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5704 if (x86_maybe_negate_const_int (&operands[2], QImode))
5707 return "sub{l}\t{%2, %k0|%k0, %2}";
5709 return "sub{b}\t{%2, %0|%0, %2}";
5712 return "add{l}\t{%k2, %k0|%k0, %k2}";
5714 return "add{b}\t{%2, %0|%0, %2}";
5718 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5719 (const_string "incdec")
5720 (const_string "alu")))
5721 (set (attr "length_immediate")
5723 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5725 (const_string "*")))
5726 (set_attr "mode" "QI,QI,SI")])
5728 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5729 (define_insn "*addqi_1_lea"
5730 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5731 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5732 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5733 (clobber (reg:CC FLAGS_REG))]
5734 "!TARGET_PARTIAL_REG_STALL
5735 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5737 int widen = (which_alternative == 3 || which_alternative == 4);
5739 switch (get_attr_type (insn))
5745 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5746 if (operands[2] == const1_rtx)
5747 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5750 gcc_assert (operands[2] == constm1_rtx);
5751 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5755 /* For most processors, ADD is faster than LEA. These alternatives
5756 were added to use ADD as much as possible. */
5757 if (which_alternative == 2 || which_alternative == 4)
5760 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5763 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5764 if (x86_maybe_negate_const_int (&operands[2], QImode))
5767 return "sub{l}\t{%2, %k0|%k0, %2}";
5769 return "sub{b}\t{%2, %0|%0, %2}";
5772 return "add{l}\t{%k2, %k0|%k0, %k2}";
5774 return "add{b}\t{%2, %0|%0, %2}";
5778 (cond [(eq_attr "alternative" "5")
5779 (const_string "lea")
5780 (match_operand:QI 2 "incdec_operand" "")
5781 (const_string "incdec")
5783 (const_string "alu")))
5784 (set (attr "length_immediate")
5786 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5788 (const_string "*")))
5789 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5791 (define_insn "*addqi_1_slp"
5792 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5793 (plus:QI (match_dup 0)
5794 (match_operand:QI 1 "general_operand" "qn,qnm")))
5795 (clobber (reg:CC FLAGS_REG))]
5796 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5797 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5799 switch (get_attr_type (insn))
5802 if (operands[1] == const1_rtx)
5803 return "inc{b}\t%0";
5806 gcc_assert (operands[1] == constm1_rtx);
5807 return "dec{b}\t%0";
5811 if (x86_maybe_negate_const_int (&operands[1], QImode))
5812 return "sub{b}\t{%1, %0|%0, %1}";
5814 return "add{b}\t{%1, %0|%0, %1}";
5818 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5819 (const_string "incdec")
5820 (const_string "alu1")))
5821 (set (attr "memory")
5822 (if_then_else (match_operand 1 "memory_operand" "")
5823 (const_string "load")
5824 (const_string "none")))
5825 (set_attr "mode" "QI")])
5827 ;; Convert lea to the lea pattern to avoid flags dependency.
5829 [(set (match_operand 0 "register_operand" "")
5830 (plus (match_operand 1 "register_operand" "")
5831 (match_operand 2 "nonmemory_operand" "")))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5837 enum machine_mode mode = GET_MODE (operands[0]);
5839 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5840 may confuse gen_lowpart. */
5843 operands[1] = gen_lowpart (Pmode, operands[1]);
5844 operands[2] = gen_lowpart (Pmode, operands[2]);
5847 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5849 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5850 operands[0] = gen_lowpart (SImode, operands[0]);
5852 if (TARGET_64BIT && mode != Pmode)
5853 pat = gen_rtx_SUBREG (SImode, pat, 0);
5855 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5859 ;; Convert lea to the lea pattern to avoid flags dependency.
5860 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5861 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5863 [(set (match_operand:DI 0 "register_operand" "")
5864 (plus:DI (match_operand:DI 1 "register_operand" "")
5865 (match_operand:DI 2 "x86_64_immediate_operand" "")))
5866 (clobber (reg:CC FLAGS_REG))]
5867 "TARGET_64BIT && reload_completed
5868 && true_regnum (operands[0]) != true_regnum (operands[1])"
5870 (plus:DI (match_dup 1) (match_dup 2)))])
5872 ;; Convert lea to the lea pattern to avoid flags dependency.
5874 [(set (match_operand:DI 0 "register_operand" "")
5876 (plus:SI (match_operand:SI 1 "register_operand" "")
5877 (match_operand:SI 2 "nonmemory_operand" ""))))
5878 (clobber (reg:CC FLAGS_REG))]
5879 "TARGET_64BIT && reload_completed
5880 && ix86_lea_for_add_ok (insn, operands)"
5882 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5884 operands[1] = gen_lowpart (DImode, operands[1]);
5885 operands[2] = gen_lowpart (DImode, operands[2]);
5888 (define_insn "*add<mode>_2"
5889 [(set (reg FLAGS_REG)
5892 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5893 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5895 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5896 (plus:SWI (match_dup 1) (match_dup 2)))]
5897 "ix86_match_ccmode (insn, CCGOCmode)
5898 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5900 switch (get_attr_type (insn))
5903 if (operands[2] == const1_rtx)
5904 return "inc{<imodesuffix>}\t%0";
5907 gcc_assert (operands[2] == constm1_rtx);
5908 return "dec{<imodesuffix>}\t%0";
5912 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5913 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5915 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5919 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5920 (const_string "incdec")
5921 (const_string "alu")))
5922 (set (attr "length_immediate")
5924 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5926 (const_string "*")))
5927 (set_attr "mode" "<MODE>")])
5929 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5930 (define_insn "*addsi_2_zext"
5931 [(set (reg FLAGS_REG)
5933 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5934 (match_operand:SI 2 "general_operand" "g"))
5936 (set (match_operand:DI 0 "register_operand" "=r")
5937 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5938 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5939 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5941 switch (get_attr_type (insn))
5944 if (operands[2] == const1_rtx)
5945 return "inc{l}\t%k0";
5948 gcc_assert (operands[2] == constm1_rtx);
5949 return "dec{l}\t%k0";
5953 if (x86_maybe_negate_const_int (&operands[2], SImode))
5954 return "sub{l}\t{%2, %k0|%k0, %2}";
5956 return "add{l}\t{%2, %k0|%k0, %2}";
5960 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5961 (const_string "incdec")
5962 (const_string "alu")))
5963 (set (attr "length_immediate")
5965 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5967 (const_string "*")))
5968 (set_attr "mode" "SI")])
5970 (define_insn "*add<mode>_3"
5971 [(set (reg FLAGS_REG)
5973 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5974 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5975 (clobber (match_scratch:SWI 0 "=<r>"))]
5976 "ix86_match_ccmode (insn, CCZmode)
5977 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5979 switch (get_attr_type (insn))
5982 if (operands[2] == const1_rtx)
5983 return "inc{<imodesuffix>}\t%0";
5986 gcc_assert (operands[2] == constm1_rtx);
5987 return "dec{<imodesuffix>}\t%0";
5991 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5992 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5994 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5998 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5999 (const_string "incdec")
6000 (const_string "alu")))
6001 (set (attr "length_immediate")
6003 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6005 (const_string "*")))
6006 (set_attr "mode" "<MODE>")])
6008 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6009 (define_insn "*addsi_3_zext"
6010 [(set (reg FLAGS_REG)
6012 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6013 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6014 (set (match_operand:DI 0 "register_operand" "=r")
6015 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6016 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6017 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6019 switch (get_attr_type (insn))
6022 if (operands[2] == const1_rtx)
6023 return "inc{l}\t%k0";
6026 gcc_assert (operands[2] == constm1_rtx);
6027 return "dec{l}\t%k0";
6031 if (x86_maybe_negate_const_int (&operands[2], SImode))
6032 return "sub{l}\t{%2, %k0|%k0, %2}";
6034 return "add{l}\t{%2, %k0|%k0, %2}";
6038 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6039 (const_string "incdec")
6040 (const_string "alu")))
6041 (set (attr "length_immediate")
6043 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6045 (const_string "*")))
6046 (set_attr "mode" "SI")])
6048 ; For comparisons against 1, -1 and 128, we may generate better code
6049 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6050 ; is matched then. We can't accept general immediate, because for
6051 ; case of overflows, the result is messed up.
6052 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6053 ; only for comparisons not depending on it.
6055 (define_insn "*adddi_4"
6056 [(set (reg FLAGS_REG)
6058 (match_operand:DI 1 "nonimmediate_operand" "0")
6059 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6060 (clobber (match_scratch:DI 0 "=rm"))]
6062 && ix86_match_ccmode (insn, CCGCmode)"
6064 switch (get_attr_type (insn))
6067 if (operands[2] == constm1_rtx)
6068 return "inc{q}\t%0";
6071 gcc_assert (operands[2] == const1_rtx);
6072 return "dec{q}\t%0";
6076 if (x86_maybe_negate_const_int (&operands[2], DImode))
6077 return "add{q}\t{%2, %0|%0, %2}";
6079 return "sub{q}\t{%2, %0|%0, %2}";
6083 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6084 (const_string "incdec")
6085 (const_string "alu")))
6086 (set (attr "length_immediate")
6088 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6090 (const_string "*")))
6091 (set_attr "mode" "DI")])
6093 ; For comparisons against 1, -1 and 128, we may generate better code
6094 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6095 ; is matched then. We can't accept general immediate, because for
6096 ; case of overflows, the result is messed up.
6097 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6098 ; only for comparisons not depending on it.
6100 (define_insn "*add<mode>_4"
6101 [(set (reg FLAGS_REG)
6103 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6104 (match_operand:SWI124 2 "const_int_operand" "n")))
6105 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6106 "ix86_match_ccmode (insn, CCGCmode)"
6108 switch (get_attr_type (insn))
6111 if (operands[2] == constm1_rtx)
6112 return "inc{<imodesuffix>}\t%0";
6115 gcc_assert (operands[2] == const1_rtx);
6116 return "dec{<imodesuffix>}\t%0";
6120 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6121 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6123 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6127 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6128 (const_string "incdec")
6129 (const_string "alu")))
6130 (set (attr "length_immediate")
6132 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6134 (const_string "*")))
6135 (set_attr "mode" "<MODE>")])
6137 (define_insn "*add<mode>_5"
6138 [(set (reg FLAGS_REG)
6141 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6142 (match_operand:SWI 2 "<general_operand>" "<g>"))
6144 (clobber (match_scratch:SWI 0 "=<r>"))]
6145 "ix86_match_ccmode (insn, CCGOCmode)
6146 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6148 switch (get_attr_type (insn))
6151 if (operands[2] == const1_rtx)
6152 return "inc{<imodesuffix>}\t%0";
6155 gcc_assert (operands[2] == constm1_rtx);
6156 return "dec{<imodesuffix>}\t%0";
6160 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6161 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6163 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6167 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6168 (const_string "incdec")
6169 (const_string "alu")))
6170 (set (attr "length_immediate")
6172 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6174 (const_string "*")))
6175 (set_attr "mode" "<MODE>")])
6177 (define_insn "*addqi_ext_1_rex64"
6178 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6183 (match_operand 1 "ext_register_operand" "0")
6186 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6187 (clobber (reg:CC FLAGS_REG))]
6190 switch (get_attr_type (insn))
6193 if (operands[2] == const1_rtx)
6194 return "inc{b}\t%h0";
6197 gcc_assert (operands[2] == constm1_rtx);
6198 return "dec{b}\t%h0";
6202 return "add{b}\t{%2, %h0|%h0, %2}";
6206 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6207 (const_string "incdec")
6208 (const_string "alu")))
6209 (set_attr "modrm" "1")
6210 (set_attr "mode" "QI")])
6212 (define_insn "addqi_ext_1"
6213 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6218 (match_operand 1 "ext_register_operand" "0")
6221 (match_operand:QI 2 "general_operand" "Qmn")))
6222 (clobber (reg:CC FLAGS_REG))]
6225 switch (get_attr_type (insn))
6228 if (operands[2] == const1_rtx)
6229 return "inc{b}\t%h0";
6232 gcc_assert (operands[2] == constm1_rtx);
6233 return "dec{b}\t%h0";
6237 return "add{b}\t{%2, %h0|%h0, %2}";
6241 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6242 (const_string "incdec")
6243 (const_string "alu")))
6244 (set_attr "modrm" "1")
6245 (set_attr "mode" "QI")])
6247 (define_insn "*addqi_ext_2"
6248 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6253 (match_operand 1 "ext_register_operand" "%0")
6257 (match_operand 2 "ext_register_operand" "Q")
6260 (clobber (reg:CC FLAGS_REG))]
6262 "add{b}\t{%h2, %h0|%h0, %h2}"
6263 [(set_attr "type" "alu")
6264 (set_attr "mode" "QI")])
6266 ;; The lea patterns for non-Pmodes needs to be matched by
6267 ;; several insns converted to real lea by splitters.
6269 (define_insn_and_split "*lea_general_1"
6270 [(set (match_operand 0 "register_operand" "=r")
6271 (plus (plus (match_operand 1 "index_register_operand" "l")
6272 (match_operand 2 "register_operand" "r"))
6273 (match_operand 3 "immediate_operand" "i")))]
6274 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6275 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6276 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6277 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6278 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6279 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6280 || GET_MODE (operands[3]) == VOIDmode)"
6282 "&& reload_completed"
6286 operands[0] = gen_lowpart (SImode, operands[0]);
6287 operands[1] = gen_lowpart (Pmode, operands[1]);
6288 operands[2] = gen_lowpart (Pmode, operands[2]);
6289 operands[3] = gen_lowpart (Pmode, operands[3]);
6290 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6292 if (Pmode != SImode)
6293 pat = gen_rtx_SUBREG (SImode, pat, 0);
6294 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6297 [(set_attr "type" "lea")
6298 (set_attr "mode" "SI")])
6300 (define_insn_and_split "*lea_general_1_zext"
6301 [(set (match_operand:DI 0 "register_operand" "=r")
6304 (match_operand:SI 1 "index_register_operand" "l")
6305 (match_operand:SI 2 "register_operand" "r"))
6306 (match_operand:SI 3 "immediate_operand" "i"))))]
6309 "&& reload_completed"
6311 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6313 (match_dup 3)) 0)))]
6315 operands[1] = gen_lowpart (Pmode, operands[1]);
6316 operands[2] = gen_lowpart (Pmode, operands[2]);
6317 operands[3] = gen_lowpart (Pmode, operands[3]);
6319 [(set_attr "type" "lea")
6320 (set_attr "mode" "SI")])
6322 (define_insn_and_split "*lea_general_2"
6323 [(set (match_operand 0 "register_operand" "=r")
6324 (plus (mult (match_operand 1 "index_register_operand" "l")
6325 (match_operand 2 "const248_operand" "i"))
6326 (match_operand 3 "nonmemory_operand" "ri")))]
6327 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6328 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6329 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6330 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6331 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6332 || GET_MODE (operands[3]) == VOIDmode)"
6334 "&& reload_completed"
6338 operands[0] = gen_lowpart (SImode, operands[0]);
6339 operands[1] = gen_lowpart (Pmode, operands[1]);
6340 operands[3] = gen_lowpart (Pmode, operands[3]);
6341 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6343 if (Pmode != SImode)
6344 pat = gen_rtx_SUBREG (SImode, pat, 0);
6345 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6348 [(set_attr "type" "lea")
6349 (set_attr "mode" "SI")])
6351 (define_insn_and_split "*lea_general_2_zext"
6352 [(set (match_operand:DI 0 "register_operand" "=r")
6355 (match_operand:SI 1 "index_register_operand" "l")
6356 (match_operand:SI 2 "const248_operand" "n"))
6357 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6360 "&& reload_completed"
6362 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6364 (match_dup 3)) 0)))]
6366 operands[1] = gen_lowpart (Pmode, operands[1]);
6367 operands[3] = gen_lowpart (Pmode, operands[3]);
6369 [(set_attr "type" "lea")
6370 (set_attr "mode" "SI")])
6372 (define_insn_and_split "*lea_general_3"
6373 [(set (match_operand 0 "register_operand" "=r")
6374 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6375 (match_operand 2 "const248_operand" "i"))
6376 (match_operand 3 "register_operand" "r"))
6377 (match_operand 4 "immediate_operand" "i")))]
6378 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6379 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6380 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6381 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6382 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6384 "&& reload_completed"
6388 operands[0] = gen_lowpart (SImode, operands[0]);
6389 operands[1] = gen_lowpart (Pmode, operands[1]);
6390 operands[3] = gen_lowpart (Pmode, operands[3]);
6391 operands[4] = gen_lowpart (Pmode, operands[4]);
6392 pat = gen_rtx_PLUS (Pmode,
6393 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6397 if (Pmode != SImode)
6398 pat = gen_rtx_SUBREG (SImode, pat, 0);
6399 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6402 [(set_attr "type" "lea")
6403 (set_attr "mode" "SI")])
6405 (define_insn_and_split "*lea_general_3_zext"
6406 [(set (match_operand:DI 0 "register_operand" "=r")
6410 (match_operand:SI 1 "index_register_operand" "l")
6411 (match_operand:SI 2 "const248_operand" "n"))
6412 (match_operand:SI 3 "register_operand" "r"))
6413 (match_operand:SI 4 "immediate_operand" "i"))))]
6416 "&& reload_completed"
6418 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6421 (match_dup 4)) 0)))]
6423 operands[1] = gen_lowpart (Pmode, operands[1]);
6424 operands[3] = gen_lowpart (Pmode, operands[3]);
6425 operands[4] = gen_lowpart (Pmode, operands[4]);
6427 [(set_attr "type" "lea")
6428 (set_attr "mode" "SI")])
6430 ;; Subtract instructions
6432 (define_expand "sub<mode>3"
6433 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6434 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6435 (match_operand:SDWIM 2 "<general_operand>" "")))]
6437 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6439 (define_insn_and_split "*sub<dwi>3_doubleword"
6440 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6442 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6443 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6444 (clobber (reg:CC FLAGS_REG))]
6445 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6448 [(parallel [(set (reg:CC FLAGS_REG)
6449 (compare:CC (match_dup 1) (match_dup 2)))
6451 (minus:DWIH (match_dup 1) (match_dup 2)))])
6452 (parallel [(set (match_dup 3)
6456 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6458 (clobber (reg:CC FLAGS_REG))])]
6459 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6461 (define_insn "*sub<mode>_1"
6462 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6464 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6465 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6466 (clobber (reg:CC FLAGS_REG))]
6467 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6468 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6469 [(set_attr "type" "alu")
6470 (set_attr "mode" "<MODE>")])
6472 (define_insn "*subsi_1_zext"
6473 [(set (match_operand:DI 0 "register_operand" "=r")
6475 (minus:SI (match_operand:SI 1 "register_operand" "0")
6476 (match_operand:SI 2 "general_operand" "g"))))
6477 (clobber (reg:CC FLAGS_REG))]
6478 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6479 "sub{l}\t{%2, %k0|%k0, %2}"
6480 [(set_attr "type" "alu")
6481 (set_attr "mode" "SI")])
6483 (define_insn "*subqi_1_slp"
6484 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6485 (minus:QI (match_dup 0)
6486 (match_operand:QI 1 "general_operand" "qn,qm")))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6489 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6490 "sub{b}\t{%1, %0|%0, %1}"
6491 [(set_attr "type" "alu1")
6492 (set_attr "mode" "QI")])
6494 (define_insn "*sub<mode>_2"
6495 [(set (reg FLAGS_REG)
6498 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6499 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6501 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6502 (minus:SWI (match_dup 1) (match_dup 2)))]
6503 "ix86_match_ccmode (insn, CCGOCmode)
6504 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6505 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "mode" "<MODE>")])
6509 (define_insn "*subsi_2_zext"
6510 [(set (reg FLAGS_REG)
6512 (minus:SI (match_operand:SI 1 "register_operand" "0")
6513 (match_operand:SI 2 "general_operand" "g"))
6515 (set (match_operand:DI 0 "register_operand" "=r")
6517 (minus:SI (match_dup 1)
6519 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6520 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6521 "sub{l}\t{%2, %k0|%k0, %2}"
6522 [(set_attr "type" "alu")
6523 (set_attr "mode" "SI")])
6525 (define_insn "*sub<mode>_3"
6526 [(set (reg FLAGS_REG)
6527 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6528 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6529 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6530 (minus:SWI (match_dup 1) (match_dup 2)))]
6531 "ix86_match_ccmode (insn, CCmode)
6532 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6533 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6534 [(set_attr "type" "alu")
6535 (set_attr "mode" "<MODE>")])
6537 (define_insn "*subsi_3_zext"
6538 [(set (reg FLAGS_REG)
6539 (compare (match_operand:SI 1 "register_operand" "0")
6540 (match_operand:SI 2 "general_operand" "g")))
6541 (set (match_operand:DI 0 "register_operand" "=r")
6543 (minus:SI (match_dup 1)
6545 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6546 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6547 "sub{l}\t{%2, %1|%1, %2}"
6548 [(set_attr "type" "alu")
6549 (set_attr "mode" "SI")])
6551 ;; Add with carry and subtract with borrow
6553 (define_expand "<plusminus_insn><mode>3_carry"
6555 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6557 (match_operand:SWI 1 "nonimmediate_operand" "")
6558 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6559 [(match_operand 3 "flags_reg_operand" "")
6561 (match_operand:SWI 2 "<general_operand>" ""))))
6562 (clobber (reg:CC FLAGS_REG))])]
6563 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6565 (define_insn "*<plusminus_insn><mode>3_carry"
6566 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6568 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6570 (match_operator 3 "ix86_carry_flag_operator"
6571 [(reg FLAGS_REG) (const_int 0)])
6572 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6573 (clobber (reg:CC FLAGS_REG))]
6574 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6575 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6576 [(set_attr "type" "alu")
6577 (set_attr "use_carry" "1")
6578 (set_attr "pent_pair" "pu")
6579 (set_attr "mode" "<MODE>")])
6581 (define_insn "*addsi3_carry_zext"
6582 [(set (match_operand:DI 0 "register_operand" "=r")
6584 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6585 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6586 [(reg FLAGS_REG) (const_int 0)])
6587 (match_operand:SI 2 "general_operand" "g")))))
6588 (clobber (reg:CC FLAGS_REG))]
6589 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6590 "adc{l}\t{%2, %k0|%k0, %2}"
6591 [(set_attr "type" "alu")
6592 (set_attr "use_carry" "1")
6593 (set_attr "pent_pair" "pu")
6594 (set_attr "mode" "SI")])
6596 (define_insn "*subsi3_carry_zext"
6597 [(set (match_operand:DI 0 "register_operand" "=r")
6599 (minus:SI (match_operand:SI 1 "register_operand" "0")
6600 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6601 [(reg FLAGS_REG) (const_int 0)])
6602 (match_operand:SI 2 "general_operand" "g")))))
6603 (clobber (reg:CC FLAGS_REG))]
6604 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6605 "sbb{l}\t{%2, %k0|%k0, %2}"
6606 [(set_attr "type" "alu")
6607 (set_attr "pent_pair" "pu")
6608 (set_attr "mode" "SI")])
6610 ;; Overflow setting add and subtract instructions
6612 (define_insn "*add<mode>3_cconly_overflow"
6613 [(set (reg:CCC FLAGS_REG)
6616 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6617 (match_operand:SWI 2 "<general_operand>" "<g>"))
6619 (clobber (match_scratch:SWI 0 "=<r>"))]
6620 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6621 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6622 [(set_attr "type" "alu")
6623 (set_attr "mode" "<MODE>")])
6625 (define_insn "*sub<mode>3_cconly_overflow"
6626 [(set (reg:CCC FLAGS_REG)
6629 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6630 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6633 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6634 [(set_attr "type" "icmp")
6635 (set_attr "mode" "<MODE>")])
6637 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6638 [(set (reg:CCC FLAGS_REG)
6641 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6642 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6644 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6645 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6646 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6647 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "mode" "<MODE>")])
6651 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6652 [(set (reg:CCC FLAGS_REG)
6655 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6656 (match_operand:SI 2 "general_operand" "g"))
6658 (set (match_operand:DI 0 "register_operand" "=r")
6659 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6660 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6661 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6662 [(set_attr "type" "alu")
6663 (set_attr "mode" "SI")])
6665 ;; The patterns that match these are at the end of this file.
6667 (define_expand "<plusminus_insn>xf3"
6668 [(set (match_operand:XF 0 "register_operand" "")
6670 (match_operand:XF 1 "register_operand" "")
6671 (match_operand:XF 2 "register_operand" "")))]
6674 (define_expand "<plusminus_insn><mode>3"
6675 [(set (match_operand:MODEF 0 "register_operand" "")
6677 (match_operand:MODEF 1 "register_operand" "")
6678 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6679 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6680 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6682 ;; Multiply instructions
6684 (define_expand "mul<mode>3"
6685 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6687 (match_operand:SWIM248 1 "register_operand" "")
6688 (match_operand:SWIM248 2 "<general_operand>" "")))
6689 (clobber (reg:CC FLAGS_REG))])])
6691 (define_expand "mulqi3"
6692 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6694 (match_operand:QI 1 "register_operand" "")
6695 (match_operand:QI 2 "nonimmediate_operand" "")))
6696 (clobber (reg:CC FLAGS_REG))])]
6697 "TARGET_QIMODE_MATH")
6700 ;; IMUL reg32/64, reg32/64, imm8 Direct
6701 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6702 ;; IMUL reg32/64, reg32/64, imm32 Direct
6703 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6704 ;; IMUL reg32/64, reg32/64 Direct
6705 ;; IMUL reg32/64, mem32/64 Direct
6707 ;; On BDVER1, all above IMULs use DirectPath
6709 (define_insn "*mul<mode>3_1"
6710 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6712 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6713 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6714 (clobber (reg:CC FLAGS_REG))]
6715 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6717 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6718 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6719 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6720 [(set_attr "type" "imul")
6721 (set_attr "prefix_0f" "0,0,1")
6722 (set (attr "athlon_decode")
6723 (cond [(eq_attr "cpu" "athlon")
6724 (const_string "vector")
6725 (eq_attr "alternative" "1")
6726 (const_string "vector")
6727 (and (eq_attr "alternative" "2")
6728 (match_operand 1 "memory_operand" ""))
6729 (const_string "vector")]
6730 (const_string "direct")))
6731 (set (attr "amdfam10_decode")
6732 (cond [(and (eq_attr "alternative" "0,1")
6733 (match_operand 1 "memory_operand" ""))
6734 (const_string "vector")]
6735 (const_string "direct")))
6736 (set_attr "bdver1_decode" "direct")
6737 (set_attr "mode" "<MODE>")])
6739 (define_insn "*mulsi3_1_zext"
6740 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6742 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6743 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6744 (clobber (reg:CC FLAGS_REG))]
6746 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6748 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6749 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6750 imul{l}\t{%2, %k0|%k0, %2}"
6751 [(set_attr "type" "imul")
6752 (set_attr "prefix_0f" "0,0,1")
6753 (set (attr "athlon_decode")
6754 (cond [(eq_attr "cpu" "athlon")
6755 (const_string "vector")
6756 (eq_attr "alternative" "1")
6757 (const_string "vector")
6758 (and (eq_attr "alternative" "2")
6759 (match_operand 1 "memory_operand" ""))
6760 (const_string "vector")]
6761 (const_string "direct")))
6762 (set (attr "amdfam10_decode")
6763 (cond [(and (eq_attr "alternative" "0,1")
6764 (match_operand 1 "memory_operand" ""))
6765 (const_string "vector")]
6766 (const_string "direct")))
6767 (set_attr "bdver1_decode" "direct")
6768 (set_attr "mode" "SI")])
6771 ;; IMUL reg16, reg16, imm8 VectorPath
6772 ;; IMUL reg16, mem16, imm8 VectorPath
6773 ;; IMUL reg16, reg16, imm16 VectorPath
6774 ;; IMUL reg16, mem16, imm16 VectorPath
6775 ;; IMUL reg16, reg16 Direct
6776 ;; IMUL reg16, mem16 Direct
6778 ;; On BDVER1, all HI MULs use DoublePath
6780 (define_insn "*mulhi3_1"
6781 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6782 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6783 (match_operand:HI 2 "general_operand" "K,n,mr")))
6784 (clobber (reg:CC FLAGS_REG))]
6786 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6788 imul{w}\t{%2, %1, %0|%0, %1, %2}
6789 imul{w}\t{%2, %1, %0|%0, %1, %2}
6790 imul{w}\t{%2, %0|%0, %2}"
6791 [(set_attr "type" "imul")
6792 (set_attr "prefix_0f" "0,0,1")
6793 (set (attr "athlon_decode")
6794 (cond [(eq_attr "cpu" "athlon")
6795 (const_string "vector")
6796 (eq_attr "alternative" "1,2")
6797 (const_string "vector")]
6798 (const_string "direct")))
6799 (set (attr "amdfam10_decode")
6800 (cond [(eq_attr "alternative" "0,1")
6801 (const_string "vector")]
6802 (const_string "direct")))
6803 (set_attr "bdver1_decode" "double")
6804 (set_attr "mode" "HI")])
6806 ;;On AMDFAM10 and BDVER1
6810 (define_insn "*mulqi3_1"
6811 [(set (match_operand:QI 0 "register_operand" "=a")
6812 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6813 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6814 (clobber (reg:CC FLAGS_REG))]
6816 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6818 [(set_attr "type" "imul")
6819 (set_attr "length_immediate" "0")
6820 (set (attr "athlon_decode")
6821 (if_then_else (eq_attr "cpu" "athlon")
6822 (const_string "vector")
6823 (const_string "direct")))
6824 (set_attr "amdfam10_decode" "direct")
6825 (set_attr "bdver1_decode" "direct")
6826 (set_attr "mode" "QI")])
6828 (define_expand "<u>mul<mode><dwi>3"
6829 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6832 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6834 (match_operand:DWIH 2 "register_operand" ""))))
6835 (clobber (reg:CC FLAGS_REG))])])
6837 (define_expand "<u>mulqihi3"
6838 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6841 (match_operand:QI 1 "nonimmediate_operand" ""))
6843 (match_operand:QI 2 "register_operand" ""))))
6844 (clobber (reg:CC FLAGS_REG))])]
6845 "TARGET_QIMODE_MATH")
6847 (define_insn "*<u>mul<mode><dwi>3_1"
6848 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6851 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6853 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6854 (clobber (reg:CC FLAGS_REG))]
6855 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 "<sgnprefix>mul{<imodesuffix>}\t%2"
6857 [(set_attr "type" "imul")
6858 (set_attr "length_immediate" "0")
6859 (set (attr "athlon_decode")
6860 (if_then_else (eq_attr "cpu" "athlon")
6861 (const_string "vector")
6862 (const_string "double")))
6863 (set_attr "amdfam10_decode" "double")
6864 (set_attr "bdver1_decode" "direct")
6865 (set_attr "mode" "<MODE>")])
6867 (define_insn "*<u>mulqihi3_1"
6868 [(set (match_operand:HI 0 "register_operand" "=a")
6871 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6873 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6874 (clobber (reg:CC FLAGS_REG))]
6876 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6877 "<sgnprefix>mul{b}\t%2"
6878 [(set_attr "type" "imul")
6879 (set_attr "length_immediate" "0")
6880 (set (attr "athlon_decode")
6881 (if_then_else (eq_attr "cpu" "athlon")
6882 (const_string "vector")
6883 (const_string "direct")))
6884 (set_attr "amdfam10_decode" "direct")
6885 (set_attr "bdver1_decode" "direct")
6886 (set_attr "mode" "QI")])
6888 (define_expand "<s>mul<mode>3_highpart"
6889 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6894 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6896 (match_operand:SWI48 2 "register_operand" "")))
6898 (clobber (match_scratch:SWI48 3 ""))
6899 (clobber (reg:CC FLAGS_REG))])]
6901 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6903 (define_insn "*<s>muldi3_highpart_1"
6904 [(set (match_operand:DI 0 "register_operand" "=d")
6909 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6911 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6913 (clobber (match_scratch:DI 3 "=1"))
6914 (clobber (reg:CC FLAGS_REG))]
6916 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917 "<sgnprefix>mul{q}\t%2"
6918 [(set_attr "type" "imul")
6919 (set_attr "length_immediate" "0")
6920 (set (attr "athlon_decode")
6921 (if_then_else (eq_attr "cpu" "athlon")
6922 (const_string "vector")
6923 (const_string "double")))
6924 (set_attr "amdfam10_decode" "double")
6925 (set_attr "bdver1_decode" "direct")
6926 (set_attr "mode" "DI")])
6928 (define_insn "*<s>mulsi3_highpart_1"
6929 [(set (match_operand:SI 0 "register_operand" "=d")
6934 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6936 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6938 (clobber (match_scratch:SI 3 "=1"))
6939 (clobber (reg:CC FLAGS_REG))]
6940 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6941 "<sgnprefix>mul{l}\t%2"
6942 [(set_attr "type" "imul")
6943 (set_attr "length_immediate" "0")
6944 (set (attr "athlon_decode")
6945 (if_then_else (eq_attr "cpu" "athlon")
6946 (const_string "vector")
6947 (const_string "double")))
6948 (set_attr "amdfam10_decode" "double")
6949 (set_attr "bdver1_decode" "direct")
6950 (set_attr "mode" "SI")])
6952 (define_insn "*<s>mulsi3_highpart_zext"
6953 [(set (match_operand:DI 0 "register_operand" "=d")
6954 (zero_extend:DI (truncate:SI
6956 (mult:DI (any_extend:DI
6957 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6959 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6961 (clobber (match_scratch:SI 3 "=1"))
6962 (clobber (reg:CC FLAGS_REG))]
6964 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6965 "<sgnprefix>mul{l}\t%2"
6966 [(set_attr "type" "imul")
6967 (set_attr "length_immediate" "0")
6968 (set (attr "athlon_decode")
6969 (if_then_else (eq_attr "cpu" "athlon")
6970 (const_string "vector")
6971 (const_string "double")))
6972 (set_attr "amdfam10_decode" "double")
6973 (set_attr "bdver1_decode" "direct")
6974 (set_attr "mode" "SI")])
6976 ;; The patterns that match these are at the end of this file.
6978 (define_expand "mulxf3"
6979 [(set (match_operand:XF 0 "register_operand" "")
6980 (mult:XF (match_operand:XF 1 "register_operand" "")
6981 (match_operand:XF 2 "register_operand" "")))]
6984 (define_expand "mul<mode>3"
6985 [(set (match_operand:MODEF 0 "register_operand" "")
6986 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6987 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6988 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6989 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6991 ;; Divide instructions
6993 ;; The patterns that match these are at the end of this file.
6995 (define_expand "divxf3"
6996 [(set (match_operand:XF 0 "register_operand" "")
6997 (div:XF (match_operand:XF 1 "register_operand" "")
6998 (match_operand:XF 2 "register_operand" "")))]
7001 (define_expand "divdf3"
7002 [(set (match_operand:DF 0 "register_operand" "")
7003 (div:DF (match_operand:DF 1 "register_operand" "")
7004 (match_operand:DF 2 "nonimmediate_operand" "")))]
7005 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7006 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7008 (define_expand "divsf3"
7009 [(set (match_operand:SF 0 "register_operand" "")
7010 (div:SF (match_operand:SF 1 "register_operand" "")
7011 (match_operand:SF 2 "nonimmediate_operand" "")))]
7012 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7015 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7016 && flag_finite_math_only && !flag_trapping_math
7017 && flag_unsafe_math_optimizations)
7019 ix86_emit_swdivsf (operands[0], operands[1],
7020 operands[2], SFmode);
7025 ;; Divmod instructions.
7027 (define_expand "divmod<mode>4"
7028 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7030 (match_operand:SWIM248 1 "register_operand" "")
7031 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7032 (set (match_operand:SWIM248 3 "register_operand" "")
7033 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7034 (clobber (reg:CC FLAGS_REG))])])
7036 ;; Split with 8bit unsigned divide:
7037 ;; if (dividend an divisor are in [0-255])
7038 ;; use 8bit unsigned integer divide
7040 ;; use original integer divide
7042 [(set (match_operand:SWI48 0 "register_operand" "")
7043 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7044 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7045 (set (match_operand:SWI48 1 "register_operand" "")
7046 (mod:SWI48 (match_dup 2) (match_dup 3)))
7047 (clobber (reg:CC FLAGS_REG))]
7048 "TARGET_USE_8BIT_IDIV
7049 && TARGET_QIMODE_MATH
7050 && can_create_pseudo_p ()
7051 && !optimize_insn_for_size_p ()"
7053 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7055 (define_insn_and_split "divmod<mode>4_1"
7056 [(set (match_operand:SWI48 0 "register_operand" "=a")
7057 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7058 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7059 (set (match_operand:SWI48 1 "register_operand" "=&d")
7060 (mod:SWI48 (match_dup 2) (match_dup 3)))
7061 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7062 (clobber (reg:CC FLAGS_REG))]
7066 [(parallel [(set (match_dup 1)
7067 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7068 (clobber (reg:CC FLAGS_REG))])
7069 (parallel [(set (match_dup 0)
7070 (div:SWI48 (match_dup 2) (match_dup 3)))
7072 (mod:SWI48 (match_dup 2) (match_dup 3)))
7074 (clobber (reg:CC FLAGS_REG))])]
7076 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7078 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7079 operands[4] = operands[2];
7082 /* Avoid use of cltd in favor of a mov+shift. */
7083 emit_move_insn (operands[1], operands[2]);
7084 operands[4] = operands[1];
7087 [(set_attr "type" "multi")
7088 (set_attr "mode" "<MODE>")])
7090 (define_insn_and_split "*divmod<mode>4"
7091 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7092 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7093 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7094 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7095 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7096 (clobber (reg:CC FLAGS_REG))]
7100 [(parallel [(set (match_dup 1)
7101 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7102 (clobber (reg:CC FLAGS_REG))])
7103 (parallel [(set (match_dup 0)
7104 (div:SWIM248 (match_dup 2) (match_dup 3)))
7106 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7108 (clobber (reg:CC FLAGS_REG))])]
7110 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7112 if (<MODE>mode != HImode
7113 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7114 operands[4] = operands[2];
7117 /* Avoid use of cltd in favor of a mov+shift. */
7118 emit_move_insn (operands[1], operands[2]);
7119 operands[4] = operands[1];
7122 [(set_attr "type" "multi")
7123 (set_attr "mode" "<MODE>")])
7125 (define_insn "*divmod<mode>4_noext"
7126 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7127 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7128 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7129 (set (match_operand:SWIM248 1 "register_operand" "=d")
7130 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7131 (use (match_operand:SWIM248 4 "register_operand" "1"))
7132 (clobber (reg:CC FLAGS_REG))]
7134 "idiv{<imodesuffix>}\t%3"
7135 [(set_attr "type" "idiv")
7136 (set_attr "mode" "<MODE>")])
7138 (define_expand "divmodqi4"
7139 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7141 (match_operand:QI 1 "register_operand" "")
7142 (match_operand:QI 2 "nonimmediate_operand" "")))
7143 (set (match_operand:QI 3 "register_operand" "")
7144 (mod:QI (match_dup 1) (match_dup 2)))
7145 (clobber (reg:CC FLAGS_REG))])]
7146 "TARGET_QIMODE_MATH"
7151 tmp0 = gen_reg_rtx (HImode);
7152 tmp1 = gen_reg_rtx (HImode);
7154 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7156 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7157 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7159 /* Extract remainder from AH. */
7160 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7161 insn = emit_move_insn (operands[3], tmp1);
7163 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7164 set_unique_reg_note (insn, REG_EQUAL, mod);
7166 /* Extract quotient from AL. */
7167 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7169 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7170 set_unique_reg_note (insn, REG_EQUAL, div);
7175 ;; Divide AX by r/m8, with result stored in
7178 ;; Change div/mod to HImode and extend the second argument to HImode
7179 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7180 ;; combine may fail.
7181 (define_insn "divmodhiqi3"
7182 [(set (match_operand:HI 0 "register_operand" "=a")
7187 (mod:HI (match_operand:HI 1 "register_operand" "0")
7189 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7193 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7194 (clobber (reg:CC FLAGS_REG))]
7195 "TARGET_QIMODE_MATH"
7197 [(set_attr "type" "idiv")
7198 (set_attr "mode" "QI")])
7200 (define_expand "udivmod<mode>4"
7201 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7203 (match_operand:SWIM248 1 "register_operand" "")
7204 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7205 (set (match_operand:SWIM248 3 "register_operand" "")
7206 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7207 (clobber (reg:CC FLAGS_REG))])])
7209 ;; Split with 8bit unsigned divide:
7210 ;; if (dividend an divisor are in [0-255])
7211 ;; use 8bit unsigned integer divide
7213 ;; use original integer divide
7215 [(set (match_operand:SWI48 0 "register_operand" "")
7216 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7217 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7218 (set (match_operand:SWI48 1 "register_operand" "")
7219 (umod:SWI48 (match_dup 2) (match_dup 3)))
7220 (clobber (reg:CC FLAGS_REG))]
7221 "TARGET_USE_8BIT_IDIV
7222 && TARGET_QIMODE_MATH
7223 && can_create_pseudo_p ()
7224 && !optimize_insn_for_size_p ()"
7226 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7228 (define_insn_and_split "udivmod<mode>4_1"
7229 [(set (match_operand:SWI48 0 "register_operand" "=a")
7230 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7231 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7232 (set (match_operand:SWI48 1 "register_operand" "=&d")
7233 (umod:SWI48 (match_dup 2) (match_dup 3)))
7234 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7235 (clobber (reg:CC FLAGS_REG))]
7239 [(set (match_dup 1) (const_int 0))
7240 (parallel [(set (match_dup 0)
7241 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7243 (umod:SWI48 (match_dup 2) (match_dup 3)))
7245 (clobber (reg:CC FLAGS_REG))])]
7247 [(set_attr "type" "multi")
7248 (set_attr "mode" "<MODE>")])
7250 (define_insn_and_split "*udivmod<mode>4"
7251 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7252 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7253 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7254 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7255 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7256 (clobber (reg:CC FLAGS_REG))]
7260 [(set (match_dup 1) (const_int 0))
7261 (parallel [(set (match_dup 0)
7262 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7264 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7266 (clobber (reg:CC FLAGS_REG))])]
7268 [(set_attr "type" "multi")
7269 (set_attr "mode" "<MODE>")])
7271 (define_insn "*udivmod<mode>4_noext"
7272 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7273 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7274 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7275 (set (match_operand:SWIM248 1 "register_operand" "=d")
7276 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7277 (use (match_operand:SWIM248 4 "register_operand" "1"))
7278 (clobber (reg:CC FLAGS_REG))]
7280 "div{<imodesuffix>}\t%3"
7281 [(set_attr "type" "idiv")
7282 (set_attr "mode" "<MODE>")])
7284 (define_expand "udivmodqi4"
7285 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7287 (match_operand:QI 1 "register_operand" "")
7288 (match_operand:QI 2 "nonimmediate_operand" "")))
7289 (set (match_operand:QI 3 "register_operand" "")
7290 (umod:QI (match_dup 1) (match_dup 2)))
7291 (clobber (reg:CC FLAGS_REG))])]
7292 "TARGET_QIMODE_MATH"
7297 tmp0 = gen_reg_rtx (HImode);
7298 tmp1 = gen_reg_rtx (HImode);
7300 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7302 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7303 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7305 /* Extract remainder from AH. */
7306 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7307 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7308 insn = emit_move_insn (operands[3], tmp1);
7310 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7311 set_unique_reg_note (insn, REG_EQUAL, mod);
7313 /* Extract quotient from AL. */
7314 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7316 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7317 set_unique_reg_note (insn, REG_EQUAL, div);
7322 (define_insn "udivmodhiqi3"
7323 [(set (match_operand:HI 0 "register_operand" "=a")
7328 (mod:HI (match_operand:HI 1 "register_operand" "0")
7330 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7334 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7335 (clobber (reg:CC FLAGS_REG))]
7336 "TARGET_QIMODE_MATH"
7338 [(set_attr "type" "idiv")
7339 (set_attr "mode" "QI")])
7341 ;; We cannot use div/idiv for double division, because it causes
7342 ;; "division by zero" on the overflow and that's not what we expect
7343 ;; from truncate. Because true (non truncating) double division is
7344 ;; never generated, we can't create this insn anyway.
7347 ; [(set (match_operand:SI 0 "register_operand" "=a")
7349 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7351 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7352 ; (set (match_operand:SI 3 "register_operand" "=d")
7354 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7355 ; (clobber (reg:CC FLAGS_REG))]
7357 ; "div{l}\t{%2, %0|%0, %2}"
7358 ; [(set_attr "type" "idiv")])
7360 ;;- Logical AND instructions
7362 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7363 ;; Note that this excludes ah.
7365 (define_expand "testsi_ccno_1"
7366 [(set (reg:CCNO FLAGS_REG)
7368 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7369 (match_operand:SI 1 "nonmemory_operand" ""))
7372 (define_expand "testqi_ccz_1"
7373 [(set (reg:CCZ FLAGS_REG)
7374 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7375 (match_operand:QI 1 "nonmemory_operand" ""))
7378 (define_expand "testdi_ccno_1"
7379 [(set (reg:CCNO FLAGS_REG)
7381 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7382 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7384 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7386 (define_insn "*testdi_1"
7387 [(set (reg FLAGS_REG)
7390 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7391 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7393 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7394 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7396 test{l}\t{%k1, %k0|%k0, %k1}
7397 test{l}\t{%k1, %k0|%k0, %k1}
7398 test{q}\t{%1, %0|%0, %1}
7399 test{q}\t{%1, %0|%0, %1}
7400 test{q}\t{%1, %0|%0, %1}"
7401 [(set_attr "type" "test")
7402 (set_attr "modrm" "0,1,0,1,1")
7403 (set_attr "mode" "SI,SI,DI,DI,DI")])
7405 (define_insn "*testqi_1_maybe_si"
7406 [(set (reg FLAGS_REG)
7409 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7410 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7412 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7413 && ix86_match_ccmode (insn,
7414 CONST_INT_P (operands[1])
7415 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7417 if (which_alternative == 3)
7419 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7420 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7421 return "test{l}\t{%1, %k0|%k0, %1}";
7423 return "test{b}\t{%1, %0|%0, %1}";
7425 [(set_attr "type" "test")
7426 (set_attr "modrm" "0,1,1,1")
7427 (set_attr "mode" "QI,QI,QI,SI")
7428 (set_attr "pent_pair" "uv,np,uv,np")])
7430 (define_insn "*test<mode>_1"
7431 [(set (reg FLAGS_REG)
7434 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7435 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7437 "ix86_match_ccmode (insn, CCNOmode)
7438 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7439 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7440 [(set_attr "type" "test")
7441 (set_attr "modrm" "0,1,1")
7442 (set_attr "mode" "<MODE>")
7443 (set_attr "pent_pair" "uv,np,uv")])
7445 (define_expand "testqi_ext_ccno_0"
7446 [(set (reg:CCNO FLAGS_REG)
7450 (match_operand 0 "ext_register_operand" "")
7453 (match_operand 1 "const_int_operand" ""))
7456 (define_insn "*testqi_ext_0"
7457 [(set (reg FLAGS_REG)
7461 (match_operand 0 "ext_register_operand" "Q")
7464 (match_operand 1 "const_int_operand" "n"))
7466 "ix86_match_ccmode (insn, CCNOmode)"
7467 "test{b}\t{%1, %h0|%h0, %1}"
7468 [(set_attr "type" "test")
7469 (set_attr "mode" "QI")
7470 (set_attr "length_immediate" "1")
7471 (set_attr "modrm" "1")
7472 (set_attr "pent_pair" "np")])
7474 (define_insn "*testqi_ext_1_rex64"
7475 [(set (reg FLAGS_REG)
7479 (match_operand 0 "ext_register_operand" "Q")
7483 (match_operand:QI 1 "register_operand" "Q")))
7485 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7486 "test{b}\t{%1, %h0|%h0, %1}"
7487 [(set_attr "type" "test")
7488 (set_attr "mode" "QI")])
7490 (define_insn "*testqi_ext_1"
7491 [(set (reg FLAGS_REG)
7495 (match_operand 0 "ext_register_operand" "Q")
7499 (match_operand:QI 1 "general_operand" "Qm")))
7501 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7502 "test{b}\t{%1, %h0|%h0, %1}"
7503 [(set_attr "type" "test")
7504 (set_attr "mode" "QI")])
7506 (define_insn "*testqi_ext_2"
7507 [(set (reg FLAGS_REG)
7511 (match_operand 0 "ext_register_operand" "Q")
7515 (match_operand 1 "ext_register_operand" "Q")
7519 "ix86_match_ccmode (insn, CCNOmode)"
7520 "test{b}\t{%h1, %h0|%h0, %h1}"
7521 [(set_attr "type" "test")
7522 (set_attr "mode" "QI")])
7524 (define_insn "*testqi_ext_3_rex64"
7525 [(set (reg FLAGS_REG)
7526 (compare (zero_extract:DI
7527 (match_operand 0 "nonimmediate_operand" "rm")
7528 (match_operand:DI 1 "const_int_operand" "")
7529 (match_operand:DI 2 "const_int_operand" ""))
7532 && ix86_match_ccmode (insn, CCNOmode)
7533 && INTVAL (operands[1]) > 0
7534 && INTVAL (operands[2]) >= 0
7535 /* Ensure that resulting mask is zero or sign extended operand. */
7536 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7537 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7538 && INTVAL (operands[1]) > 32))
7539 && (GET_MODE (operands[0]) == SImode
7540 || GET_MODE (operands[0]) == DImode
7541 || GET_MODE (operands[0]) == HImode
7542 || GET_MODE (operands[0]) == QImode)"
7545 ;; Combine likes to form bit extractions for some tests. Humor it.
7546 (define_insn "*testqi_ext_3"
7547 [(set (reg FLAGS_REG)
7548 (compare (zero_extract:SI
7549 (match_operand 0 "nonimmediate_operand" "rm")
7550 (match_operand:SI 1 "const_int_operand" "")
7551 (match_operand:SI 2 "const_int_operand" ""))
7553 "ix86_match_ccmode (insn, CCNOmode)
7554 && INTVAL (operands[1]) > 0
7555 && INTVAL (operands[2]) >= 0
7556 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7557 && (GET_MODE (operands[0]) == SImode
7558 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7559 || GET_MODE (operands[0]) == HImode
7560 || GET_MODE (operands[0]) == QImode)"
7564 [(set (match_operand 0 "flags_reg_operand" "")
7565 (match_operator 1 "compare_operator"
7567 (match_operand 2 "nonimmediate_operand" "")
7568 (match_operand 3 "const_int_operand" "")
7569 (match_operand 4 "const_int_operand" ""))
7571 "ix86_match_ccmode (insn, CCNOmode)"
7572 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7574 rtx val = operands[2];
7575 HOST_WIDE_INT len = INTVAL (operands[3]);
7576 HOST_WIDE_INT pos = INTVAL (operands[4]);
7578 enum machine_mode mode, submode;
7580 mode = GET_MODE (val);
7583 /* ??? Combine likes to put non-volatile mem extractions in QImode
7584 no matter the size of the test. So find a mode that works. */
7585 if (! MEM_VOLATILE_P (val))
7587 mode = smallest_mode_for_size (pos + len, MODE_INT);
7588 val = adjust_address (val, mode, 0);
7591 else if (GET_CODE (val) == SUBREG
7592 && (submode = GET_MODE (SUBREG_REG (val)),
7593 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7594 && pos + len <= GET_MODE_BITSIZE (submode)
7595 && GET_MODE_CLASS (submode) == MODE_INT)
7597 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7599 val = SUBREG_REG (val);
7601 else if (mode == HImode && pos + len <= 8)
7603 /* Small HImode tests can be converted to QImode. */
7605 val = gen_lowpart (QImode, val);
7608 if (len == HOST_BITS_PER_WIDE_INT)
7611 mask = ((HOST_WIDE_INT)1 << len) - 1;
7614 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7617 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7618 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7619 ;; this is relatively important trick.
7620 ;; Do the conversion only post-reload to avoid limiting of the register class
7623 [(set (match_operand 0 "flags_reg_operand" "")
7624 (match_operator 1 "compare_operator"
7625 [(and (match_operand 2 "register_operand" "")
7626 (match_operand 3 "const_int_operand" ""))
7629 && QI_REG_P (operands[2])
7630 && GET_MODE (operands[2]) != QImode
7631 && ((ix86_match_ccmode (insn, CCZmode)
7632 && !(INTVAL (operands[3]) & ~(255 << 8)))
7633 || (ix86_match_ccmode (insn, CCNOmode)
7634 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7637 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7640 "operands[2] = gen_lowpart (SImode, operands[2]);
7641 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7644 [(set (match_operand 0 "flags_reg_operand" "")
7645 (match_operator 1 "compare_operator"
7646 [(and (match_operand 2 "nonimmediate_operand" "")
7647 (match_operand 3 "const_int_operand" ""))
7650 && GET_MODE (operands[2]) != QImode
7651 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7652 && ((ix86_match_ccmode (insn, CCZmode)
7653 && !(INTVAL (operands[3]) & ~255))
7654 || (ix86_match_ccmode (insn, CCNOmode)
7655 && !(INTVAL (operands[3]) & ~127)))"
7657 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7659 "operands[2] = gen_lowpart (QImode, operands[2]);
7660 operands[3] = gen_lowpart (QImode, operands[3]);")
7662 ;; %%% This used to optimize known byte-wide and operations to memory,
7663 ;; and sometimes to QImode registers. If this is considered useful,
7664 ;; it should be done with splitters.
7666 (define_expand "and<mode>3"
7667 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7668 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7669 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7671 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7673 (define_insn "*anddi_1"
7674 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7676 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7677 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7678 (clobber (reg:CC FLAGS_REG))]
7679 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7681 switch (get_attr_type (insn))
7685 enum machine_mode mode;
7687 gcc_assert (CONST_INT_P (operands[2]));
7688 if (INTVAL (operands[2]) == 0xff)
7692 gcc_assert (INTVAL (operands[2]) == 0xffff);
7696 operands[1] = gen_lowpart (mode, operands[1]);
7698 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7700 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7704 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7705 if (get_attr_mode (insn) == MODE_SI)
7706 return "and{l}\t{%k2, %k0|%k0, %k2}";
7708 return "and{q}\t{%2, %0|%0, %2}";
7711 [(set_attr "type" "alu,alu,alu,imovx")
7712 (set_attr "length_immediate" "*,*,*,0")
7713 (set (attr "prefix_rex")
7715 (and (eq_attr "type" "imovx")
7716 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7717 (match_operand 1 "ext_QIreg_operand" "")))
7719 (const_string "*")))
7720 (set_attr "mode" "SI,DI,DI,SI")])
7722 (define_insn "*andsi_1"
7723 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7724 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7725 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7726 (clobber (reg:CC FLAGS_REG))]
7727 "ix86_binary_operator_ok (AND, SImode, operands)"
7729 switch (get_attr_type (insn))
7733 enum machine_mode mode;
7735 gcc_assert (CONST_INT_P (operands[2]));
7736 if (INTVAL (operands[2]) == 0xff)
7740 gcc_assert (INTVAL (operands[2]) == 0xffff);
7744 operands[1] = gen_lowpart (mode, operands[1]);
7746 return "movz{bl|x}\t{%1, %0|%0, %1}";
7748 return "movz{wl|x}\t{%1, %0|%0, %1}";
7752 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7753 return "and{l}\t{%2, %0|%0, %2}";
7756 [(set_attr "type" "alu,alu,imovx")
7757 (set (attr "prefix_rex")
7759 (and (eq_attr "type" "imovx")
7760 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7761 (match_operand 1 "ext_QIreg_operand" "")))
7763 (const_string "*")))
7764 (set_attr "length_immediate" "*,*,0")
7765 (set_attr "mode" "SI")])
7767 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7768 (define_insn "*andsi_1_zext"
7769 [(set (match_operand:DI 0 "register_operand" "=r")
7771 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7772 (match_operand:SI 2 "general_operand" "g"))))
7773 (clobber (reg:CC FLAGS_REG))]
7774 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7775 "and{l}\t{%2, %k0|%k0, %2}"
7776 [(set_attr "type" "alu")
7777 (set_attr "mode" "SI")])
7779 (define_insn "*andhi_1"
7780 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7781 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7782 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7783 (clobber (reg:CC FLAGS_REG))]
7784 "ix86_binary_operator_ok (AND, HImode, operands)"
7786 switch (get_attr_type (insn))
7789 gcc_assert (CONST_INT_P (operands[2]));
7790 gcc_assert (INTVAL (operands[2]) == 0xff);
7791 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7794 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7796 return "and{w}\t{%2, %0|%0, %2}";
7799 [(set_attr "type" "alu,alu,imovx")
7800 (set_attr "length_immediate" "*,*,0")
7801 (set (attr "prefix_rex")
7803 (and (eq_attr "type" "imovx")
7804 (match_operand 1 "ext_QIreg_operand" ""))
7806 (const_string "*")))
7807 (set_attr "mode" "HI,HI,SI")])
7809 ;; %%% Potential partial reg stall on alternative 2. What to do?
7810 (define_insn "*andqi_1"
7811 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7812 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7813 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7814 (clobber (reg:CC FLAGS_REG))]
7815 "ix86_binary_operator_ok (AND, QImode, operands)"
7817 and{b}\t{%2, %0|%0, %2}
7818 and{b}\t{%2, %0|%0, %2}
7819 and{l}\t{%k2, %k0|%k0, %k2}"
7820 [(set_attr "type" "alu")
7821 (set_attr "mode" "QI,QI,SI")])
7823 (define_insn "*andqi_1_slp"
7824 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7825 (and:QI (match_dup 0)
7826 (match_operand:QI 1 "general_operand" "qn,qmn")))
7827 (clobber (reg:CC FLAGS_REG))]
7828 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7829 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7830 "and{b}\t{%1, %0|%0, %1}"
7831 [(set_attr "type" "alu1")
7832 (set_attr "mode" "QI")])
7835 [(set (match_operand 0 "register_operand" "")
7837 (const_int -65536)))
7838 (clobber (reg:CC FLAGS_REG))]
7839 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7840 || optimize_function_for_size_p (cfun)"
7841 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7842 "operands[1] = gen_lowpart (HImode, operands[0]);")
7845 [(set (match_operand 0 "ext_register_operand" "")
7848 (clobber (reg:CC FLAGS_REG))]
7849 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7850 && reload_completed"
7851 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7852 "operands[1] = gen_lowpart (QImode, operands[0]);")
7855 [(set (match_operand 0 "ext_register_operand" "")
7857 (const_int -65281)))
7858 (clobber (reg:CC FLAGS_REG))]
7859 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7860 && reload_completed"
7861 [(parallel [(set (zero_extract:SI (match_dup 0)
7865 (zero_extract:SI (match_dup 0)
7868 (zero_extract:SI (match_dup 0)
7871 (clobber (reg:CC FLAGS_REG))])]
7872 "operands[0] = gen_lowpart (SImode, operands[0]);")
7874 (define_insn "*anddi_2"
7875 [(set (reg FLAGS_REG)
7878 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7879 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7881 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7882 (and:DI (match_dup 1) (match_dup 2)))]
7883 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7884 && ix86_binary_operator_ok (AND, DImode, operands)"
7886 and{l}\t{%k2, %k0|%k0, %k2}
7887 and{q}\t{%2, %0|%0, %2}
7888 and{q}\t{%2, %0|%0, %2}"
7889 [(set_attr "type" "alu")
7890 (set_attr "mode" "SI,DI,DI")])
7892 (define_insn "*andqi_2_maybe_si"
7893 [(set (reg FLAGS_REG)
7895 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7896 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7898 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7899 (and:QI (match_dup 1) (match_dup 2)))]
7900 "ix86_binary_operator_ok (AND, QImode, operands)
7901 && ix86_match_ccmode (insn,
7902 CONST_INT_P (operands[2])
7903 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7905 if (which_alternative == 2)
7907 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7908 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7909 return "and{l}\t{%2, %k0|%k0, %2}";
7911 return "and{b}\t{%2, %0|%0, %2}";
7913 [(set_attr "type" "alu")
7914 (set_attr "mode" "QI,QI,SI")])
7916 (define_insn "*and<mode>_2"
7917 [(set (reg FLAGS_REG)
7918 (compare (and:SWI124
7919 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7920 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7922 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7923 (and:SWI124 (match_dup 1) (match_dup 2)))]
7924 "ix86_match_ccmode (insn, CCNOmode)
7925 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7926 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7927 [(set_attr "type" "alu")
7928 (set_attr "mode" "<MODE>")])
7930 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7931 (define_insn "*andsi_2_zext"
7932 [(set (reg FLAGS_REG)
7934 (match_operand:SI 1 "nonimmediate_operand" "%0")
7935 (match_operand:SI 2 "general_operand" "g"))
7937 (set (match_operand:DI 0 "register_operand" "=r")
7938 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7939 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7940 && ix86_binary_operator_ok (AND, SImode, operands)"
7941 "and{l}\t{%2, %k0|%k0, %2}"
7942 [(set_attr "type" "alu")
7943 (set_attr "mode" "SI")])
7945 (define_insn "*andqi_2_slp"
7946 [(set (reg FLAGS_REG)
7948 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7949 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7951 (set (strict_low_part (match_dup 0))
7952 (and:QI (match_dup 0) (match_dup 1)))]
7953 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7954 && ix86_match_ccmode (insn, CCNOmode)
7955 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7956 "and{b}\t{%1, %0|%0, %1}"
7957 [(set_attr "type" "alu1")
7958 (set_attr "mode" "QI")])
7960 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7961 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7962 ;; for a QImode operand, which of course failed.
7963 (define_insn "andqi_ext_0"
7964 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7969 (match_operand 1 "ext_register_operand" "0")
7972 (match_operand 2 "const_int_operand" "n")))
7973 (clobber (reg:CC FLAGS_REG))]
7975 "and{b}\t{%2, %h0|%h0, %2}"
7976 [(set_attr "type" "alu")
7977 (set_attr "length_immediate" "1")
7978 (set_attr "modrm" "1")
7979 (set_attr "mode" "QI")])
7981 ;; Generated by peephole translating test to and. This shows up
7982 ;; often in fp comparisons.
7983 (define_insn "*andqi_ext_0_cc"
7984 [(set (reg FLAGS_REG)
7988 (match_operand 1 "ext_register_operand" "0")
7991 (match_operand 2 "const_int_operand" "n"))
7993 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8002 "ix86_match_ccmode (insn, CCNOmode)"
8003 "and{b}\t{%2, %h0|%h0, %2}"
8004 [(set_attr "type" "alu")
8005 (set_attr "length_immediate" "1")
8006 (set_attr "modrm" "1")
8007 (set_attr "mode" "QI")])
8009 (define_insn "*andqi_ext_1_rex64"
8010 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8015 (match_operand 1 "ext_register_operand" "0")
8019 (match_operand 2 "ext_register_operand" "Q"))))
8020 (clobber (reg:CC FLAGS_REG))]
8022 "and{b}\t{%2, %h0|%h0, %2}"
8023 [(set_attr "type" "alu")
8024 (set_attr "length_immediate" "0")
8025 (set_attr "mode" "QI")])
8027 (define_insn "*andqi_ext_1"
8028 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8033 (match_operand 1 "ext_register_operand" "0")
8037 (match_operand:QI 2 "general_operand" "Qm"))))
8038 (clobber (reg:CC FLAGS_REG))]
8040 "and{b}\t{%2, %h0|%h0, %2}"
8041 [(set_attr "type" "alu")
8042 (set_attr "length_immediate" "0")
8043 (set_attr "mode" "QI")])
8045 (define_insn "*andqi_ext_2"
8046 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8051 (match_operand 1 "ext_register_operand" "%0")
8055 (match_operand 2 "ext_register_operand" "Q")
8058 (clobber (reg:CC FLAGS_REG))]
8060 "and{b}\t{%h2, %h0|%h0, %h2}"
8061 [(set_attr "type" "alu")
8062 (set_attr "length_immediate" "0")
8063 (set_attr "mode" "QI")])
8065 ;; Convert wide AND instructions with immediate operand to shorter QImode
8066 ;; equivalents when possible.
8067 ;; Don't do the splitting with memory operands, since it introduces risk
8068 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8069 ;; for size, but that can (should?) be handled by generic code instead.
8071 [(set (match_operand 0 "register_operand" "")
8072 (and (match_operand 1 "register_operand" "")
8073 (match_operand 2 "const_int_operand" "")))
8074 (clobber (reg:CC FLAGS_REG))]
8076 && QI_REG_P (operands[0])
8077 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8078 && !(~INTVAL (operands[2]) & ~(255 << 8))
8079 && GET_MODE (operands[0]) != QImode"
8080 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8081 (and:SI (zero_extract:SI (match_dup 1)
8082 (const_int 8) (const_int 8))
8084 (clobber (reg:CC FLAGS_REG))])]
8085 "operands[0] = gen_lowpart (SImode, operands[0]);
8086 operands[1] = gen_lowpart (SImode, operands[1]);
8087 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8089 ;; Since AND can be encoded with sign extended immediate, this is only
8090 ;; profitable when 7th bit is not set.
8092 [(set (match_operand 0 "register_operand" "")
8093 (and (match_operand 1 "general_operand" "")
8094 (match_operand 2 "const_int_operand" "")))
8095 (clobber (reg:CC FLAGS_REG))]
8097 && ANY_QI_REG_P (operands[0])
8098 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8099 && !(~INTVAL (operands[2]) & ~255)
8100 && !(INTVAL (operands[2]) & 128)
8101 && GET_MODE (operands[0]) != QImode"
8102 [(parallel [(set (strict_low_part (match_dup 0))
8103 (and:QI (match_dup 1)
8105 (clobber (reg:CC FLAGS_REG))])]
8106 "operands[0] = gen_lowpart (QImode, operands[0]);
8107 operands[1] = gen_lowpart (QImode, operands[1]);
8108 operands[2] = gen_lowpart (QImode, operands[2]);")
8110 ;; Logical inclusive and exclusive OR instructions
8112 ;; %%% This used to optimize known byte-wide and operations to memory.
8113 ;; If this is considered useful, it should be done with splitters.
8115 (define_expand "<code><mode>3"
8116 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8117 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8118 (match_operand:SWIM 2 "<general_operand>" "")))]
8120 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8122 (define_insn "*<code><mode>_1"
8123 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8125 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8126 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8127 (clobber (reg:CC FLAGS_REG))]
8128 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8129 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8130 [(set_attr "type" "alu")
8131 (set_attr "mode" "<MODE>")])
8133 ;; %%% Potential partial reg stall on alternative 2. What to do?
8134 (define_insn "*<code>qi_1"
8135 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8136 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8137 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8138 (clobber (reg:CC FLAGS_REG))]
8139 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8141 <logic>{b}\t{%2, %0|%0, %2}
8142 <logic>{b}\t{%2, %0|%0, %2}
8143 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8144 [(set_attr "type" "alu")
8145 (set_attr "mode" "QI,QI,SI")])
8147 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8148 (define_insn "*<code>si_1_zext"
8149 [(set (match_operand:DI 0 "register_operand" "=r")
8151 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8152 (match_operand:SI 2 "general_operand" "g"))))
8153 (clobber (reg:CC FLAGS_REG))]
8154 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8155 "<logic>{l}\t{%2, %k0|%k0, %2}"
8156 [(set_attr "type" "alu")
8157 (set_attr "mode" "SI")])
8159 (define_insn "*<code>si_1_zext_imm"
8160 [(set (match_operand:DI 0 "register_operand" "=r")
8162 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8163 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8164 (clobber (reg:CC FLAGS_REG))]
8165 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8166 "<logic>{l}\t{%2, %k0|%k0, %2}"
8167 [(set_attr "type" "alu")
8168 (set_attr "mode" "SI")])
8170 (define_insn "*<code>qi_1_slp"
8171 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8172 (any_or:QI (match_dup 0)
8173 (match_operand:QI 1 "general_operand" "qmn,qn")))
8174 (clobber (reg:CC FLAGS_REG))]
8175 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8176 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8177 "<logic>{b}\t{%1, %0|%0, %1}"
8178 [(set_attr "type" "alu1")
8179 (set_attr "mode" "QI")])
8181 (define_insn "*<code><mode>_2"
8182 [(set (reg FLAGS_REG)
8183 (compare (any_or:SWI
8184 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8185 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8187 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8188 (any_or:SWI (match_dup 1) (match_dup 2)))]
8189 "ix86_match_ccmode (insn, CCNOmode)
8190 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8191 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8192 [(set_attr "type" "alu")
8193 (set_attr "mode" "<MODE>")])
8195 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8196 ;; ??? Special case for immediate operand is missing - it is tricky.
8197 (define_insn "*<code>si_2_zext"
8198 [(set (reg FLAGS_REG)
8199 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8200 (match_operand:SI 2 "general_operand" "g"))
8202 (set (match_operand:DI 0 "register_operand" "=r")
8203 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8204 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8205 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8206 "<logic>{l}\t{%2, %k0|%k0, %2}"
8207 [(set_attr "type" "alu")
8208 (set_attr "mode" "SI")])
8210 (define_insn "*<code>si_2_zext_imm"
8211 [(set (reg FLAGS_REG)
8213 (match_operand:SI 1 "nonimmediate_operand" "%0")
8214 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8216 (set (match_operand:DI 0 "register_operand" "=r")
8217 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8218 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8219 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8220 "<logic>{l}\t{%2, %k0|%k0, %2}"
8221 [(set_attr "type" "alu")
8222 (set_attr "mode" "SI")])
8224 (define_insn "*<code>qi_2_slp"
8225 [(set (reg FLAGS_REG)
8226 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8227 (match_operand:QI 1 "general_operand" "qmn,qn"))
8229 (set (strict_low_part (match_dup 0))
8230 (any_or:QI (match_dup 0) (match_dup 1)))]
8231 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232 && ix86_match_ccmode (insn, CCNOmode)
8233 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8234 "<logic>{b}\t{%1, %0|%0, %1}"
8235 [(set_attr "type" "alu1")
8236 (set_attr "mode" "QI")])
8238 (define_insn "*<code><mode>_3"
8239 [(set (reg FLAGS_REG)
8240 (compare (any_or:SWI
8241 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8242 (match_operand:SWI 2 "<general_operand>" "<g>"))
8244 (clobber (match_scratch:SWI 0 "=<r>"))]
8245 "ix86_match_ccmode (insn, CCNOmode)
8246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8247 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8248 [(set_attr "type" "alu")
8249 (set_attr "mode" "<MODE>")])
8251 (define_insn "*<code>qi_ext_0"
8252 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8257 (match_operand 1 "ext_register_operand" "0")
8260 (match_operand 2 "const_int_operand" "n")))
8261 (clobber (reg:CC FLAGS_REG))]
8262 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8263 "<logic>{b}\t{%2, %h0|%h0, %2}"
8264 [(set_attr "type" "alu")
8265 (set_attr "length_immediate" "1")
8266 (set_attr "modrm" "1")
8267 (set_attr "mode" "QI")])
8269 (define_insn "*<code>qi_ext_1_rex64"
8270 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8275 (match_operand 1 "ext_register_operand" "0")
8279 (match_operand 2 "ext_register_operand" "Q"))))
8280 (clobber (reg:CC FLAGS_REG))]
8282 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8283 "<logic>{b}\t{%2, %h0|%h0, %2}"
8284 [(set_attr "type" "alu")
8285 (set_attr "length_immediate" "0")
8286 (set_attr "mode" "QI")])
8288 (define_insn "*<code>qi_ext_1"
8289 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8294 (match_operand 1 "ext_register_operand" "0")
8298 (match_operand:QI 2 "general_operand" "Qm"))))
8299 (clobber (reg:CC FLAGS_REG))]
8301 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8302 "<logic>{b}\t{%2, %h0|%h0, %2}"
8303 [(set_attr "type" "alu")
8304 (set_attr "length_immediate" "0")
8305 (set_attr "mode" "QI")])
8307 (define_insn "*<code>qi_ext_2"
8308 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8312 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8315 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8318 (clobber (reg:CC FLAGS_REG))]
8319 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8320 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "length_immediate" "0")
8323 (set_attr "mode" "QI")])
8326 [(set (match_operand 0 "register_operand" "")
8327 (any_or (match_operand 1 "register_operand" "")
8328 (match_operand 2 "const_int_operand" "")))
8329 (clobber (reg:CC FLAGS_REG))]
8331 && QI_REG_P (operands[0])
8332 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8333 && !(INTVAL (operands[2]) & ~(255 << 8))
8334 && GET_MODE (operands[0]) != QImode"
8335 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8336 (any_or:SI (zero_extract:SI (match_dup 1)
8337 (const_int 8) (const_int 8))
8339 (clobber (reg:CC FLAGS_REG))])]
8340 "operands[0] = gen_lowpart (SImode, operands[0]);
8341 operands[1] = gen_lowpart (SImode, operands[1]);
8342 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8344 ;; Since OR can be encoded with sign extended immediate, this is only
8345 ;; profitable when 7th bit is set.
8347 [(set (match_operand 0 "register_operand" "")
8348 (any_or (match_operand 1 "general_operand" "")
8349 (match_operand 2 "const_int_operand" "")))
8350 (clobber (reg:CC FLAGS_REG))]
8352 && ANY_QI_REG_P (operands[0])
8353 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8354 && !(INTVAL (operands[2]) & ~255)
8355 && (INTVAL (operands[2]) & 128)
8356 && GET_MODE (operands[0]) != QImode"
8357 [(parallel [(set (strict_low_part (match_dup 0))
8358 (any_or:QI (match_dup 1)
8360 (clobber (reg:CC FLAGS_REG))])]
8361 "operands[0] = gen_lowpart (QImode, operands[0]);
8362 operands[1] = gen_lowpart (QImode, operands[1]);
8363 operands[2] = gen_lowpart (QImode, operands[2]);")
8365 (define_expand "xorqi_cc_ext_1"
8367 (set (reg:CCNO FLAGS_REG)
8371 (match_operand 1 "ext_register_operand" "")
8374 (match_operand:QI 2 "general_operand" ""))
8376 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8386 (define_insn "*xorqi_cc_ext_1_rex64"
8387 [(set (reg FLAGS_REG)
8391 (match_operand 1 "ext_register_operand" "0")
8394 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8396 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8405 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8406 "xor{b}\t{%2, %h0|%h0, %2}"
8407 [(set_attr "type" "alu")
8408 (set_attr "modrm" "1")
8409 (set_attr "mode" "QI")])
8411 (define_insn "*xorqi_cc_ext_1"
8412 [(set (reg FLAGS_REG)
8416 (match_operand 1 "ext_register_operand" "0")
8419 (match_operand:QI 2 "general_operand" "qmn"))
8421 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8430 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8431 "xor{b}\t{%2, %h0|%h0, %2}"
8432 [(set_attr "type" "alu")
8433 (set_attr "modrm" "1")
8434 (set_attr "mode" "QI")])
8436 ;; Negation instructions
8438 (define_expand "neg<mode>2"
8439 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8440 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8442 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8444 (define_insn_and_split "*neg<dwi>2_doubleword"
8445 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8446 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8447 (clobber (reg:CC FLAGS_REG))]
8448 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8452 [(set (reg:CCZ FLAGS_REG)
8453 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8454 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8457 (plus:DWIH (match_dup 3)
8458 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8460 (clobber (reg:CC FLAGS_REG))])
8463 (neg:DWIH (match_dup 2)))
8464 (clobber (reg:CC FLAGS_REG))])]
8465 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8467 (define_insn "*neg<mode>2_1"
8468 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8469 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8470 (clobber (reg:CC FLAGS_REG))]
8471 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8472 "neg{<imodesuffix>}\t%0"
8473 [(set_attr "type" "negnot")
8474 (set_attr "mode" "<MODE>")])
8476 ;; Combine is quite creative about this pattern.
8477 (define_insn "*negsi2_1_zext"
8478 [(set (match_operand:DI 0 "register_operand" "=r")
8480 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8483 (clobber (reg:CC FLAGS_REG))]
8484 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8486 [(set_attr "type" "negnot")
8487 (set_attr "mode" "SI")])
8489 ;; The problem with neg is that it does not perform (compare x 0),
8490 ;; it really performs (compare 0 x), which leaves us with the zero
8491 ;; flag being the only useful item.
8493 (define_insn "*neg<mode>2_cmpz"
8494 [(set (reg:CCZ FLAGS_REG)
8496 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8498 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8499 (neg:SWI (match_dup 1)))]
8500 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8501 "neg{<imodesuffix>}\t%0"
8502 [(set_attr "type" "negnot")
8503 (set_attr "mode" "<MODE>")])
8505 (define_insn "*negsi2_cmpz_zext"
8506 [(set (reg:CCZ FLAGS_REG)
8510 (match_operand:DI 1 "register_operand" "0")
8514 (set (match_operand:DI 0 "register_operand" "=r")
8515 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8518 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8520 [(set_attr "type" "negnot")
8521 (set_attr "mode" "SI")])
8523 ;; Changing of sign for FP values is doable using integer unit too.
8525 (define_expand "<code><mode>2"
8526 [(set (match_operand:X87MODEF 0 "register_operand" "")
8527 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8528 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8529 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8531 (define_insn "*absneg<mode>2_mixed"
8532 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8533 (match_operator:MODEF 3 "absneg_operator"
8534 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8535 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8540 (define_insn "*absneg<mode>2_sse"
8541 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8542 (match_operator:MODEF 3 "absneg_operator"
8543 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8544 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8549 (define_insn "*absneg<mode>2_i387"
8550 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8551 (match_operator:X87MODEF 3 "absneg_operator"
8552 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8553 (use (match_operand 2 "" ""))
8554 (clobber (reg:CC FLAGS_REG))]
8555 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8558 (define_expand "<code>tf2"
8559 [(set (match_operand:TF 0 "register_operand" "")
8560 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8562 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8564 (define_insn "*absnegtf2_sse"
8565 [(set (match_operand:TF 0 "register_operand" "=x,x")
8566 (match_operator:TF 3 "absneg_operator"
8567 [(match_operand:TF 1 "register_operand" "0,x")]))
8568 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8569 (clobber (reg:CC FLAGS_REG))]
8573 ;; Splitters for fp abs and neg.
8576 [(set (match_operand 0 "fp_register_operand" "")
8577 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8578 (use (match_operand 2 "" ""))
8579 (clobber (reg:CC FLAGS_REG))]
8581 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8584 [(set (match_operand 0 "register_operand" "")
8585 (match_operator 3 "absneg_operator"
8586 [(match_operand 1 "register_operand" "")]))
8587 (use (match_operand 2 "nonimmediate_operand" ""))
8588 (clobber (reg:CC FLAGS_REG))]
8589 "reload_completed && SSE_REG_P (operands[0])"
8590 [(set (match_dup 0) (match_dup 3))]
8592 enum machine_mode mode = GET_MODE (operands[0]);
8593 enum machine_mode vmode = GET_MODE (operands[2]);
8596 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8597 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8598 if (operands_match_p (operands[0], operands[2]))
8601 operands[1] = operands[2];
8604 if (GET_CODE (operands[3]) == ABS)
8605 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8607 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8612 [(set (match_operand:SF 0 "register_operand" "")
8613 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8614 (use (match_operand:V4SF 2 "" ""))
8615 (clobber (reg:CC FLAGS_REG))]
8617 [(parallel [(set (match_dup 0) (match_dup 1))
8618 (clobber (reg:CC FLAGS_REG))])]
8621 operands[0] = gen_lowpart (SImode, operands[0]);
8622 if (GET_CODE (operands[1]) == ABS)
8624 tmp = gen_int_mode (0x7fffffff, SImode);
8625 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8629 tmp = gen_int_mode (0x80000000, SImode);
8630 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8636 [(set (match_operand:DF 0 "register_operand" "")
8637 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8638 (use (match_operand 2 "" ""))
8639 (clobber (reg:CC FLAGS_REG))]
8641 [(parallel [(set (match_dup 0) (match_dup 1))
8642 (clobber (reg:CC FLAGS_REG))])]
8647 tmp = gen_lowpart (DImode, operands[0]);
8648 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8651 if (GET_CODE (operands[1]) == ABS)
8654 tmp = gen_rtx_NOT (DImode, tmp);
8658 operands[0] = gen_highpart (SImode, operands[0]);
8659 if (GET_CODE (operands[1]) == ABS)
8661 tmp = gen_int_mode (0x7fffffff, SImode);
8662 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8666 tmp = gen_int_mode (0x80000000, SImode);
8667 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8674 [(set (match_operand:XF 0 "register_operand" "")
8675 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8676 (use (match_operand 2 "" ""))
8677 (clobber (reg:CC FLAGS_REG))]
8679 [(parallel [(set (match_dup 0) (match_dup 1))
8680 (clobber (reg:CC FLAGS_REG))])]
8683 operands[0] = gen_rtx_REG (SImode,
8684 true_regnum (operands[0])
8685 + (TARGET_64BIT ? 1 : 2));
8686 if (GET_CODE (operands[1]) == ABS)
8688 tmp = GEN_INT (0x7fff);
8689 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8693 tmp = GEN_INT (0x8000);
8694 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8699 ;; Conditionalize these after reload. If they match before reload, we
8700 ;; lose the clobber and ability to use integer instructions.
8702 (define_insn "*<code><mode>2_1"
8703 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8704 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8706 && (reload_completed
8707 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8708 "f<absneg_mnemonic>"
8709 [(set_attr "type" "fsgn")
8710 (set_attr "mode" "<MODE>")])
8712 (define_insn "*<code>extendsfdf2"
8713 [(set (match_operand:DF 0 "register_operand" "=f")
8714 (absneg:DF (float_extend:DF
8715 (match_operand:SF 1 "register_operand" "0"))))]
8716 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8717 "f<absneg_mnemonic>"
8718 [(set_attr "type" "fsgn")
8719 (set_attr "mode" "DF")])
8721 (define_insn "*<code>extendsfxf2"
8722 [(set (match_operand:XF 0 "register_operand" "=f")
8723 (absneg:XF (float_extend:XF
8724 (match_operand:SF 1 "register_operand" "0"))))]
8726 "f<absneg_mnemonic>"
8727 [(set_attr "type" "fsgn")
8728 (set_attr "mode" "XF")])
8730 (define_insn "*<code>extenddfxf2"
8731 [(set (match_operand:XF 0 "register_operand" "=f")
8732 (absneg:XF (float_extend:XF
8733 (match_operand:DF 1 "register_operand" "0"))))]
8735 "f<absneg_mnemonic>"
8736 [(set_attr "type" "fsgn")
8737 (set_attr "mode" "XF")])
8739 ;; Copysign instructions
8741 (define_mode_iterator CSGNMODE [SF DF TF])
8742 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8744 (define_expand "copysign<mode>3"
8745 [(match_operand:CSGNMODE 0 "register_operand" "")
8746 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8747 (match_operand:CSGNMODE 2 "register_operand" "")]
8748 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8749 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8750 "ix86_expand_copysign (operands); DONE;")
8752 (define_insn_and_split "copysign<mode>3_const"
8753 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8755 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8756 (match_operand:CSGNMODE 2 "register_operand" "0")
8757 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8759 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8760 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8762 "&& reload_completed"
8764 "ix86_split_copysign_const (operands); DONE;")
8766 (define_insn "copysign<mode>3_var"
8767 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8769 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8770 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8771 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8772 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8774 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8775 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8776 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8780 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8782 [(match_operand:CSGNMODE 2 "register_operand" "")
8783 (match_operand:CSGNMODE 3 "register_operand" "")
8784 (match_operand:<CSGNVMODE> 4 "" "")
8785 (match_operand:<CSGNVMODE> 5 "" "")]
8787 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8788 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8789 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8790 && reload_completed"
8792 "ix86_split_copysign_var (operands); DONE;")
8794 ;; One complement instructions
8796 (define_expand "one_cmpl<mode>2"
8797 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8798 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8800 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8802 (define_insn "*one_cmpl<mode>2_1"
8803 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8804 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8805 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8806 "not{<imodesuffix>}\t%0"
8807 [(set_attr "type" "negnot")
8808 (set_attr "mode" "<MODE>")])
8810 ;; %%% Potential partial reg stall on alternative 1. What to do?
8811 (define_insn "*one_cmplqi2_1"
8812 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8813 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8814 "ix86_unary_operator_ok (NOT, QImode, operands)"
8818 [(set_attr "type" "negnot")
8819 (set_attr "mode" "QI,SI")])
8821 ;; ??? Currently never generated - xor is used instead.
8822 (define_insn "*one_cmplsi2_1_zext"
8823 [(set (match_operand:DI 0 "register_operand" "=r")
8825 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8826 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8828 [(set_attr "type" "negnot")
8829 (set_attr "mode" "SI")])
8831 (define_insn "*one_cmpl<mode>2_2"
8832 [(set (reg FLAGS_REG)
8833 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8835 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8836 (not:SWI (match_dup 1)))]
8837 "ix86_match_ccmode (insn, CCNOmode)
8838 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8840 [(set_attr "type" "alu1")
8841 (set_attr "mode" "<MODE>")])
8844 [(set (match_operand 0 "flags_reg_operand" "")
8845 (match_operator 2 "compare_operator"
8846 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8848 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8849 (not:SWI (match_dup 3)))]
8850 "ix86_match_ccmode (insn, CCNOmode)"
8851 [(parallel [(set (match_dup 0)
8852 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8855 (xor:SWI (match_dup 3) (const_int -1)))])])
8857 ;; ??? Currently never generated - xor is used instead.
8858 (define_insn "*one_cmplsi2_2_zext"
8859 [(set (reg FLAGS_REG)
8860 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8862 (set (match_operand:DI 0 "register_operand" "=r")
8863 (zero_extend:DI (not:SI (match_dup 1))))]
8864 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8865 && ix86_unary_operator_ok (NOT, SImode, operands)"
8867 [(set_attr "type" "alu1")
8868 (set_attr "mode" "SI")])
8871 [(set (match_operand 0 "flags_reg_operand" "")
8872 (match_operator 2 "compare_operator"
8873 [(not:SI (match_operand:SI 3 "register_operand" ""))
8875 (set (match_operand:DI 1 "register_operand" "")
8876 (zero_extend:DI (not:SI (match_dup 3))))]
8877 "ix86_match_ccmode (insn, CCNOmode)"
8878 [(parallel [(set (match_dup 0)
8879 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8882 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8884 ;; Shift instructions
8886 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8887 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8888 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8889 ;; from the assembler input.
8891 ;; This instruction shifts the target reg/mem as usual, but instead of
8892 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8893 ;; is a left shift double, bits are taken from the high order bits of
8894 ;; reg, else if the insn is a shift right double, bits are taken from the
8895 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8896 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8898 ;; Since sh[lr]d does not change the `reg' operand, that is done
8899 ;; separately, making all shifts emit pairs of shift double and normal
8900 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8901 ;; support a 63 bit shift, each shift where the count is in a reg expands
8902 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8904 ;; If the shift count is a constant, we need never emit more than one
8905 ;; shift pair, instead using moves and sign extension for counts greater
8908 (define_expand "ashl<mode>3"
8909 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8910 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8911 (match_operand:QI 2 "nonmemory_operand" "")))]
8913 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8915 (define_insn "*ashl<mode>3_doubleword"
8916 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8917 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8918 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8919 (clobber (reg:CC FLAGS_REG))]
8922 [(set_attr "type" "multi")])
8925 [(set (match_operand:DWI 0 "register_operand" "")
8926 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8927 (match_operand:QI 2 "nonmemory_operand" "")))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8931 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8933 ;; By default we don't ask for a scratch register, because when DWImode
8934 ;; values are manipulated, registers are already at a premium. But if
8935 ;; we have one handy, we won't turn it away.
8938 [(match_scratch:DWIH 3 "r")
8939 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8941 (match_operand:<DWI> 1 "nonmemory_operand" "")
8942 (match_operand:QI 2 "nonmemory_operand" "")))
8943 (clobber (reg:CC FLAGS_REG))])
8947 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8949 (define_insn "x86_64_shld"
8950 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8951 (ior:DI (ashift:DI (match_dup 0)
8952 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8953 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8954 (minus:QI (const_int 64) (match_dup 2)))))
8955 (clobber (reg:CC FLAGS_REG))]
8957 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8958 [(set_attr "type" "ishift")
8959 (set_attr "prefix_0f" "1")
8960 (set_attr "mode" "DI")
8961 (set_attr "athlon_decode" "vector")
8962 (set_attr "amdfam10_decode" "vector")
8963 (set_attr "bdver1_decode" "vector")])
8965 (define_insn "x86_shld"
8966 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8967 (ior:SI (ashift:SI (match_dup 0)
8968 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8969 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8970 (minus:QI (const_int 32) (match_dup 2)))))
8971 (clobber (reg:CC FLAGS_REG))]
8973 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8974 [(set_attr "type" "ishift")
8975 (set_attr "prefix_0f" "1")
8976 (set_attr "mode" "SI")
8977 (set_attr "pent_pair" "np")
8978 (set_attr "athlon_decode" "vector")
8979 (set_attr "amdfam10_decode" "vector")
8980 (set_attr "bdver1_decode" "vector")])
8982 (define_expand "x86_shift<mode>_adj_1"
8983 [(set (reg:CCZ FLAGS_REG)
8984 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8987 (set (match_operand:SWI48 0 "register_operand" "")
8988 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8989 (match_operand:SWI48 1 "register_operand" "")
8992 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8993 (match_operand:SWI48 3 "register_operand" "r")
8996 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8998 (define_expand "x86_shift<mode>_adj_2"
8999 [(use (match_operand:SWI48 0 "register_operand" ""))
9000 (use (match_operand:SWI48 1 "register_operand" ""))
9001 (use (match_operand:QI 2 "register_operand" ""))]
9004 rtx label = gen_label_rtx ();
9007 emit_insn (gen_testqi_ccz_1 (operands[2],
9008 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9010 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9011 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9012 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9013 gen_rtx_LABEL_REF (VOIDmode, label),
9015 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9016 JUMP_LABEL (tmp) = label;
9018 emit_move_insn (operands[0], operands[1]);
9019 ix86_expand_clear (operands[1]);
9022 LABEL_NUSES (label) = 1;
9027 ;; Avoid useless masking of count operand.
9028 (define_insn_and_split "*ashl<mode>3_mask"
9029 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9031 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9034 (match_operand:SI 2 "nonimmediate_operand" "c")
9035 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9036 (clobber (reg:CC FLAGS_REG))]
9037 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9038 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9039 == GET_MODE_BITSIZE (<MODE>mode)-1"
9042 [(parallel [(set (match_dup 0)
9043 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9044 (clobber (reg:CC FLAGS_REG))])]
9046 if (can_create_pseudo_p ())
9047 operands [2] = force_reg (SImode, operands[2]);
9049 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9051 [(set_attr "type" "ishift")
9052 (set_attr "mode" "<MODE>")])
9054 (define_insn "*ashl<mode>3_1"
9055 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9056 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9057 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9058 (clobber (reg:CC FLAGS_REG))]
9059 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9061 switch (get_attr_type (insn))
9067 gcc_assert (operands[2] == const1_rtx);
9068 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9069 return "add{<imodesuffix>}\t%0, %0";
9072 if (operands[2] == const1_rtx
9073 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9074 return "sal{<imodesuffix>}\t%0";
9076 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9080 (cond [(eq_attr "alternative" "1")
9081 (const_string "lea")
9082 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9084 (match_operand 0 "register_operand" ""))
9085 (match_operand 2 "const1_operand" ""))
9086 (const_string "alu")
9088 (const_string "ishift")))
9089 (set (attr "length_immediate")
9091 (ior (eq_attr "type" "alu")
9092 (and (eq_attr "type" "ishift")
9093 (and (match_operand 2 "const1_operand" "")
9094 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9097 (const_string "*")))
9098 (set_attr "mode" "<MODE>")])
9100 (define_insn "*ashlsi3_1_zext"
9101 [(set (match_operand:DI 0 "register_operand" "=r,r")
9103 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9104 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9105 (clobber (reg:CC FLAGS_REG))]
9106 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9108 switch (get_attr_type (insn))
9114 gcc_assert (operands[2] == const1_rtx);
9115 return "add{l}\t%k0, %k0";
9118 if (operands[2] == const1_rtx
9119 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9120 return "sal{l}\t%k0";
9122 return "sal{l}\t{%2, %k0|%k0, %2}";
9126 (cond [(eq_attr "alternative" "1")
9127 (const_string "lea")
9128 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9130 (match_operand 2 "const1_operand" ""))
9131 (const_string "alu")
9133 (const_string "ishift")))
9134 (set (attr "length_immediate")
9136 (ior (eq_attr "type" "alu")
9137 (and (eq_attr "type" "ishift")
9138 (and (match_operand 2 "const1_operand" "")
9139 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9142 (const_string "*")))
9143 (set_attr "mode" "SI")])
9145 (define_insn "*ashlhi3_1"
9146 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9147 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9148 (match_operand:QI 2 "nonmemory_operand" "cI")))
9149 (clobber (reg:CC FLAGS_REG))]
9150 "TARGET_PARTIAL_REG_STALL
9151 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9153 switch (get_attr_type (insn))
9156 gcc_assert (operands[2] == const1_rtx);
9157 return "add{w}\t%0, %0";
9160 if (operands[2] == const1_rtx
9161 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9162 return "sal{w}\t%0";
9164 return "sal{w}\t{%2, %0|%0, %2}";
9168 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9170 (match_operand 0 "register_operand" ""))
9171 (match_operand 2 "const1_operand" ""))
9172 (const_string "alu")
9174 (const_string "ishift")))
9175 (set (attr "length_immediate")
9177 (ior (eq_attr "type" "alu")
9178 (and (eq_attr "type" "ishift")
9179 (and (match_operand 2 "const1_operand" "")
9180 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9183 (const_string "*")))
9184 (set_attr "mode" "HI")])
9186 (define_insn "*ashlhi3_1_lea"
9187 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9188 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9189 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9190 (clobber (reg:CC FLAGS_REG))]
9191 "!TARGET_PARTIAL_REG_STALL
9192 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9194 switch (get_attr_type (insn))
9200 gcc_assert (operands[2] == const1_rtx);
9201 return "add{w}\t%0, %0";
9204 if (operands[2] == const1_rtx
9205 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9206 return "sal{w}\t%0";
9208 return "sal{w}\t{%2, %0|%0, %2}";
9212 (cond [(eq_attr "alternative" "1")
9213 (const_string "lea")
9214 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9216 (match_operand 0 "register_operand" ""))
9217 (match_operand 2 "const1_operand" ""))
9218 (const_string "alu")
9220 (const_string "ishift")))
9221 (set (attr "length_immediate")
9223 (ior (eq_attr "type" "alu")
9224 (and (eq_attr "type" "ishift")
9225 (and (match_operand 2 "const1_operand" "")
9226 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9229 (const_string "*")))
9230 (set_attr "mode" "HI,SI")])
9232 (define_insn "*ashlqi3_1"
9233 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9234 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9235 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9236 (clobber (reg:CC FLAGS_REG))]
9237 "TARGET_PARTIAL_REG_STALL
9238 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9240 switch (get_attr_type (insn))
9243 gcc_assert (operands[2] == const1_rtx);
9244 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9245 return "add{l}\t%k0, %k0";
9247 return "add{b}\t%0, %0";
9250 if (operands[2] == const1_rtx
9251 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9253 if (get_attr_mode (insn) == MODE_SI)
9254 return "sal{l}\t%k0";
9256 return "sal{b}\t%0";
9260 if (get_attr_mode (insn) == MODE_SI)
9261 return "sal{l}\t{%2, %k0|%k0, %2}";
9263 return "sal{b}\t{%2, %0|%0, %2}";
9268 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9270 (match_operand 0 "register_operand" ""))
9271 (match_operand 2 "const1_operand" ""))
9272 (const_string "alu")
9274 (const_string "ishift")))
9275 (set (attr "length_immediate")
9277 (ior (eq_attr "type" "alu")
9278 (and (eq_attr "type" "ishift")
9279 (and (match_operand 2 "const1_operand" "")
9280 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9283 (const_string "*")))
9284 (set_attr "mode" "QI,SI")])
9286 ;; %%% Potential partial reg stall on alternative 2. What to do?
9287 (define_insn "*ashlqi3_1_lea"
9288 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9289 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9290 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9291 (clobber (reg:CC FLAGS_REG))]
9292 "!TARGET_PARTIAL_REG_STALL
9293 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9295 switch (get_attr_type (insn))
9301 gcc_assert (operands[2] == const1_rtx);
9302 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9303 return "add{l}\t%k0, %k0";
9305 return "add{b}\t%0, %0";
9308 if (operands[2] == const1_rtx
9309 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9311 if (get_attr_mode (insn) == MODE_SI)
9312 return "sal{l}\t%k0";
9314 return "sal{b}\t%0";
9318 if (get_attr_mode (insn) == MODE_SI)
9319 return "sal{l}\t{%2, %k0|%k0, %2}";
9321 return "sal{b}\t{%2, %0|%0, %2}";
9326 (cond [(eq_attr "alternative" "2")
9327 (const_string "lea")
9328 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9330 (match_operand 0 "register_operand" ""))
9331 (match_operand 2 "const1_operand" ""))
9332 (const_string "alu")
9334 (const_string "ishift")))
9335 (set (attr "length_immediate")
9337 (ior (eq_attr "type" "alu")
9338 (and (eq_attr "type" "ishift")
9339 (and (match_operand 2 "const1_operand" "")
9340 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9343 (const_string "*")))
9344 (set_attr "mode" "QI,SI,SI")])
9346 (define_insn "*ashlqi3_1_slp"
9347 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9348 (ashift:QI (match_dup 0)
9349 (match_operand:QI 1 "nonmemory_operand" "cI")))
9350 (clobber (reg:CC FLAGS_REG))]
9351 "(optimize_function_for_size_p (cfun)
9352 || !TARGET_PARTIAL_FLAG_REG_STALL
9353 || (operands[1] == const1_rtx
9355 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9357 switch (get_attr_type (insn))
9360 gcc_assert (operands[1] == const1_rtx);
9361 return "add{b}\t%0, %0";
9364 if (operands[1] == const1_rtx
9365 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9366 return "sal{b}\t%0";
9368 return "sal{b}\t{%1, %0|%0, %1}";
9372 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9374 (match_operand 0 "register_operand" ""))
9375 (match_operand 1 "const1_operand" ""))
9376 (const_string "alu")
9378 (const_string "ishift1")))
9379 (set (attr "length_immediate")
9381 (ior (eq_attr "type" "alu")
9382 (and (eq_attr "type" "ishift1")
9383 (and (match_operand 1 "const1_operand" "")
9384 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9387 (const_string "*")))
9388 (set_attr "mode" "QI")])
9390 ;; Convert lea to the lea pattern to avoid flags dependency.
9392 [(set (match_operand 0 "register_operand" "")
9393 (ashift (match_operand 1 "index_register_operand" "")
9394 (match_operand:QI 2 "const_int_operand" "")))
9395 (clobber (reg:CC FLAGS_REG))]
9397 && true_regnum (operands[0]) != true_regnum (operands[1])"
9401 enum machine_mode mode = GET_MODE (operands[0]);
9404 operands[1] = gen_lowpart (Pmode, operands[1]);
9405 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9407 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9409 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9410 operands[0] = gen_lowpart (SImode, operands[0]);
9412 if (TARGET_64BIT && mode != Pmode)
9413 pat = gen_rtx_SUBREG (SImode, pat, 0);
9415 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9419 ;; Convert lea to the lea pattern to avoid flags dependency.
9421 [(set (match_operand:DI 0 "register_operand" "")
9423 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9424 (match_operand:QI 2 "const_int_operand" ""))))
9425 (clobber (reg:CC FLAGS_REG))]
9426 "TARGET_64BIT && reload_completed
9427 && true_regnum (operands[0]) != true_regnum (operands[1])"
9429 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9431 operands[1] = gen_lowpart (DImode, operands[1]);
9432 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9435 ;; This pattern can't accept a variable shift count, since shifts by
9436 ;; zero don't affect the flags. We assume that shifts by constant
9437 ;; zero are optimized away.
9438 (define_insn "*ashl<mode>3_cmp"
9439 [(set (reg FLAGS_REG)
9441 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9442 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9444 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9445 (ashift:SWI (match_dup 1) (match_dup 2)))]
9446 "(optimize_function_for_size_p (cfun)
9447 || !TARGET_PARTIAL_FLAG_REG_STALL
9448 || (operands[2] == const1_rtx
9450 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9451 && ix86_match_ccmode (insn, CCGOCmode)
9452 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9454 switch (get_attr_type (insn))
9457 gcc_assert (operands[2] == const1_rtx);
9458 return "add{<imodesuffix>}\t%0, %0";
9461 if (operands[2] == const1_rtx
9462 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9463 return "sal{<imodesuffix>}\t%0";
9465 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9469 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9471 (match_operand 0 "register_operand" ""))
9472 (match_operand 2 "const1_operand" ""))
9473 (const_string "alu")
9475 (const_string "ishift")))
9476 (set (attr "length_immediate")
9478 (ior (eq_attr "type" "alu")
9479 (and (eq_attr "type" "ishift")
9480 (and (match_operand 2 "const1_operand" "")
9481 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9484 (const_string "*")))
9485 (set_attr "mode" "<MODE>")])
9487 (define_insn "*ashlsi3_cmp_zext"
9488 [(set (reg FLAGS_REG)
9490 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9491 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9493 (set (match_operand:DI 0 "register_operand" "=r")
9494 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9496 && (optimize_function_for_size_p (cfun)
9497 || !TARGET_PARTIAL_FLAG_REG_STALL
9498 || (operands[2] == const1_rtx
9500 || TARGET_DOUBLE_WITH_ADD)))
9501 && ix86_match_ccmode (insn, CCGOCmode)
9502 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9504 switch (get_attr_type (insn))
9507 gcc_assert (operands[2] == const1_rtx);
9508 return "add{l}\t%k0, %k0";
9511 if (operands[2] == const1_rtx
9512 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513 return "sal{l}\t%k0";
9515 return "sal{l}\t{%2, %k0|%k0, %2}";
9519 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9521 (match_operand 2 "const1_operand" ""))
9522 (const_string "alu")
9524 (const_string "ishift")))
9525 (set (attr "length_immediate")
9527 (ior (eq_attr "type" "alu")
9528 (and (eq_attr "type" "ishift")
9529 (and (match_operand 2 "const1_operand" "")
9530 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9533 (const_string "*")))
9534 (set_attr "mode" "SI")])
9536 (define_insn "*ashl<mode>3_cconly"
9537 [(set (reg FLAGS_REG)
9539 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9540 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9542 (clobber (match_scratch:SWI 0 "=<r>"))]
9543 "(optimize_function_for_size_p (cfun)
9544 || !TARGET_PARTIAL_FLAG_REG_STALL
9545 || (operands[2] == const1_rtx
9547 || TARGET_DOUBLE_WITH_ADD)))
9548 && ix86_match_ccmode (insn, CCGOCmode)"
9550 switch (get_attr_type (insn))
9553 gcc_assert (operands[2] == const1_rtx);
9554 return "add{<imodesuffix>}\t%0, %0";
9557 if (operands[2] == const1_rtx
9558 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9559 return "sal{<imodesuffix>}\t%0";
9561 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9565 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9567 (match_operand 0 "register_operand" ""))
9568 (match_operand 2 "const1_operand" ""))
9569 (const_string "alu")
9571 (const_string "ishift")))
9572 (set (attr "length_immediate")
9574 (ior (eq_attr "type" "alu")
9575 (and (eq_attr "type" "ishift")
9576 (and (match_operand 2 "const1_operand" "")
9577 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9580 (const_string "*")))
9581 (set_attr "mode" "<MODE>")])
9583 ;; See comment above `ashl<mode>3' about how this works.
9585 (define_expand "<shiftrt_insn><mode>3"
9586 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9587 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9588 (match_operand:QI 2 "nonmemory_operand" "")))]
9590 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9592 ;; Avoid useless masking of count operand.
9593 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9594 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9596 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9599 (match_operand:SI 2 "nonimmediate_operand" "c")
9600 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9601 (clobber (reg:CC FLAGS_REG))]
9602 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9603 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9604 == GET_MODE_BITSIZE (<MODE>mode)-1"
9607 [(parallel [(set (match_dup 0)
9608 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9609 (clobber (reg:CC FLAGS_REG))])]
9611 if (can_create_pseudo_p ())
9612 operands [2] = force_reg (SImode, operands[2]);
9614 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9616 [(set_attr "type" "ishift")
9617 (set_attr "mode" "<MODE>")])
9619 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9620 [(set (match_operand:DWI 0 "register_operand" "=r")
9621 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9622 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9623 (clobber (reg:CC FLAGS_REG))]
9626 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9628 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9629 [(set_attr "type" "multi")])
9631 ;; By default we don't ask for a scratch register, because when DWImode
9632 ;; values are manipulated, registers are already at a premium. But if
9633 ;; we have one handy, we won't turn it away.
9636 [(match_scratch:DWIH 3 "r")
9637 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9639 (match_operand:<DWI> 1 "register_operand" "")
9640 (match_operand:QI 2 "nonmemory_operand" "")))
9641 (clobber (reg:CC FLAGS_REG))])
9645 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9647 (define_insn "x86_64_shrd"
9648 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9649 (ior:DI (ashiftrt:DI (match_dup 0)
9650 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9651 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9652 (minus:QI (const_int 64) (match_dup 2)))))
9653 (clobber (reg:CC FLAGS_REG))]
9655 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9656 [(set_attr "type" "ishift")
9657 (set_attr "prefix_0f" "1")
9658 (set_attr "mode" "DI")
9659 (set_attr "athlon_decode" "vector")
9660 (set_attr "amdfam10_decode" "vector")
9661 (set_attr "bdver1_decode" "vector")])
9663 (define_insn "x86_shrd"
9664 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9665 (ior:SI (ashiftrt:SI (match_dup 0)
9666 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9667 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9668 (minus:QI (const_int 32) (match_dup 2)))))
9669 (clobber (reg:CC FLAGS_REG))]
9671 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9672 [(set_attr "type" "ishift")
9673 (set_attr "prefix_0f" "1")
9674 (set_attr "mode" "SI")
9675 (set_attr "pent_pair" "np")
9676 (set_attr "athlon_decode" "vector")
9677 (set_attr "amdfam10_decode" "vector")
9678 (set_attr "bdver1_decode" "vector")])
9680 (define_insn "ashrdi3_cvt"
9681 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9682 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9683 (match_operand:QI 2 "const_int_operand" "")))
9684 (clobber (reg:CC FLAGS_REG))]
9685 "TARGET_64BIT && INTVAL (operands[2]) == 63
9686 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9687 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9690 sar{q}\t{%2, %0|%0, %2}"
9691 [(set_attr "type" "imovx,ishift")
9692 (set_attr "prefix_0f" "0,*")
9693 (set_attr "length_immediate" "0,*")
9694 (set_attr "modrm" "0,1")
9695 (set_attr "mode" "DI")])
9697 (define_insn "ashrsi3_cvt"
9698 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9699 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9700 (match_operand:QI 2 "const_int_operand" "")))
9701 (clobber (reg:CC FLAGS_REG))]
9702 "INTVAL (operands[2]) == 31
9703 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9704 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9707 sar{l}\t{%2, %0|%0, %2}"
9708 [(set_attr "type" "imovx,ishift")
9709 (set_attr "prefix_0f" "0,*")
9710 (set_attr "length_immediate" "0,*")
9711 (set_attr "modrm" "0,1")
9712 (set_attr "mode" "SI")])
9714 (define_insn "*ashrsi3_cvt_zext"
9715 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9717 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9718 (match_operand:QI 2 "const_int_operand" ""))))
9719 (clobber (reg:CC FLAGS_REG))]
9720 "TARGET_64BIT && INTVAL (operands[2]) == 31
9721 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9722 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9725 sar{l}\t{%2, %k0|%k0, %2}"
9726 [(set_attr "type" "imovx,ishift")
9727 (set_attr "prefix_0f" "0,*")
9728 (set_attr "length_immediate" "0,*")
9729 (set_attr "modrm" "0,1")
9730 (set_attr "mode" "SI")])
9732 (define_expand "x86_shift<mode>_adj_3"
9733 [(use (match_operand:SWI48 0 "register_operand" ""))
9734 (use (match_operand:SWI48 1 "register_operand" ""))
9735 (use (match_operand:QI 2 "register_operand" ""))]
9738 rtx label = gen_label_rtx ();
9741 emit_insn (gen_testqi_ccz_1 (operands[2],
9742 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9744 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9745 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9746 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9747 gen_rtx_LABEL_REF (VOIDmode, label),
9749 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9750 JUMP_LABEL (tmp) = label;
9752 emit_move_insn (operands[0], operands[1]);
9753 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9754 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9756 LABEL_NUSES (label) = 1;
9761 (define_insn "*<shiftrt_insn><mode>3_1"
9762 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9763 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9764 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9765 (clobber (reg:CC FLAGS_REG))]
9766 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9768 if (operands[2] == const1_rtx
9769 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9770 return "<shiftrt>{<imodesuffix>}\t%0";
9772 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9774 [(set_attr "type" "ishift")
9775 (set (attr "length_immediate")
9777 (and (match_operand 2 "const1_operand" "")
9778 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9781 (const_string "*")))
9782 (set_attr "mode" "<MODE>")])
9784 (define_insn "*<shiftrt_insn>si3_1_zext"
9785 [(set (match_operand:DI 0 "register_operand" "=r")
9787 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9788 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9789 (clobber (reg:CC FLAGS_REG))]
9790 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9792 if (operands[2] == const1_rtx
9793 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9794 return "<shiftrt>{l}\t%k0";
9796 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9798 [(set_attr "type" "ishift")
9799 (set (attr "length_immediate")
9801 (and (match_operand 2 "const1_operand" "")
9802 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9805 (const_string "*")))
9806 (set_attr "mode" "SI")])
9808 (define_insn "*<shiftrt_insn>qi3_1_slp"
9809 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9810 (any_shiftrt:QI (match_dup 0)
9811 (match_operand:QI 1 "nonmemory_operand" "cI")))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "(optimize_function_for_size_p (cfun)
9814 || !TARGET_PARTIAL_REG_STALL
9815 || (operands[1] == const1_rtx
9818 if (operands[1] == const1_rtx
9819 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9820 return "<shiftrt>{b}\t%0";
9822 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9824 [(set_attr "type" "ishift1")
9825 (set (attr "length_immediate")
9827 (and (match_operand 1 "const1_operand" "")
9828 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9831 (const_string "*")))
9832 (set_attr "mode" "QI")])
9834 ;; This pattern can't accept a variable shift count, since shifts by
9835 ;; zero don't affect the flags. We assume that shifts by constant
9836 ;; zero are optimized away.
9837 (define_insn "*<shiftrt_insn><mode>3_cmp"
9838 [(set (reg FLAGS_REG)
9841 (match_operand:SWI 1 "nonimmediate_operand" "0")
9842 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9844 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9845 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9846 "(optimize_function_for_size_p (cfun)
9847 || !TARGET_PARTIAL_FLAG_REG_STALL
9848 || (operands[2] == const1_rtx
9850 && ix86_match_ccmode (insn, CCGOCmode)
9851 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9853 if (operands[2] == const1_rtx
9854 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9855 return "<shiftrt>{<imodesuffix>}\t%0";
9857 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9859 [(set_attr "type" "ishift")
9860 (set (attr "length_immediate")
9862 (and (match_operand 2 "const1_operand" "")
9863 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9866 (const_string "*")))
9867 (set_attr "mode" "<MODE>")])
9869 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9870 [(set (reg FLAGS_REG)
9872 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9873 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9875 (set (match_operand:DI 0 "register_operand" "=r")
9876 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9878 && (optimize_function_for_size_p (cfun)
9879 || !TARGET_PARTIAL_FLAG_REG_STALL
9880 || (operands[2] == const1_rtx
9882 && ix86_match_ccmode (insn, CCGOCmode)
9883 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9885 if (operands[2] == const1_rtx
9886 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9887 return "<shiftrt>{l}\t%k0";
9889 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9891 [(set_attr "type" "ishift")
9892 (set (attr "length_immediate")
9894 (and (match_operand 2 "const1_operand" "")
9895 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9898 (const_string "*")))
9899 (set_attr "mode" "SI")])
9901 (define_insn "*<shiftrt_insn><mode>3_cconly"
9902 [(set (reg FLAGS_REG)
9905 (match_operand:SWI 1 "register_operand" "0")
9906 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9908 (clobber (match_scratch:SWI 0 "=<r>"))]
9909 "(optimize_function_for_size_p (cfun)
9910 || !TARGET_PARTIAL_FLAG_REG_STALL
9911 || (operands[2] == const1_rtx
9913 && ix86_match_ccmode (insn, CCGOCmode)"
9915 if (operands[2] == const1_rtx
9916 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9917 return "<shiftrt>{<imodesuffix>}\t%0";
9919 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9921 [(set_attr "type" "ishift")
9922 (set (attr "length_immediate")
9924 (and (match_operand 2 "const1_operand" "")
9925 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9928 (const_string "*")))
9929 (set_attr "mode" "<MODE>")])
9931 ;; Rotate instructions
9933 (define_expand "<rotate_insn>ti3"
9934 [(set (match_operand:TI 0 "register_operand" "")
9935 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9936 (match_operand:QI 2 "nonmemory_operand" "")))]
9939 if (const_1_to_63_operand (operands[2], VOIDmode))
9940 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9941 (operands[0], operands[1], operands[2]));
9948 (define_expand "<rotate_insn>di3"
9949 [(set (match_operand:DI 0 "shiftdi_operand" "")
9950 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9951 (match_operand:QI 2 "nonmemory_operand" "")))]
9955 ix86_expand_binary_operator (<CODE>, DImode, operands);
9956 else if (const_1_to_31_operand (operands[2], VOIDmode))
9957 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9958 (operands[0], operands[1], operands[2]));
9965 (define_expand "<rotate_insn><mode>3"
9966 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9967 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9968 (match_operand:QI 2 "nonmemory_operand" "")))]
9970 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9972 ;; Avoid useless masking of count operand.
9973 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9974 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9976 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9979 (match_operand:SI 2 "nonimmediate_operand" "c")
9980 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9981 (clobber (reg:CC FLAGS_REG))]
9982 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9983 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9984 == GET_MODE_BITSIZE (<MODE>mode)-1"
9987 [(parallel [(set (match_dup 0)
9988 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9989 (clobber (reg:CC FLAGS_REG))])]
9991 if (can_create_pseudo_p ())
9992 operands [2] = force_reg (SImode, operands[2]);
9994 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9996 [(set_attr "type" "rotate")
9997 (set_attr "mode" "<MODE>")])
9999 ;; Implement rotation using two double-precision
10000 ;; shift instructions and a scratch register.
10002 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10003 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10004 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10005 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10006 (clobber (reg:CC FLAGS_REG))
10007 (clobber (match_scratch:DWIH 3 "=&r"))]
10011 [(set (match_dup 3) (match_dup 4))
10013 [(set (match_dup 4)
10014 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10015 (lshiftrt:DWIH (match_dup 5)
10016 (minus:QI (match_dup 6) (match_dup 2)))))
10017 (clobber (reg:CC FLAGS_REG))])
10019 [(set (match_dup 5)
10020 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10021 (lshiftrt:DWIH (match_dup 3)
10022 (minus:QI (match_dup 6) (match_dup 2)))))
10023 (clobber (reg:CC FLAGS_REG))])]
10025 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10027 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10030 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10031 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10032 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10033 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10034 (clobber (reg:CC FLAGS_REG))
10035 (clobber (match_scratch:DWIH 3 "=&r"))]
10039 [(set (match_dup 3) (match_dup 4))
10041 [(set (match_dup 4)
10042 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10043 (ashift:DWIH (match_dup 5)
10044 (minus:QI (match_dup 6) (match_dup 2)))))
10045 (clobber (reg:CC FLAGS_REG))])
10047 [(set (match_dup 5)
10048 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10049 (ashift:DWIH (match_dup 3)
10050 (minus:QI (match_dup 6) (match_dup 2)))))
10051 (clobber (reg:CC FLAGS_REG))])]
10053 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10055 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10058 (define_insn "*<rotate_insn><mode>3_1"
10059 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10060 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10061 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10062 (clobber (reg:CC FLAGS_REG))]
10063 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10065 if (operands[2] == const1_rtx
10066 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10067 return "<rotate>{<imodesuffix>}\t%0";
10069 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10071 [(set_attr "type" "rotate")
10072 (set (attr "length_immediate")
10074 (and (match_operand 2 "const1_operand" "")
10075 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10078 (const_string "*")))
10079 (set_attr "mode" "<MODE>")])
10081 (define_insn "*<rotate_insn>si3_1_zext"
10082 [(set (match_operand:DI 0 "register_operand" "=r")
10084 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10085 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10086 (clobber (reg:CC FLAGS_REG))]
10087 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10089 if (operands[2] == const1_rtx
10090 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10091 return "<rotate>{l}\t%k0";
10093 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10095 [(set_attr "type" "rotate")
10096 (set (attr "length_immediate")
10098 (and (match_operand 2 "const1_operand" "")
10099 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10102 (const_string "*")))
10103 (set_attr "mode" "SI")])
10105 (define_insn "*<rotate_insn>qi3_1_slp"
10106 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10107 (any_rotate:QI (match_dup 0)
10108 (match_operand:QI 1 "nonmemory_operand" "cI")))
10109 (clobber (reg:CC FLAGS_REG))]
10110 "(optimize_function_for_size_p (cfun)
10111 || !TARGET_PARTIAL_REG_STALL
10112 || (operands[1] == const1_rtx
10113 && TARGET_SHIFT1))"
10115 if (operands[1] == const1_rtx
10116 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10117 return "<rotate>{b}\t%0";
10119 return "<rotate>{b}\t{%1, %0|%0, %1}";
10121 [(set_attr "type" "rotate1")
10122 (set (attr "length_immediate")
10124 (and (match_operand 1 "const1_operand" "")
10125 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10128 (const_string "*")))
10129 (set_attr "mode" "QI")])
10132 [(set (match_operand:HI 0 "register_operand" "")
10133 (any_rotate:HI (match_dup 0) (const_int 8)))
10134 (clobber (reg:CC FLAGS_REG))]
10136 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10137 [(parallel [(set (strict_low_part (match_dup 0))
10138 (bswap:HI (match_dup 0)))
10139 (clobber (reg:CC FLAGS_REG))])])
10141 ;; Bit set / bit test instructions
10143 (define_expand "extv"
10144 [(set (match_operand:SI 0 "register_operand" "")
10145 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10146 (match_operand:SI 2 "const8_operand" "")
10147 (match_operand:SI 3 "const8_operand" "")))]
10150 /* Handle extractions from %ah et al. */
10151 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10154 /* From mips.md: extract_bit_field doesn't verify that our source
10155 matches the predicate, so check it again here. */
10156 if (! ext_register_operand (operands[1], VOIDmode))
10160 (define_expand "extzv"
10161 [(set (match_operand:SI 0 "register_operand" "")
10162 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10163 (match_operand:SI 2 "const8_operand" "")
10164 (match_operand:SI 3 "const8_operand" "")))]
10167 /* Handle extractions from %ah et al. */
10168 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10171 /* From mips.md: extract_bit_field doesn't verify that our source
10172 matches the predicate, so check it again here. */
10173 if (! ext_register_operand (operands[1], VOIDmode))
10177 (define_expand "insv"
10178 [(set (zero_extract (match_operand 0 "register_operand" "")
10179 (match_operand 1 "const_int_operand" "")
10180 (match_operand 2 "const_int_operand" ""))
10181 (match_operand 3 "register_operand" ""))]
10184 rtx (*gen_mov_insv_1) (rtx, rtx);
10186 if (ix86_expand_pinsr (operands))
10189 /* Handle insertions to %ah et al. */
10190 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10193 /* From mips.md: insert_bit_field doesn't verify that our source
10194 matches the predicate, so check it again here. */
10195 if (! ext_register_operand (operands[0], VOIDmode))
10198 gen_mov_insv_1 = (TARGET_64BIT
10199 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10201 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10205 ;; %%% bts, btr, btc, bt.
10206 ;; In general these instructions are *slow* when applied to memory,
10207 ;; since they enforce atomic operation. When applied to registers,
10208 ;; it depends on the cpu implementation. They're never faster than
10209 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10210 ;; no point. But in 64-bit, we can't hold the relevant immediates
10211 ;; within the instruction itself, so operating on bits in the high
10212 ;; 32-bits of a register becomes easier.
10214 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10215 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10216 ;; negdf respectively, so they can never be disabled entirely.
10218 (define_insn "*btsq"
10219 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10221 (match_operand:DI 1 "const_0_to_63_operand" ""))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10225 "bts{q}\t{%1, %0|%0, %1}"
10226 [(set_attr "type" "alu1")
10227 (set_attr "prefix_0f" "1")
10228 (set_attr "mode" "DI")])
10230 (define_insn "*btrq"
10231 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10233 (match_operand:DI 1 "const_0_to_63_operand" ""))
10235 (clobber (reg:CC FLAGS_REG))]
10236 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10237 "btr{q}\t{%1, %0|%0, %1}"
10238 [(set_attr "type" "alu1")
10239 (set_attr "prefix_0f" "1")
10240 (set_attr "mode" "DI")])
10242 (define_insn "*btcq"
10243 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10245 (match_operand:DI 1 "const_0_to_63_operand" ""))
10246 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10247 (clobber (reg:CC FLAGS_REG))]
10248 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10249 "btc{q}\t{%1, %0|%0, %1}"
10250 [(set_attr "type" "alu1")
10251 (set_attr "prefix_0f" "1")
10252 (set_attr "mode" "DI")])
10254 ;; Allow Nocona to avoid these instructions if a register is available.
10257 [(match_scratch:DI 2 "r")
10258 (parallel [(set (zero_extract:DI
10259 (match_operand:DI 0 "register_operand" "")
10261 (match_operand:DI 1 "const_0_to_63_operand" ""))
10263 (clobber (reg:CC FLAGS_REG))])]
10264 "TARGET_64BIT && !TARGET_USE_BT"
10267 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10270 if (HOST_BITS_PER_WIDE_INT >= 64)
10271 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10272 else if (i < HOST_BITS_PER_WIDE_INT)
10273 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10275 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10277 op1 = immed_double_const (lo, hi, DImode);
10280 emit_move_insn (operands[2], op1);
10284 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10289 [(match_scratch:DI 2 "r")
10290 (parallel [(set (zero_extract:DI
10291 (match_operand:DI 0 "register_operand" "")
10293 (match_operand:DI 1 "const_0_to_63_operand" ""))
10295 (clobber (reg:CC FLAGS_REG))])]
10296 "TARGET_64BIT && !TARGET_USE_BT"
10299 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10302 if (HOST_BITS_PER_WIDE_INT >= 64)
10303 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10304 else if (i < HOST_BITS_PER_WIDE_INT)
10305 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10307 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10309 op1 = immed_double_const (~lo, ~hi, DImode);
10312 emit_move_insn (operands[2], op1);
10316 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10321 [(match_scratch:DI 2 "r")
10322 (parallel [(set (zero_extract:DI
10323 (match_operand:DI 0 "register_operand" "")
10325 (match_operand:DI 1 "const_0_to_63_operand" ""))
10326 (not:DI (zero_extract:DI
10327 (match_dup 0) (const_int 1) (match_dup 1))))
10328 (clobber (reg:CC FLAGS_REG))])]
10329 "TARGET_64BIT && !TARGET_USE_BT"
10332 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10335 if (HOST_BITS_PER_WIDE_INT >= 64)
10336 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10337 else if (i < HOST_BITS_PER_WIDE_INT)
10338 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10340 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10342 op1 = immed_double_const (lo, hi, DImode);
10345 emit_move_insn (operands[2], op1);
10349 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10353 (define_insn "*bt<mode>"
10354 [(set (reg:CCC FLAGS_REG)
10356 (zero_extract:SWI48
10357 (match_operand:SWI48 0 "register_operand" "r")
10359 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10361 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10362 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10363 [(set_attr "type" "alu1")
10364 (set_attr "prefix_0f" "1")
10365 (set_attr "mode" "<MODE>")])
10367 ;; Store-flag instructions.
10369 ;; For all sCOND expanders, also expand the compare or test insn that
10370 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10372 (define_insn_and_split "*setcc_di_1"
10373 [(set (match_operand:DI 0 "register_operand" "=q")
10374 (match_operator:DI 1 "ix86_comparison_operator"
10375 [(reg FLAGS_REG) (const_int 0)]))]
10376 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10378 "&& reload_completed"
10379 [(set (match_dup 2) (match_dup 1))
10380 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10382 PUT_MODE (operands[1], QImode);
10383 operands[2] = gen_lowpart (QImode, operands[0]);
10386 (define_insn_and_split "*setcc_si_1_and"
10387 [(set (match_operand:SI 0 "register_operand" "=q")
10388 (match_operator:SI 1 "ix86_comparison_operator"
10389 [(reg FLAGS_REG) (const_int 0)]))
10390 (clobber (reg:CC FLAGS_REG))]
10391 "!TARGET_PARTIAL_REG_STALL
10392 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10394 "&& reload_completed"
10395 [(set (match_dup 2) (match_dup 1))
10396 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10397 (clobber (reg:CC FLAGS_REG))])]
10399 PUT_MODE (operands[1], QImode);
10400 operands[2] = gen_lowpart (QImode, operands[0]);
10403 (define_insn_and_split "*setcc_si_1_movzbl"
10404 [(set (match_operand:SI 0 "register_operand" "=q")
10405 (match_operator:SI 1 "ix86_comparison_operator"
10406 [(reg FLAGS_REG) (const_int 0)]))]
10407 "!TARGET_PARTIAL_REG_STALL
10408 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10410 "&& reload_completed"
10411 [(set (match_dup 2) (match_dup 1))
10412 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10414 PUT_MODE (operands[1], QImode);
10415 operands[2] = gen_lowpart (QImode, operands[0]);
10418 (define_insn "*setcc_qi"
10419 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10420 (match_operator:QI 1 "ix86_comparison_operator"
10421 [(reg FLAGS_REG) (const_int 0)]))]
10424 [(set_attr "type" "setcc")
10425 (set_attr "mode" "QI")])
10427 (define_insn "*setcc_qi_slp"
10428 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10429 (match_operator:QI 1 "ix86_comparison_operator"
10430 [(reg FLAGS_REG) (const_int 0)]))]
10433 [(set_attr "type" "setcc")
10434 (set_attr "mode" "QI")])
10436 ;; In general it is not safe to assume too much about CCmode registers,
10437 ;; so simplify-rtx stops when it sees a second one. Under certain
10438 ;; conditions this is safe on x86, so help combine not create
10445 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10446 (ne:QI (match_operator 1 "ix86_comparison_operator"
10447 [(reg FLAGS_REG) (const_int 0)])
10450 [(set (match_dup 0) (match_dup 1))]
10451 "PUT_MODE (operands[1], QImode);")
10454 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10455 (ne:QI (match_operator 1 "ix86_comparison_operator"
10456 [(reg FLAGS_REG) (const_int 0)])
10459 [(set (match_dup 0) (match_dup 1))]
10460 "PUT_MODE (operands[1], QImode);")
10463 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10464 (eq:QI (match_operator 1 "ix86_comparison_operator"
10465 [(reg FLAGS_REG) (const_int 0)])
10468 [(set (match_dup 0) (match_dup 1))]
10470 rtx new_op1 = copy_rtx (operands[1]);
10471 operands[1] = new_op1;
10472 PUT_MODE (new_op1, QImode);
10473 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10474 GET_MODE (XEXP (new_op1, 0))));
10476 /* Make sure that (a) the CCmode we have for the flags is strong
10477 enough for the reversed compare or (b) we have a valid FP compare. */
10478 if (! ix86_comparison_operator (new_op1, VOIDmode))
10483 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10484 (eq:QI (match_operator 1 "ix86_comparison_operator"
10485 [(reg FLAGS_REG) (const_int 0)])
10488 [(set (match_dup 0) (match_dup 1))]
10490 rtx new_op1 = copy_rtx (operands[1]);
10491 operands[1] = new_op1;
10492 PUT_MODE (new_op1, QImode);
10493 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10494 GET_MODE (XEXP (new_op1, 0))));
10496 /* Make sure that (a) the CCmode we have for the flags is strong
10497 enough for the reversed compare or (b) we have a valid FP compare. */
10498 if (! ix86_comparison_operator (new_op1, VOIDmode))
10502 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10503 ;; subsequent logical operations are used to imitate conditional moves.
10504 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10507 (define_insn "setcc_<mode>_sse"
10508 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10509 (match_operator:MODEF 3 "sse_comparison_operator"
10510 [(match_operand:MODEF 1 "register_operand" "0,x")
10511 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10512 "SSE_FLOAT_MODE_P (<MODE>mode)"
10514 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10515 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10516 [(set_attr "isa" "noavx,avx")
10517 (set_attr "type" "ssecmp")
10518 (set_attr "length_immediate" "1")
10519 (set_attr "prefix" "orig,vex")
10520 (set_attr "mode" "<MODE>")])
10522 ;; Basic conditional jump instructions.
10523 ;; We ignore the overflow flag for signed branch instructions.
10525 (define_insn "*jcc_1"
10527 (if_then_else (match_operator 1 "ix86_comparison_operator"
10528 [(reg FLAGS_REG) (const_int 0)])
10529 (label_ref (match_operand 0 "" ""))
10533 [(set_attr "type" "ibr")
10534 (set_attr "modrm" "0")
10535 (set (attr "length")
10536 (if_then_else (and (ge (minus (match_dup 0) (pc))
10538 (lt (minus (match_dup 0) (pc))
10543 (define_insn "*jcc_2"
10545 (if_then_else (match_operator 1 "ix86_comparison_operator"
10546 [(reg FLAGS_REG) (const_int 0)])
10548 (label_ref (match_operand 0 "" ""))))]
10551 [(set_attr "type" "ibr")
10552 (set_attr "modrm" "0")
10553 (set (attr "length")
10554 (if_then_else (and (ge (minus (match_dup 0) (pc))
10556 (lt (minus (match_dup 0) (pc))
10561 ;; In general it is not safe to assume too much about CCmode registers,
10562 ;; so simplify-rtx stops when it sees a second one. Under certain
10563 ;; conditions this is safe on x86, so help combine not create
10571 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10572 [(reg FLAGS_REG) (const_int 0)])
10574 (label_ref (match_operand 1 "" ""))
10578 (if_then_else (match_dup 0)
10579 (label_ref (match_dup 1))
10581 "PUT_MODE (operands[0], VOIDmode);")
10585 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10586 [(reg FLAGS_REG) (const_int 0)])
10588 (label_ref (match_operand 1 "" ""))
10592 (if_then_else (match_dup 0)
10593 (label_ref (match_dup 1))
10596 rtx new_op0 = copy_rtx (operands[0]);
10597 operands[0] = new_op0;
10598 PUT_MODE (new_op0, VOIDmode);
10599 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10600 GET_MODE (XEXP (new_op0, 0))));
10602 /* Make sure that (a) the CCmode we have for the flags is strong
10603 enough for the reversed compare or (b) we have a valid FP compare. */
10604 if (! ix86_comparison_operator (new_op0, VOIDmode))
10608 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10609 ;; pass generates from shift insn with QImode operand. Actually, the mode
10610 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10611 ;; appropriate modulo of the bit offset value.
10613 (define_insn_and_split "*jcc_bt<mode>"
10615 (if_then_else (match_operator 0 "bt_comparison_operator"
10616 [(zero_extract:SWI48
10617 (match_operand:SWI48 1 "register_operand" "r")
10620 (match_operand:QI 2 "register_operand" "r")))
10622 (label_ref (match_operand 3 "" ""))
10624 (clobber (reg:CC FLAGS_REG))]
10625 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10628 [(set (reg:CCC FLAGS_REG)
10630 (zero_extract:SWI48
10636 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10637 (label_ref (match_dup 3))
10640 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10642 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10645 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10646 ;; also for DImode, this is what combine produces.
10647 (define_insn_and_split "*jcc_bt<mode>_mask"
10649 (if_then_else (match_operator 0 "bt_comparison_operator"
10650 [(zero_extract:SWI48
10651 (match_operand:SWI48 1 "register_operand" "r")
10654 (match_operand:SI 2 "register_operand" "r")
10655 (match_operand:SI 3 "const_int_operand" "n")))])
10656 (label_ref (match_operand 4 "" ""))
10658 (clobber (reg:CC FLAGS_REG))]
10659 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10660 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10661 == GET_MODE_BITSIZE (<MODE>mode)-1"
10664 [(set (reg:CCC FLAGS_REG)
10666 (zero_extract:SWI48
10672 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10673 (label_ref (match_dup 4))
10676 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10678 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10681 (define_insn_and_split "*jcc_btsi_1"
10683 (if_then_else (match_operator 0 "bt_comparison_operator"
10686 (match_operand:SI 1 "register_operand" "r")
10687 (match_operand:QI 2 "register_operand" "r"))
10690 (label_ref (match_operand 3 "" ""))
10692 (clobber (reg:CC FLAGS_REG))]
10693 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10696 [(set (reg:CCC FLAGS_REG)
10704 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10705 (label_ref (match_dup 3))
10708 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10710 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10713 ;; avoid useless masking of bit offset operand
10714 (define_insn_and_split "*jcc_btsi_mask_1"
10717 (match_operator 0 "bt_comparison_operator"
10720 (match_operand:SI 1 "register_operand" "r")
10723 (match_operand:SI 2 "register_operand" "r")
10724 (match_operand:SI 3 "const_int_operand" "n")) 0))
10727 (label_ref (match_operand 4 "" ""))
10729 (clobber (reg:CC FLAGS_REG))]
10730 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10731 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10734 [(set (reg:CCC FLAGS_REG)
10742 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10743 (label_ref (match_dup 4))
10745 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10747 ;; Define combination compare-and-branch fp compare instructions to help
10750 (define_insn "*fp_jcc_1_387"
10752 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10753 [(match_operand 1 "register_operand" "f")
10754 (match_operand 2 "nonimmediate_operand" "fm")])
10755 (label_ref (match_operand 3 "" ""))
10757 (clobber (reg:CCFP FPSR_REG))
10758 (clobber (reg:CCFP FLAGS_REG))
10759 (clobber (match_scratch:HI 4 "=a"))]
10761 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10762 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10763 && SELECT_CC_MODE (GET_CODE (operands[0]),
10764 operands[1], operands[2]) == CCFPmode
10768 (define_insn "*fp_jcc_1r_387"
10770 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10771 [(match_operand 1 "register_operand" "f")
10772 (match_operand 2 "nonimmediate_operand" "fm")])
10774 (label_ref (match_operand 3 "" ""))))
10775 (clobber (reg:CCFP FPSR_REG))
10776 (clobber (reg:CCFP FLAGS_REG))
10777 (clobber (match_scratch:HI 4 "=a"))]
10779 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10780 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10781 && SELECT_CC_MODE (GET_CODE (operands[0]),
10782 operands[1], operands[2]) == CCFPmode
10786 (define_insn "*fp_jcc_2_387"
10788 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10789 [(match_operand 1 "register_operand" "f")
10790 (match_operand 2 "register_operand" "f")])
10791 (label_ref (match_operand 3 "" ""))
10793 (clobber (reg:CCFP FPSR_REG))
10794 (clobber (reg:CCFP FLAGS_REG))
10795 (clobber (match_scratch:HI 4 "=a"))]
10796 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10797 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10801 (define_insn "*fp_jcc_2r_387"
10803 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10804 [(match_operand 1 "register_operand" "f")
10805 (match_operand 2 "register_operand" "f")])
10807 (label_ref (match_operand 3 "" ""))))
10808 (clobber (reg:CCFP FPSR_REG))
10809 (clobber (reg:CCFP FLAGS_REG))
10810 (clobber (match_scratch:HI 4 "=a"))]
10811 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10812 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10816 (define_insn "*fp_jcc_3_387"
10818 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10819 [(match_operand 1 "register_operand" "f")
10820 (match_operand 2 "const0_operand" "")])
10821 (label_ref (match_operand 3 "" ""))
10823 (clobber (reg:CCFP FPSR_REG))
10824 (clobber (reg:CCFP FLAGS_REG))
10825 (clobber (match_scratch:HI 4 "=a"))]
10826 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10827 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10828 && SELECT_CC_MODE (GET_CODE (operands[0]),
10829 operands[1], operands[2]) == CCFPmode
10835 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10836 [(match_operand 1 "register_operand" "")
10837 (match_operand 2 "nonimmediate_operand" "")])
10838 (match_operand 3 "" "")
10839 (match_operand 4 "" "")))
10840 (clobber (reg:CCFP FPSR_REG))
10841 (clobber (reg:CCFP FLAGS_REG))]
10845 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10846 operands[3], operands[4], NULL_RTX, NULL_RTX);
10852 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10853 [(match_operand 1 "register_operand" "")
10854 (match_operand 2 "general_operand" "")])
10855 (match_operand 3 "" "")
10856 (match_operand 4 "" "")))
10857 (clobber (reg:CCFP FPSR_REG))
10858 (clobber (reg:CCFP FLAGS_REG))
10859 (clobber (match_scratch:HI 5 "=a"))]
10863 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10864 operands[3], operands[4], operands[5], NULL_RTX);
10868 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10869 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10870 ;; with a precedence over other operators and is always put in the first
10871 ;; place. Swap condition and operands to match ficom instruction.
10873 (define_insn "*fp_jcc_4_<mode>_387"
10876 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10877 [(match_operator 1 "float_operator"
10878 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10879 (match_operand 3 "register_operand" "f,f")])
10880 (label_ref (match_operand 4 "" ""))
10882 (clobber (reg:CCFP FPSR_REG))
10883 (clobber (reg:CCFP FLAGS_REG))
10884 (clobber (match_scratch:HI 5 "=a,a"))]
10885 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10886 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10887 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10888 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10895 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10896 [(match_operator 1 "float_operator"
10897 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10898 (match_operand 3 "register_operand" "")])
10899 (match_operand 4 "" "")
10900 (match_operand 5 "" "")))
10901 (clobber (reg:CCFP FPSR_REG))
10902 (clobber (reg:CCFP FLAGS_REG))
10903 (clobber (match_scratch:HI 6 "=a"))]
10907 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10909 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10910 operands[3], operands[7],
10911 operands[4], operands[5], operands[6], NULL_RTX);
10915 ;; %%% Kill this when reload knows how to do it.
10919 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10920 [(match_operator 1 "float_operator"
10921 [(match_operand:X87MODEI12 2 "register_operand" "")])
10922 (match_operand 3 "register_operand" "")])
10923 (match_operand 4 "" "")
10924 (match_operand 5 "" "")))
10925 (clobber (reg:CCFP FPSR_REG))
10926 (clobber (reg:CCFP FLAGS_REG))
10927 (clobber (match_scratch:HI 6 "=a"))]
10931 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10932 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10934 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10935 operands[3], operands[7],
10936 operands[4], operands[5], operands[6], operands[2]);
10940 ;; Unconditional and other jump instructions
10942 (define_insn "jump"
10944 (label_ref (match_operand 0 "" "")))]
10947 [(set_attr "type" "ibr")
10948 (set (attr "length")
10949 (if_then_else (and (ge (minus (match_dup 0) (pc))
10951 (lt (minus (match_dup 0) (pc))
10955 (set_attr "modrm" "0")])
10957 (define_expand "indirect_jump"
10958 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10962 (define_insn "*indirect_jump"
10963 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10966 [(set_attr "type" "ibr")
10967 (set_attr "length_immediate" "0")])
10969 (define_expand "tablejump"
10970 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10971 (use (label_ref (match_operand 1 "" "")))])]
10974 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10975 relative. Convert the relative address to an absolute address. */
10979 enum rtx_code code;
10981 /* We can't use @GOTOFF for text labels on VxWorks;
10982 see gotoff_operand. */
10983 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10987 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10989 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10993 op1 = pic_offset_table_rtx;
10998 op0 = pic_offset_table_rtx;
11002 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11007 (define_insn "*tablejump_1"
11008 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11009 (use (label_ref (match_operand 1 "" "")))]
11012 [(set_attr "type" "ibr")
11013 (set_attr "length_immediate" "0")])
11015 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11018 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11019 (set (match_operand:QI 1 "register_operand" "")
11020 (match_operator:QI 2 "ix86_comparison_operator"
11021 [(reg FLAGS_REG) (const_int 0)]))
11022 (set (match_operand 3 "q_regs_operand" "")
11023 (zero_extend (match_dup 1)))]
11024 "(peep2_reg_dead_p (3, operands[1])
11025 || operands_match_p (operands[1], operands[3]))
11026 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11027 [(set (match_dup 4) (match_dup 0))
11028 (set (strict_low_part (match_dup 5))
11031 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11032 operands[5] = gen_lowpart (QImode, operands[3]);
11033 ix86_expand_clear (operands[3]);
11036 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11039 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11040 (set (match_operand:QI 1 "register_operand" "")
11041 (match_operator:QI 2 "ix86_comparison_operator"
11042 [(reg FLAGS_REG) (const_int 0)]))
11043 (parallel [(set (match_operand 3 "q_regs_operand" "")
11044 (zero_extend (match_dup 1)))
11045 (clobber (reg:CC FLAGS_REG))])]
11046 "(peep2_reg_dead_p (3, operands[1])
11047 || operands_match_p (operands[1], operands[3]))
11048 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11049 [(set (match_dup 4) (match_dup 0))
11050 (set (strict_low_part (match_dup 5))
11053 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11054 operands[5] = gen_lowpart (QImode, operands[3]);
11055 ix86_expand_clear (operands[3]);
11058 ;; Call instructions.
11060 ;; The predicates normally associated with named expanders are not properly
11061 ;; checked for calls. This is a bug in the generic code, but it isn't that
11062 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11064 ;; P6 processors will jump to the address after the decrement when %esp
11065 ;; is used as a call operand, so they will execute return address as a code.
11066 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11068 ;; Call subroutine returning no value.
11070 (define_expand "call_pop"
11071 [(parallel [(call (match_operand:QI 0 "" "")
11072 (match_operand:SI 1 "" ""))
11073 (set (reg:SI SP_REG)
11074 (plus:SI (reg:SI SP_REG)
11075 (match_operand:SI 3 "" "")))])]
11078 ix86_expand_call (NULL, operands[0], operands[1],
11079 operands[2], operands[3], 0);
11083 (define_insn_and_split "*call_pop_0_vzeroupper"
11085 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11086 (match_operand:SI 1 "" ""))
11087 (set (reg:SI SP_REG)
11088 (plus:SI (reg:SI SP_REG)
11089 (match_operand:SI 2 "immediate_operand" "")))])
11090 (unspec [(match_operand 3 "const_int_operand" "")]
11091 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11092 "TARGET_VZEROUPPER && !TARGET_64BIT"
11094 "&& reload_completed"
11096 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11097 [(set_attr "type" "call")])
11099 (define_insn "*call_pop_0"
11100 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11101 (match_operand:SI 1 "" ""))
11102 (set (reg:SI SP_REG)
11103 (plus:SI (reg:SI SP_REG)
11104 (match_operand:SI 2 "immediate_operand" "")))]
11107 if (SIBLING_CALL_P (insn))
11110 return "call\t%P0";
11112 [(set_attr "type" "call")])
11114 (define_insn_and_split "*call_pop_1_vzeroupper"
11116 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11117 (match_operand:SI 1 "" ""))
11118 (set (reg:SI SP_REG)
11119 (plus:SI (reg:SI SP_REG)
11120 (match_operand:SI 2 "immediate_operand" "i")))])
11121 (unspec [(match_operand 3 "const_int_operand" "")]
11122 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11123 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11125 "&& reload_completed"
11127 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11128 [(set_attr "type" "call")])
11130 (define_insn "*call_pop_1"
11131 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11132 (match_operand:SI 1 "" ""))
11133 (set (reg:SI SP_REG)
11134 (plus:SI (reg:SI SP_REG)
11135 (match_operand:SI 2 "immediate_operand" "i")))]
11136 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11138 if (constant_call_address_operand (operands[0], Pmode))
11139 return "call\t%P0";
11140 return "call\t%A0";
11142 [(set_attr "type" "call")])
11144 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11146 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11147 (match_operand:SI 1 "" ""))
11148 (set (reg:SI SP_REG)
11149 (plus:SI (reg:SI SP_REG)
11150 (match_operand:SI 2 "immediate_operand" "i,i")))])
11151 (unspec [(match_operand 3 "const_int_operand" "")]
11152 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11153 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11155 "&& reload_completed"
11157 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11158 [(set_attr "type" "call")])
11160 (define_insn "*sibcall_pop_1"
11161 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11162 (match_operand:SI 1 "" ""))
11163 (set (reg:SI SP_REG)
11164 (plus:SI (reg:SI SP_REG)
11165 (match_operand:SI 2 "immediate_operand" "i,i")))]
11166 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11170 [(set_attr "type" "call")])
11172 (define_expand "call"
11173 [(call (match_operand:QI 0 "" "")
11174 (match_operand 1 "" ""))
11175 (use (match_operand 2 "" ""))]
11178 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11182 (define_expand "sibcall"
11183 [(call (match_operand:QI 0 "" "")
11184 (match_operand 1 "" ""))
11185 (use (match_operand 2 "" ""))]
11188 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11192 (define_insn_and_split "*call_0_vzeroupper"
11193 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11194 (match_operand 1 "" ""))
11195 (unspec [(match_operand 2 "const_int_operand" "")]
11196 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11197 "TARGET_VZEROUPPER"
11199 "&& reload_completed"
11201 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11202 [(set_attr "type" "call")])
11204 (define_insn "*call_0"
11205 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11206 (match_operand 1 "" ""))]
11208 { return ix86_output_call_insn (insn, operands[0], 0); }
11209 [(set_attr "type" "call")])
11211 (define_insn_and_split "*call_1_vzeroupper"
11212 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11213 (match_operand 1 "" ""))
11214 (unspec [(match_operand 2 "const_int_operand" "")]
11215 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11216 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11218 "&& reload_completed"
11220 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11221 [(set_attr "type" "call")])
11223 (define_insn "*call_1"
11224 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11225 (match_operand 1 "" ""))]
11226 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11227 { return ix86_output_call_insn (insn, operands[0], 0); }
11228 [(set_attr "type" "call")])
11230 (define_insn_and_split "*sibcall_1_vzeroupper"
11231 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11232 (match_operand 1 "" ""))
11233 (unspec [(match_operand 2 "const_int_operand" "")]
11234 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11235 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11237 "&& reload_completed"
11239 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11240 [(set_attr "type" "call")])
11242 (define_insn "*sibcall_1"
11243 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11244 (match_operand 1 "" ""))]
11245 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11246 { return ix86_output_call_insn (insn, operands[0], 0); }
11247 [(set_attr "type" "call")])
11249 (define_insn_and_split "*call_1_rex64_vzeroupper"
11250 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11251 (match_operand 1 "" ""))
11252 (unspec [(match_operand 2 "const_int_operand" "")]
11253 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11254 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11255 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11257 "&& reload_completed"
11259 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11260 [(set_attr "type" "call")])
11262 (define_insn "*call_1_rex64"
11263 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11264 (match_operand 1 "" ""))]
11265 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11266 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11267 { return ix86_output_call_insn (insn, operands[0], 0); }
11268 [(set_attr "type" "call")])
11270 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11272 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11273 (match_operand 1 "" ""))
11274 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11275 (clobber (reg:TI XMM6_REG))
11276 (clobber (reg:TI XMM7_REG))
11277 (clobber (reg:TI XMM8_REG))
11278 (clobber (reg:TI XMM9_REG))
11279 (clobber (reg:TI XMM10_REG))
11280 (clobber (reg:TI XMM11_REG))
11281 (clobber (reg:TI XMM12_REG))
11282 (clobber (reg:TI XMM13_REG))
11283 (clobber (reg:TI XMM14_REG))
11284 (clobber (reg:TI XMM15_REG))
11285 (clobber (reg:DI SI_REG))
11286 (clobber (reg:DI DI_REG))])
11287 (unspec [(match_operand 2 "const_int_operand" "")]
11288 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11289 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11291 "&& reload_completed"
11293 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11294 [(set_attr "type" "call")])
11296 (define_insn "*call_1_rex64_ms_sysv"
11297 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11298 (match_operand 1 "" ""))
11299 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11300 (clobber (reg:TI XMM6_REG))
11301 (clobber (reg:TI XMM7_REG))
11302 (clobber (reg:TI XMM8_REG))
11303 (clobber (reg:TI XMM9_REG))
11304 (clobber (reg:TI XMM10_REG))
11305 (clobber (reg:TI XMM11_REG))
11306 (clobber (reg:TI XMM12_REG))
11307 (clobber (reg:TI XMM13_REG))
11308 (clobber (reg:TI XMM14_REG))
11309 (clobber (reg:TI XMM15_REG))
11310 (clobber (reg:DI SI_REG))
11311 (clobber (reg:DI DI_REG))]
11312 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11313 { return ix86_output_call_insn (insn, operands[0], 0); }
11314 [(set_attr "type" "call")])
11316 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11317 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11318 (match_operand 1 "" ""))
11319 (unspec [(match_operand 2 "const_int_operand" "")]
11320 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11321 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11323 "&& reload_completed"
11325 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11326 [(set_attr "type" "call")])
11328 (define_insn "*call_1_rex64_large"
11329 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11330 (match_operand 1 "" ""))]
11331 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11332 { return ix86_output_call_insn (insn, operands[0], 0); }
11333 [(set_attr "type" "call")])
11335 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11336 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11337 (match_operand 1 "" ""))
11338 (unspec [(match_operand 2 "const_int_operand" "")]
11339 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11340 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11342 "&& reload_completed"
11344 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11345 [(set_attr "type" "call")])
11347 (define_insn "*sibcall_1_rex64"
11348 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11349 (match_operand 1 "" ""))]
11350 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11351 { return ix86_output_call_insn (insn, operands[0], 0); }
11352 [(set_attr "type" "call")])
11354 ;; Call subroutine, returning value in operand 0
11355 (define_expand "call_value_pop"
11356 [(parallel [(set (match_operand 0 "" "")
11357 (call (match_operand:QI 1 "" "")
11358 (match_operand:SI 2 "" "")))
11359 (set (reg:SI SP_REG)
11360 (plus:SI (reg:SI SP_REG)
11361 (match_operand:SI 4 "" "")))])]
11364 ix86_expand_call (operands[0], operands[1], operands[2],
11365 operands[3], operands[4], 0);
11369 (define_expand "call_value"
11370 [(set (match_operand 0 "" "")
11371 (call (match_operand:QI 1 "" "")
11372 (match_operand:SI 2 "" "")))
11373 (use (match_operand:SI 3 "" ""))]
11374 ;; Operand 3 is not used on the i386.
11377 ix86_expand_call (operands[0], operands[1], operands[2],
11378 operands[3], NULL, 0);
11382 (define_expand "sibcall_value"
11383 [(set (match_operand 0 "" "")
11384 (call (match_operand:QI 1 "" "")
11385 (match_operand:SI 2 "" "")))
11386 (use (match_operand:SI 3 "" ""))]
11387 ;; Operand 3 is not used on the i386.
11390 ix86_expand_call (operands[0], operands[1], operands[2],
11391 operands[3], NULL, 1);
11395 ;; Call subroutine returning any type.
11397 (define_expand "untyped_call"
11398 [(parallel [(call (match_operand 0 "" "")
11400 (match_operand 1 "" "")
11401 (match_operand 2 "" "")])]
11406 /* In order to give reg-stack an easier job in validating two
11407 coprocessor registers as containing a possible return value,
11408 simply pretend the untyped call returns a complex long double
11411 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11412 and should have the default ABI. */
11414 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11415 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11416 operands[0], const0_rtx,
11417 GEN_INT ((TARGET_64BIT
11418 ? (ix86_abi == SYSV_ABI
11419 ? X86_64_SSE_REGPARM_MAX
11420 : X86_64_MS_SSE_REGPARM_MAX)
11421 : X86_32_SSE_REGPARM_MAX)
11425 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11427 rtx set = XVECEXP (operands[2], 0, i);
11428 emit_move_insn (SET_DEST (set), SET_SRC (set));
11431 /* The optimizer does not know that the call sets the function value
11432 registers we stored in the result block. We avoid problems by
11433 claiming that all hard registers are used and clobbered at this
11435 emit_insn (gen_blockage ());
11440 ;; Prologue and epilogue instructions
11442 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11443 ;; all of memory. This blocks insns from being moved across this point.
11445 (define_insn "blockage"
11446 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11449 [(set_attr "length" "0")])
11451 ;; Do not schedule instructions accessing memory across this point.
11453 (define_expand "memory_blockage"
11454 [(set (match_dup 0)
11455 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11458 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11459 MEM_VOLATILE_P (operands[0]) = 1;
11462 (define_insn "*memory_blockage"
11463 [(set (match_operand:BLK 0 "" "")
11464 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11467 [(set_attr "length" "0")])
11469 ;; As USE insns aren't meaningful after reload, this is used instead
11470 ;; to prevent deleting instructions setting registers for PIC code
11471 (define_insn "prologue_use"
11472 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11475 [(set_attr "length" "0")])
11477 ;; Insn emitted into the body of a function to return from a function.
11478 ;; This is only done if the function's epilogue is known to be simple.
11479 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11481 (define_expand "return"
11483 "ix86_can_use_return_insn_p ()"
11485 if (crtl->args.pops_args)
11487 rtx popc = GEN_INT (crtl->args.pops_args);
11488 emit_jump_insn (gen_return_pop_internal (popc));
11493 (define_insn "return_internal"
11497 [(set_attr "length" "1")
11498 (set_attr "atom_unit" "jeu")
11499 (set_attr "length_immediate" "0")
11500 (set_attr "modrm" "0")])
11502 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11503 ;; instruction Athlon and K8 have.
11505 (define_insn "return_internal_long"
11507 (unspec [(const_int 0)] UNSPEC_REP)]
11510 [(set_attr "length" "2")
11511 (set_attr "atom_unit" "jeu")
11512 (set_attr "length_immediate" "0")
11513 (set_attr "prefix_rep" "1")
11514 (set_attr "modrm" "0")])
11516 (define_insn "return_pop_internal"
11518 (use (match_operand:SI 0 "const_int_operand" ""))]
11521 [(set_attr "length" "3")
11522 (set_attr "atom_unit" "jeu")
11523 (set_attr "length_immediate" "2")
11524 (set_attr "modrm" "0")])
11526 (define_insn "return_indirect_internal"
11528 (use (match_operand:SI 0 "register_operand" "r"))]
11531 [(set_attr "type" "ibr")
11532 (set_attr "length_immediate" "0")])
11538 [(set_attr "length" "1")
11539 (set_attr "length_immediate" "0")
11540 (set_attr "modrm" "0")])
11542 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11543 (define_insn "nops"
11544 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11548 int num = INTVAL (operands[0]);
11550 gcc_assert (num >= 1 && num <= 8);
11553 fputs ("\tnop\n", asm_out_file);
11557 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11558 (set_attr "length_immediate" "0")
11559 (set_attr "modrm" "0")])
11561 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11562 ;; branch prediction penalty for the third jump in a 16-byte
11566 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11569 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11570 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11572 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11573 The align insn is used to avoid 3 jump instructions in the row to improve
11574 branch prediction and the benefits hardly outweigh the cost of extra 8
11575 nops on the average inserted by full alignment pseudo operation. */
11579 [(set_attr "length" "16")])
11581 (define_expand "prologue"
11584 "ix86_expand_prologue (); DONE;")
11586 (define_insn "set_got"
11587 [(set (match_operand:SI 0 "register_operand" "=r")
11588 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11589 (clobber (reg:CC FLAGS_REG))]
11591 "* return output_set_got (operands[0], NULL_RTX);"
11592 [(set_attr "type" "multi")
11593 (set_attr "length" "12")])
11595 (define_insn "set_got_labelled"
11596 [(set (match_operand:SI 0 "register_operand" "=r")
11597 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11599 (clobber (reg:CC FLAGS_REG))]
11601 "* return output_set_got (operands[0], operands[1]);"
11602 [(set_attr "type" "multi")
11603 (set_attr "length" "12")])
11605 (define_insn "set_got_rex64"
11606 [(set (match_operand:DI 0 "register_operand" "=r")
11607 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11609 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11610 [(set_attr "type" "lea")
11611 (set_attr "length_address" "4")
11612 (set_attr "mode" "DI")])
11614 (define_insn "set_rip_rex64"
11615 [(set (match_operand:DI 0 "register_operand" "=r")
11616 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11618 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11619 [(set_attr "type" "lea")
11620 (set_attr "length_address" "4")
11621 (set_attr "mode" "DI")])
11623 (define_insn "set_got_offset_rex64"
11624 [(set (match_operand:DI 0 "register_operand" "=r")
11626 [(label_ref (match_operand 1 "" ""))]
11627 UNSPEC_SET_GOT_OFFSET))]
11629 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11630 [(set_attr "type" "imov")
11631 (set_attr "length_immediate" "0")
11632 (set_attr "length_address" "8")
11633 (set_attr "mode" "DI")])
11635 (define_expand "epilogue"
11638 "ix86_expand_epilogue (1); DONE;")
11640 (define_expand "sibcall_epilogue"
11643 "ix86_expand_epilogue (0); DONE;")
11645 (define_expand "eh_return"
11646 [(use (match_operand 0 "register_operand" ""))]
11649 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11651 /* Tricky bit: we write the address of the handler to which we will
11652 be returning into someone else's stack frame, one word below the
11653 stack address we wish to restore. */
11654 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11655 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11656 tmp = gen_rtx_MEM (Pmode, tmp);
11657 emit_move_insn (tmp, ra);
11659 emit_jump_insn (gen_eh_return_internal ());
11664 (define_insn_and_split "eh_return_internal"
11668 "epilogue_completed"
11670 "ix86_expand_epilogue (2); DONE;")
11672 (define_insn "leave"
11673 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11674 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11675 (clobber (mem:BLK (scratch)))]
11678 [(set_attr "type" "leave")])
11680 (define_insn "leave_rex64"
11681 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11682 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11683 (clobber (mem:BLK (scratch)))]
11686 [(set_attr "type" "leave")])
11688 ;; Handle -fsplit-stack.
11690 (define_expand "split_stack_prologue"
11694 ix86_expand_split_stack_prologue ();
11698 ;; In order to support the call/return predictor, we use a return
11699 ;; instruction which the middle-end doesn't see.
11700 (define_insn "split_stack_return"
11701 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11702 UNSPECV_SPLIT_STACK_RETURN)]
11705 if (operands[0] == const0_rtx)
11710 [(set_attr "atom_unit" "jeu")
11711 (set_attr "modrm" "0")
11712 (set (attr "length")
11713 (if_then_else (match_operand:SI 0 "const0_operand" "")
11716 (set (attr "length_immediate")
11717 (if_then_else (match_operand:SI 0 "const0_operand" "")
11721 ;; If there are operand 0 bytes available on the stack, jump to
11724 (define_expand "split_stack_space_check"
11725 [(set (pc) (if_then_else
11726 (ltu (minus (reg SP_REG)
11727 (match_operand 0 "register_operand" ""))
11728 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11729 (label_ref (match_operand 1 "" ""))
11733 rtx reg, size, limit;
11735 reg = gen_reg_rtx (Pmode);
11736 size = force_reg (Pmode, operands[0]);
11737 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11738 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11739 UNSPEC_STACK_CHECK);
11740 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11741 ix86_expand_branch (GEU, reg, limit, operands[1]);
11746 ;; Bit manipulation instructions.
11748 (define_expand "ffs<mode>2"
11749 [(set (match_dup 2) (const_int -1))
11750 (parallel [(set (reg:CCZ FLAGS_REG)
11752 (match_operand:SWI48 1 "nonimmediate_operand" "")
11754 (set (match_operand:SWI48 0 "register_operand" "")
11755 (ctz:SWI48 (match_dup 1)))])
11756 (set (match_dup 0) (if_then_else:SWI48
11757 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11760 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11761 (clobber (reg:CC FLAGS_REG))])]
11764 if (<MODE>mode == SImode && !TARGET_CMOVE)
11766 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11769 operands[2] = gen_reg_rtx (<MODE>mode);
11772 (define_insn_and_split "ffssi2_no_cmove"
11773 [(set (match_operand:SI 0 "register_operand" "=r")
11774 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11775 (clobber (match_scratch:SI 2 "=&q"))
11776 (clobber (reg:CC FLAGS_REG))]
11779 "&& reload_completed"
11780 [(parallel [(set (reg:CCZ FLAGS_REG)
11781 (compare:CCZ (match_dup 1) (const_int 0)))
11782 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11783 (set (strict_low_part (match_dup 3))
11784 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11785 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11786 (clobber (reg:CC FLAGS_REG))])
11787 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11788 (clobber (reg:CC FLAGS_REG))])
11789 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11790 (clobber (reg:CC FLAGS_REG))])]
11792 operands[3] = gen_lowpart (QImode, operands[2]);
11793 ix86_expand_clear (operands[2]);
11796 (define_insn "*ffs<mode>_1"
11797 [(set (reg:CCZ FLAGS_REG)
11798 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11800 (set (match_operand:SWI48 0 "register_operand" "=r")
11801 (ctz:SWI48 (match_dup 1)))]
11803 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11804 [(set_attr "type" "alu1")
11805 (set_attr "prefix_0f" "1")
11806 (set_attr "mode" "<MODE>")])
11808 (define_insn "ctz<mode>2"
11809 [(set (match_operand:SWI248 0 "register_operand" "=r")
11810 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11811 (clobber (reg:CC FLAGS_REG))]
11815 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11817 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11819 [(set_attr "type" "alu1")
11820 (set_attr "prefix_0f" "1")
11821 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11822 (set_attr "mode" "<MODE>")])
11824 (define_expand "clz<mode>2"
11826 [(set (match_operand:SWI248 0 "register_operand" "")
11829 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11830 (clobber (reg:CC FLAGS_REG))])
11832 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11833 (clobber (reg:CC FLAGS_REG))])]
11838 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11841 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11844 (define_insn "clz<mode>2_abm"
11845 [(set (match_operand:SWI248 0 "register_operand" "=r")
11846 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11847 (clobber (reg:CC FLAGS_REG))]
11848 "TARGET_ABM || TARGET_BMI"
11849 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11850 [(set_attr "prefix_rep" "1")
11851 (set_attr "type" "bitmanip")
11852 (set_attr "mode" "<MODE>")])
11854 ;; BMI instructions.
11855 (define_insn "*bmi_andn_<mode>"
11856 [(set (match_operand:SWI48 0 "register_operand" "=r")
11859 (match_operand:SWI48 1 "register_operand" "r"))
11860 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11861 (clobber (reg:CC FLAGS_REG))]
11863 "andn\t{%2, %1, %0|%0, %1, %2}"
11864 [(set_attr "type" "bitmanip")
11865 (set_attr "mode" "<MODE>")])
11867 (define_insn "bmi_bextr_<mode>"
11868 [(set (match_operand:SWI48 0 "register_operand" "=r")
11869 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11870 (match_operand:SWI48 2 "register_operand" "r")]
11872 (clobber (reg:CC FLAGS_REG))]
11874 "bextr\t{%2, %1, %0|%0, %1, %2}"
11875 [(set_attr "type" "bitmanip")
11876 (set_attr "mode" "<MODE>")])
11878 (define_insn "*bmi_blsi_<mode>"
11879 [(set (match_operand:SWI48 0 "register_operand" "=r")
11882 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11884 (clobber (reg:CC FLAGS_REG))]
11886 "blsi\t{%1, %0|%0, %1}"
11887 [(set_attr "type" "bitmanip")
11888 (set_attr "mode" "<MODE>")])
11890 (define_insn "*bmi_blsmsk_<mode>"
11891 [(set (match_operand:SWI48 0 "register_operand" "=r")
11894 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11897 (clobber (reg:CC FLAGS_REG))]
11899 "blsmsk\t{%1, %0|%0, %1}"
11900 [(set_attr "type" "bitmanip")
11901 (set_attr "mode" "<MODE>")])
11903 (define_insn "*bmi_blsr_<mode>"
11904 [(set (match_operand:SWI48 0 "register_operand" "=r")
11907 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11910 (clobber (reg:CC FLAGS_REG))]
11912 "blsr\t{%1, %0|%0, %1}"
11913 [(set_attr "type" "bitmanip")
11914 (set_attr "mode" "<MODE>")])
11916 ;; TBM instructions.
11917 (define_insn "tbm_bextri_<mode>"
11918 [(set (match_operand:SWI48 0 "register_operand" "=r")
11919 (zero_extract:SWI48
11920 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11921 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11922 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11923 (clobber (reg:CC FLAGS_REG))]
11926 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11927 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11929 [(set_attr "type" "bitmanip")
11930 (set_attr "mode" "<MODE>")])
11932 (define_insn "*tbm_blcfill_<mode>"
11933 [(set (match_operand:SWI48 0 "register_operand" "=r")
11936 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11939 (clobber (reg:CC FLAGS_REG))]
11941 "blcfill\t{%1, %0|%0, %1}"
11942 [(set_attr "type" "bitmanip")
11943 (set_attr "mode" "<MODE>")])
11945 (define_insn "*tbm_blci_<mode>"
11946 [(set (match_operand:SWI48 0 "register_operand" "=r")
11950 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11953 (clobber (reg:CC FLAGS_REG))]
11955 "blci\t{%1, %0|%0, %1}"
11956 [(set_attr "type" "bitmanip")
11957 (set_attr "mode" "<MODE>")])
11959 (define_insn "*tbm_blcic_<mode>"
11960 [(set (match_operand:SWI48 0 "register_operand" "=r")
11963 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11967 (clobber (reg:CC FLAGS_REG))]
11969 "blcic\t{%1, %0|%0, %1}"
11970 [(set_attr "type" "bitmanip")
11971 (set_attr "mode" "<MODE>")])
11973 (define_insn "*tbm_blcmsk_<mode>"
11974 [(set (match_operand:SWI48 0 "register_operand" "=r")
11977 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11980 (clobber (reg:CC FLAGS_REG))]
11982 "blcmsk\t{%1, %0|%0, %1}"
11983 [(set_attr "type" "bitmanip")
11984 (set_attr "mode" "<MODE>")])
11986 (define_insn "*tbm_blcs_<mode>"
11987 [(set (match_operand:SWI48 0 "register_operand" "=r")
11990 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11993 (clobber (reg:CC FLAGS_REG))]
11995 "blcs\t{%1, %0|%0, %1}"
11996 [(set_attr "type" "bitmanip")
11997 (set_attr "mode" "<MODE>")])
11999 (define_insn "*tbm_blsfill_<mode>"
12000 [(set (match_operand:SWI48 0 "register_operand" "=r")
12003 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12006 (clobber (reg:CC FLAGS_REG))]
12008 "blsfill\t{%1, %0|%0, %1}"
12009 [(set_attr "type" "bitmanip")
12010 (set_attr "mode" "<MODE>")])
12012 (define_insn "*tbm_blsic_<mode>"
12013 [(set (match_operand:SWI48 0 "register_operand" "=r")
12016 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12020 (clobber (reg:CC FLAGS_REG))]
12022 "blsic\t{%1, %0|%0, %1}"
12023 [(set_attr "type" "bitmanip")
12024 (set_attr "mode" "<MODE>")])
12026 (define_insn "*tbm_t1mskc_<mode>"
12027 [(set (match_operand:SWI48 0 "register_operand" "=r")
12030 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12034 (clobber (reg:CC FLAGS_REG))]
12036 "t1mskc\t{%1, %0|%0, %1}"
12037 [(set_attr "type" "bitmanip")
12038 (set_attr "mode" "<MODE>")])
12040 (define_insn "*tbm_tzmsk_<mode>"
12041 [(set (match_operand:SWI48 0 "register_operand" "=r")
12044 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12048 (clobber (reg:CC FLAGS_REG))]
12050 "tzmsk\t{%1, %0|%0, %1}"
12051 [(set_attr "type" "bitmanip")
12052 (set_attr "mode" "<MODE>")])
12054 (define_insn "bsr_rex64"
12055 [(set (match_operand:DI 0 "register_operand" "=r")
12056 (minus:DI (const_int 63)
12057 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12058 (clobber (reg:CC FLAGS_REG))]
12060 "bsr{q}\t{%1, %0|%0, %1}"
12061 [(set_attr "type" "alu1")
12062 (set_attr "prefix_0f" "1")
12063 (set_attr "mode" "DI")])
12066 [(set (match_operand:SI 0 "register_operand" "=r")
12067 (minus:SI (const_int 31)
12068 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12069 (clobber (reg:CC FLAGS_REG))]
12071 "bsr{l}\t{%1, %0|%0, %1}"
12072 [(set_attr "type" "alu1")
12073 (set_attr "prefix_0f" "1")
12074 (set_attr "mode" "SI")])
12076 (define_insn "*bsrhi"
12077 [(set (match_operand:HI 0 "register_operand" "=r")
12078 (minus:HI (const_int 15)
12079 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12080 (clobber (reg:CC FLAGS_REG))]
12082 "bsr{w}\t{%1, %0|%0, %1}"
12083 [(set_attr "type" "alu1")
12084 (set_attr "prefix_0f" "1")
12085 (set_attr "mode" "HI")])
12087 (define_insn "popcount<mode>2"
12088 [(set (match_operand:SWI248 0 "register_operand" "=r")
12090 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12091 (clobber (reg:CC FLAGS_REG))]
12095 return "popcnt\t{%1, %0|%0, %1}";
12097 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12100 [(set_attr "prefix_rep" "1")
12101 (set_attr "type" "bitmanip")
12102 (set_attr "mode" "<MODE>")])
12104 (define_insn "*popcount<mode>2_cmp"
12105 [(set (reg FLAGS_REG)
12108 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12110 (set (match_operand:SWI248 0 "register_operand" "=r")
12111 (popcount:SWI248 (match_dup 1)))]
12112 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12115 return "popcnt\t{%1, %0|%0, %1}";
12117 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12120 [(set_attr "prefix_rep" "1")
12121 (set_attr "type" "bitmanip")
12122 (set_attr "mode" "<MODE>")])
12124 (define_insn "*popcountsi2_cmp_zext"
12125 [(set (reg FLAGS_REG)
12127 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12129 (set (match_operand:DI 0 "register_operand" "=r")
12130 (zero_extend:DI(popcount:SI (match_dup 1))))]
12131 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12134 return "popcnt\t{%1, %0|%0, %1}";
12136 return "popcnt{l}\t{%1, %0|%0, %1}";
12139 [(set_attr "prefix_rep" "1")
12140 (set_attr "type" "bitmanip")
12141 (set_attr "mode" "SI")])
12143 (define_expand "bswap<mode>2"
12144 [(set (match_operand:SWI48 0 "register_operand" "")
12145 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12148 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12150 rtx x = operands[0];
12152 emit_move_insn (x, operands[1]);
12153 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12154 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12155 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12160 (define_insn "*bswap<mode>2_movbe"
12161 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12162 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12164 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12167 movbe\t{%1, %0|%0, %1}
12168 movbe\t{%1, %0|%0, %1}"
12169 [(set_attr "type" "bitmanip,imov,imov")
12170 (set_attr "modrm" "0,1,1")
12171 (set_attr "prefix_0f" "*,1,1")
12172 (set_attr "prefix_extra" "*,1,1")
12173 (set_attr "mode" "<MODE>")])
12175 (define_insn "*bswap<mode>2_1"
12176 [(set (match_operand:SWI48 0 "register_operand" "=r")
12177 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12180 [(set_attr "type" "bitmanip")
12181 (set_attr "modrm" "0")
12182 (set_attr "mode" "<MODE>")])
12184 (define_insn "*bswaphi_lowpart_1"
12185 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12186 (bswap:HI (match_dup 0)))
12187 (clobber (reg:CC FLAGS_REG))]
12188 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12190 xchg{b}\t{%h0, %b0|%b0, %h0}
12191 rol{w}\t{$8, %0|%0, 8}"
12192 [(set_attr "length" "2,4")
12193 (set_attr "mode" "QI,HI")])
12195 (define_insn "bswaphi_lowpart"
12196 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12197 (bswap:HI (match_dup 0)))
12198 (clobber (reg:CC FLAGS_REG))]
12200 "rol{w}\t{$8, %0|%0, 8}"
12201 [(set_attr "length" "4")
12202 (set_attr "mode" "HI")])
12204 (define_expand "paritydi2"
12205 [(set (match_operand:DI 0 "register_operand" "")
12206 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12209 rtx scratch = gen_reg_rtx (QImode);
12212 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12213 NULL_RTX, operands[1]));
12215 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12216 gen_rtx_REG (CCmode, FLAGS_REG),
12218 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12221 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12224 rtx tmp = gen_reg_rtx (SImode);
12226 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12227 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12232 (define_expand "paritysi2"
12233 [(set (match_operand:SI 0 "register_operand" "")
12234 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12237 rtx scratch = gen_reg_rtx (QImode);
12240 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12242 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12243 gen_rtx_REG (CCmode, FLAGS_REG),
12245 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12247 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12251 (define_insn_and_split "paritydi2_cmp"
12252 [(set (reg:CC FLAGS_REG)
12253 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12255 (clobber (match_scratch:DI 0 "=r"))
12256 (clobber (match_scratch:SI 1 "=&r"))
12257 (clobber (match_scratch:HI 2 "=Q"))]
12260 "&& reload_completed"
12262 [(set (match_dup 1)
12263 (xor:SI (match_dup 1) (match_dup 4)))
12264 (clobber (reg:CC FLAGS_REG))])
12266 [(set (reg:CC FLAGS_REG)
12267 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12268 (clobber (match_dup 1))
12269 (clobber (match_dup 2))])]
12271 operands[4] = gen_lowpart (SImode, operands[3]);
12275 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12276 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12279 operands[1] = gen_highpart (SImode, operands[3]);
12282 (define_insn_and_split "paritysi2_cmp"
12283 [(set (reg:CC FLAGS_REG)
12284 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12286 (clobber (match_scratch:SI 0 "=r"))
12287 (clobber (match_scratch:HI 1 "=&Q"))]
12290 "&& reload_completed"
12292 [(set (match_dup 1)
12293 (xor:HI (match_dup 1) (match_dup 3)))
12294 (clobber (reg:CC FLAGS_REG))])
12296 [(set (reg:CC FLAGS_REG)
12297 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12298 (clobber (match_dup 1))])]
12300 operands[3] = gen_lowpart (HImode, operands[2]);
12302 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12303 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12306 (define_insn "*parityhi2_cmp"
12307 [(set (reg:CC FLAGS_REG)
12308 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12310 (clobber (match_scratch:HI 0 "=Q"))]
12312 "xor{b}\t{%h0, %b0|%b0, %h0}"
12313 [(set_attr "length" "2")
12314 (set_attr "mode" "HI")])
12316 ;; Thread-local storage patterns for ELF.
12318 ;; Note that these code sequences must appear exactly as shown
12319 ;; in order to allow linker relaxation.
12321 (define_insn "*tls_global_dynamic_32_gnu"
12322 [(set (match_operand:SI 0 "register_operand" "=a")
12323 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12324 (match_operand:SI 2 "tls_symbolic_operand" "")
12325 (match_operand:SI 3 "call_insn_operand" "")]
12327 (clobber (match_scratch:SI 4 "=d"))
12328 (clobber (match_scratch:SI 5 "=c"))
12329 (clobber (reg:CC FLAGS_REG))]
12330 "!TARGET_64BIT && TARGET_GNU_TLS"
12331 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12332 [(set_attr "type" "multi")
12333 (set_attr "length" "12")])
12335 (define_expand "tls_global_dynamic_32"
12336 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12338 [(match_operand:SI 2 "register_operand" "")
12339 (match_operand:SI 1 "tls_symbolic_operand" "")
12340 (match_operand:SI 3 "call_insn_operand" "")]
12342 (clobber (match_scratch:SI 4 ""))
12343 (clobber (match_scratch:SI 5 ""))
12344 (clobber (reg:CC FLAGS_REG))])])
12346 (define_insn "*tls_global_dynamic_64"
12347 [(set (match_operand:DI 0 "register_operand" "=a")
12348 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12349 (match_operand:DI 3 "" "")))
12350 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12353 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12354 [(set_attr "type" "multi")
12355 (set_attr "length" "16")])
12357 (define_expand "tls_global_dynamic_64"
12358 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12360 (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12362 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12365 (define_insn "*tls_local_dynamic_base_32_gnu"
12366 [(set (match_operand:SI 0 "register_operand" "=a")
12367 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12368 (match_operand:SI 2 "call_insn_operand" "")]
12369 UNSPEC_TLS_LD_BASE))
12370 (clobber (match_scratch:SI 3 "=d"))
12371 (clobber (match_scratch:SI 4 "=c"))
12372 (clobber (reg:CC FLAGS_REG))]
12373 "!TARGET_64BIT && TARGET_GNU_TLS"
12374 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12375 [(set_attr "type" "multi")
12376 (set_attr "length" "11")])
12378 (define_expand "tls_local_dynamic_base_32"
12379 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12380 (unspec:SI [(match_operand:SI 1 "register_operand" "")
12381 (match_operand:SI 2 "call_insn_operand" "")]
12382 UNSPEC_TLS_LD_BASE))
12383 (clobber (match_scratch:SI 3 ""))
12384 (clobber (match_scratch:SI 4 ""))
12385 (clobber (reg:CC FLAGS_REG))])])
12387 (define_insn "*tls_local_dynamic_base_64"
12388 [(set (match_operand:DI 0 "register_operand" "=a")
12389 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12390 (match_operand:DI 2 "" "")))
12391 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12393 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12394 [(set_attr "type" "multi")
12395 (set_attr "length" "12")])
12397 (define_expand "tls_local_dynamic_base_64"
12398 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12400 (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12402 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12404 ;; Local dynamic of a single variable is a lose. Show combine how
12405 ;; to convert that back to global dynamic.
12407 (define_insn_and_split "*tls_local_dynamic_32_once"
12408 [(set (match_operand:SI 0 "register_operand" "=a")
12409 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12410 (match_operand:SI 2 "call_insn_operand" "")]
12411 UNSPEC_TLS_LD_BASE)
12412 (const:SI (unspec:SI
12413 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12415 (clobber (match_scratch:SI 4 "=d"))
12416 (clobber (match_scratch:SI 5 "=c"))
12417 (clobber (reg:CC FLAGS_REG))]
12421 [(parallel [(set (match_dup 0)
12422 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12424 (clobber (match_dup 4))
12425 (clobber (match_dup 5))
12426 (clobber (reg:CC FLAGS_REG))])])
12428 ;; Segment register for the thread base ptr load
12429 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12431 ;; Load and add the thread base pointer from %gs:0.
12432 (define_insn "*load_tp_<mode>"
12433 [(set (match_operand:P 0 "register_operand" "=r")
12434 (unspec:P [(const_int 0)] UNSPEC_TP))]
12436 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12437 [(set_attr "type" "imov")
12438 (set_attr "modrm" "0")
12439 (set_attr "length" "7")
12440 (set_attr "memory" "load")
12441 (set_attr "imm_disp" "false")])
12443 (define_insn "*add_tp_<mode>"
12444 [(set (match_operand:P 0 "register_operand" "=r")
12445 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12446 (match_operand:P 1 "register_operand" "0")))
12447 (clobber (reg:CC FLAGS_REG))]
12449 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12450 [(set_attr "type" "alu")
12451 (set_attr "modrm" "0")
12452 (set_attr "length" "7")
12453 (set_attr "memory" "load")
12454 (set_attr "imm_disp" "false")])
12456 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12457 ;; %rax as destination of the initial executable code sequence.
12458 (define_insn "tls_initial_exec_64_sun"
12459 [(set (match_operand:DI 0 "register_operand" "=a")
12461 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12462 UNSPEC_TLS_IE_SUN))
12463 (clobber (reg:CC FLAGS_REG))]
12464 "TARGET_64BIT && TARGET_SUN_TLS"
12465 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12466 [(set_attr "type" "multi")])
12468 ;; GNU2 TLS patterns can be split.
12470 (define_expand "tls_dynamic_gnu2_32"
12471 [(set (match_dup 3)
12472 (plus:SI (match_operand:SI 2 "register_operand" "")
12474 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12477 [(set (match_operand:SI 0 "register_operand" "")
12478 (unspec:SI [(match_dup 1) (match_dup 3)
12479 (match_dup 2) (reg:SI SP_REG)]
12481 (clobber (reg:CC FLAGS_REG))])]
12482 "!TARGET_64BIT && TARGET_GNU2_TLS"
12484 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12485 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12488 (define_insn "*tls_dynamic_lea_32"
12489 [(set (match_operand:SI 0 "register_operand" "=r")
12490 (plus:SI (match_operand:SI 1 "register_operand" "b")
12492 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12493 UNSPEC_TLSDESC))))]
12494 "!TARGET_64BIT && TARGET_GNU2_TLS"
12495 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12496 [(set_attr "type" "lea")
12497 (set_attr "mode" "SI")
12498 (set_attr "length" "6")
12499 (set_attr "length_address" "4")])
12501 (define_insn "*tls_dynamic_call_32"
12502 [(set (match_operand:SI 0 "register_operand" "=a")
12503 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12504 (match_operand:SI 2 "register_operand" "0")
12505 ;; we have to make sure %ebx still points to the GOT
12506 (match_operand:SI 3 "register_operand" "b")
12509 (clobber (reg:CC FLAGS_REG))]
12510 "!TARGET_64BIT && TARGET_GNU2_TLS"
12511 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12512 [(set_attr "type" "call")
12513 (set_attr "length" "2")
12514 (set_attr "length_address" "0")])
12516 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12517 [(set (match_operand:SI 0 "register_operand" "=&a")
12519 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12520 (match_operand:SI 4 "" "")
12521 (match_operand:SI 2 "register_operand" "b")
12524 (const:SI (unspec:SI
12525 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12527 (clobber (reg:CC FLAGS_REG))]
12528 "!TARGET_64BIT && TARGET_GNU2_TLS"
12531 [(set (match_dup 0) (match_dup 5))]
12533 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12534 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12537 (define_expand "tls_dynamic_gnu2_64"
12538 [(set (match_dup 2)
12539 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12542 [(set (match_operand:DI 0 "register_operand" "")
12543 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12545 (clobber (reg:CC FLAGS_REG))])]
12546 "TARGET_64BIT && TARGET_GNU2_TLS"
12548 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12549 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12552 (define_insn "*tls_dynamic_lea_64"
12553 [(set (match_operand:DI 0 "register_operand" "=r")
12554 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12556 "TARGET_64BIT && TARGET_GNU2_TLS"
12557 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12558 [(set_attr "type" "lea")
12559 (set_attr "mode" "DI")
12560 (set_attr "length" "7")
12561 (set_attr "length_address" "4")])
12563 (define_insn "*tls_dynamic_call_64"
12564 [(set (match_operand:DI 0 "register_operand" "=a")
12565 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12566 (match_operand:DI 2 "register_operand" "0")
12569 (clobber (reg:CC FLAGS_REG))]
12570 "TARGET_64BIT && TARGET_GNU2_TLS"
12571 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12572 [(set_attr "type" "call")
12573 (set_attr "length" "2")
12574 (set_attr "length_address" "0")])
12576 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12577 [(set (match_operand:DI 0 "register_operand" "=&a")
12579 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12580 (match_operand:DI 3 "" "")
12583 (const:DI (unspec:DI
12584 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12586 (clobber (reg:CC FLAGS_REG))]
12587 "TARGET_64BIT && TARGET_GNU2_TLS"
12590 [(set (match_dup 0) (match_dup 4))]
12592 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12593 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12596 ;; These patterns match the binary 387 instructions for addM3, subM3,
12597 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12598 ;; SFmode. The first is the normal insn, the second the same insn but
12599 ;; with one operand a conversion, and the third the same insn but with
12600 ;; the other operand a conversion. The conversion may be SFmode or
12601 ;; SImode if the target mode DFmode, but only SImode if the target mode
12604 ;; Gcc is slightly more smart about handling normal two address instructions
12605 ;; so use special patterns for add and mull.
12607 (define_insn "*fop_<mode>_comm_mixed"
12608 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12609 (match_operator:MODEF 3 "binary_fp_operator"
12610 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12611 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12612 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12613 && COMMUTATIVE_ARITH_P (operands[3])
12614 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12615 "* return output_387_binary_op (insn, operands);"
12616 [(set (attr "type")
12617 (if_then_else (eq_attr "alternative" "1,2")
12618 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12619 (const_string "ssemul")
12620 (const_string "sseadd"))
12621 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12622 (const_string "fmul")
12623 (const_string "fop"))))
12624 (set_attr "isa" "base,noavx,avx")
12625 (set_attr "prefix" "orig,orig,vex")
12626 (set_attr "mode" "<MODE>")])
12628 (define_insn "*fop_<mode>_comm_sse"
12629 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12630 (match_operator:MODEF 3 "binary_fp_operator"
12631 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12632 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12633 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12634 && COMMUTATIVE_ARITH_P (operands[3])
12635 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12636 "* return output_387_binary_op (insn, operands);"
12637 [(set (attr "type")
12638 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12639 (const_string "ssemul")
12640 (const_string "sseadd")))
12641 (set_attr "isa" "noavx,avx")
12642 (set_attr "prefix" "orig,vex")
12643 (set_attr "mode" "<MODE>")])
12645 (define_insn "*fop_<mode>_comm_i387"
12646 [(set (match_operand:MODEF 0 "register_operand" "=f")
12647 (match_operator:MODEF 3 "binary_fp_operator"
12648 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12649 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12650 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12651 && COMMUTATIVE_ARITH_P (operands[3])
12652 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12653 "* return output_387_binary_op (insn, operands);"
12654 [(set (attr "type")
12655 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12656 (const_string "fmul")
12657 (const_string "fop")))
12658 (set_attr "mode" "<MODE>")])
12660 (define_insn "*fop_<mode>_1_mixed"
12661 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12662 (match_operator:MODEF 3 "binary_fp_operator"
12663 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12664 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12665 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12666 && !COMMUTATIVE_ARITH_P (operands[3])
12667 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12668 "* return output_387_binary_op (insn, operands);"
12669 [(set (attr "type")
12670 (cond [(and (eq_attr "alternative" "2,3")
12671 (match_operand:MODEF 3 "mult_operator" ""))
12672 (const_string "ssemul")
12673 (and (eq_attr "alternative" "2,3")
12674 (match_operand:MODEF 3 "div_operator" ""))
12675 (const_string "ssediv")
12676 (eq_attr "alternative" "2,3")
12677 (const_string "sseadd")
12678 (match_operand:MODEF 3 "mult_operator" "")
12679 (const_string "fmul")
12680 (match_operand:MODEF 3 "div_operator" "")
12681 (const_string "fdiv")
12683 (const_string "fop")))
12684 (set_attr "isa" "base,base,noavx,avx")
12685 (set_attr "prefix" "orig,orig,orig,vex")
12686 (set_attr "mode" "<MODE>")])
12688 (define_insn "*rcpsf2_sse"
12689 [(set (match_operand:SF 0 "register_operand" "=x")
12690 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12693 "%vrcpss\t{%1, %d0|%d0, %1}"
12694 [(set_attr "type" "sse")
12695 (set_attr "atom_sse_attr" "rcp")
12696 (set_attr "prefix" "maybe_vex")
12697 (set_attr "mode" "SF")])
12699 (define_insn "*fop_<mode>_1_sse"
12700 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12701 (match_operator:MODEF 3 "binary_fp_operator"
12702 [(match_operand:MODEF 1 "register_operand" "0,x")
12703 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12704 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12705 && !COMMUTATIVE_ARITH_P (operands[3])"
12706 "* return output_387_binary_op (insn, operands);"
12707 [(set (attr "type")
12708 (cond [(match_operand:MODEF 3 "mult_operator" "")
12709 (const_string "ssemul")
12710 (match_operand:MODEF 3 "div_operator" "")
12711 (const_string "ssediv")
12713 (const_string "sseadd")))
12714 (set_attr "isa" "noavx,avx")
12715 (set_attr "prefix" "orig,vex")
12716 (set_attr "mode" "<MODE>")])
12718 ;; This pattern is not fully shadowed by the pattern above.
12719 (define_insn "*fop_<mode>_1_i387"
12720 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12721 (match_operator:MODEF 3 "binary_fp_operator"
12722 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12723 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12724 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12725 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12726 && !COMMUTATIVE_ARITH_P (operands[3])
12727 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12728 "* return output_387_binary_op (insn, operands);"
12729 [(set (attr "type")
12730 (cond [(match_operand:MODEF 3 "mult_operator" "")
12731 (const_string "fmul")
12732 (match_operand:MODEF 3 "div_operator" "")
12733 (const_string "fdiv")
12735 (const_string "fop")))
12736 (set_attr "mode" "<MODE>")])
12738 ;; ??? Add SSE splitters for these!
12739 (define_insn "*fop_<MODEF:mode>_2_i387"
12740 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12741 (match_operator:MODEF 3 "binary_fp_operator"
12743 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12744 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12745 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12746 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12747 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12748 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12749 [(set (attr "type")
12750 (cond [(match_operand:MODEF 3 "mult_operator" "")
12751 (const_string "fmul")
12752 (match_operand:MODEF 3 "div_operator" "")
12753 (const_string "fdiv")
12755 (const_string "fop")))
12756 (set_attr "fp_int_src" "true")
12757 (set_attr "mode" "<X87MODEI12:MODE>")])
12759 (define_insn "*fop_<MODEF:mode>_3_i387"
12760 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12761 (match_operator:MODEF 3 "binary_fp_operator"
12762 [(match_operand:MODEF 1 "register_operand" "0,0")
12764 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12765 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12766 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12767 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12768 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12769 [(set (attr "type")
12770 (cond [(match_operand:MODEF 3 "mult_operator" "")
12771 (const_string "fmul")
12772 (match_operand:MODEF 3 "div_operator" "")
12773 (const_string "fdiv")
12775 (const_string "fop")))
12776 (set_attr "fp_int_src" "true")
12777 (set_attr "mode" "<MODE>")])
12779 (define_insn "*fop_df_4_i387"
12780 [(set (match_operand:DF 0 "register_operand" "=f,f")
12781 (match_operator:DF 3 "binary_fp_operator"
12783 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12784 (match_operand:DF 2 "register_operand" "0,f")]))]
12785 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12786 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12787 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12788 "* return output_387_binary_op (insn, operands);"
12789 [(set (attr "type")
12790 (cond [(match_operand:DF 3 "mult_operator" "")
12791 (const_string "fmul")
12792 (match_operand:DF 3 "div_operator" "")
12793 (const_string "fdiv")
12795 (const_string "fop")))
12796 (set_attr "mode" "SF")])
12798 (define_insn "*fop_df_5_i387"
12799 [(set (match_operand:DF 0 "register_operand" "=f,f")
12800 (match_operator:DF 3 "binary_fp_operator"
12801 [(match_operand:DF 1 "register_operand" "0,f")
12803 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12804 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12805 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12806 "* return output_387_binary_op (insn, operands);"
12807 [(set (attr "type")
12808 (cond [(match_operand:DF 3 "mult_operator" "")
12809 (const_string "fmul")
12810 (match_operand:DF 3 "div_operator" "")
12811 (const_string "fdiv")
12813 (const_string "fop")))
12814 (set_attr "mode" "SF")])
12816 (define_insn "*fop_df_6_i387"
12817 [(set (match_operand:DF 0 "register_operand" "=f,f")
12818 (match_operator:DF 3 "binary_fp_operator"
12820 (match_operand:SF 1 "register_operand" "0,f"))
12822 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12823 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12824 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12825 "* return output_387_binary_op (insn, operands);"
12826 [(set (attr "type")
12827 (cond [(match_operand:DF 3 "mult_operator" "")
12828 (const_string "fmul")
12829 (match_operand:DF 3 "div_operator" "")
12830 (const_string "fdiv")
12832 (const_string "fop")))
12833 (set_attr "mode" "SF")])
12835 (define_insn "*fop_xf_comm_i387"
12836 [(set (match_operand:XF 0 "register_operand" "=f")
12837 (match_operator:XF 3 "binary_fp_operator"
12838 [(match_operand:XF 1 "register_operand" "%0")
12839 (match_operand:XF 2 "register_operand" "f")]))]
12841 && COMMUTATIVE_ARITH_P (operands[3])"
12842 "* return output_387_binary_op (insn, operands);"
12843 [(set (attr "type")
12844 (if_then_else (match_operand:XF 3 "mult_operator" "")
12845 (const_string "fmul")
12846 (const_string "fop")))
12847 (set_attr "mode" "XF")])
12849 (define_insn "*fop_xf_1_i387"
12850 [(set (match_operand:XF 0 "register_operand" "=f,f")
12851 (match_operator:XF 3 "binary_fp_operator"
12852 [(match_operand:XF 1 "register_operand" "0,f")
12853 (match_operand:XF 2 "register_operand" "f,0")]))]
12855 && !COMMUTATIVE_ARITH_P (operands[3])"
12856 "* return output_387_binary_op (insn, operands);"
12857 [(set (attr "type")
12858 (cond [(match_operand:XF 3 "mult_operator" "")
12859 (const_string "fmul")
12860 (match_operand:XF 3 "div_operator" "")
12861 (const_string "fdiv")
12863 (const_string "fop")))
12864 (set_attr "mode" "XF")])
12866 (define_insn "*fop_xf_2_i387"
12867 [(set (match_operand:XF 0 "register_operand" "=f,f")
12868 (match_operator:XF 3 "binary_fp_operator"
12870 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12871 (match_operand:XF 2 "register_operand" "0,0")]))]
12872 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12873 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12874 [(set (attr "type")
12875 (cond [(match_operand:XF 3 "mult_operator" "")
12876 (const_string "fmul")
12877 (match_operand:XF 3 "div_operator" "")
12878 (const_string "fdiv")
12880 (const_string "fop")))
12881 (set_attr "fp_int_src" "true")
12882 (set_attr "mode" "<MODE>")])
12884 (define_insn "*fop_xf_3_i387"
12885 [(set (match_operand:XF 0 "register_operand" "=f,f")
12886 (match_operator:XF 3 "binary_fp_operator"
12887 [(match_operand:XF 1 "register_operand" "0,0")
12889 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12890 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12891 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12892 [(set (attr "type")
12893 (cond [(match_operand:XF 3 "mult_operator" "")
12894 (const_string "fmul")
12895 (match_operand:XF 3 "div_operator" "")
12896 (const_string "fdiv")
12898 (const_string "fop")))
12899 (set_attr "fp_int_src" "true")
12900 (set_attr "mode" "<MODE>")])
12902 (define_insn "*fop_xf_4_i387"
12903 [(set (match_operand:XF 0 "register_operand" "=f,f")
12904 (match_operator:XF 3 "binary_fp_operator"
12906 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12907 (match_operand:XF 2 "register_operand" "0,f")]))]
12909 "* return output_387_binary_op (insn, operands);"
12910 [(set (attr "type")
12911 (cond [(match_operand:XF 3 "mult_operator" "")
12912 (const_string "fmul")
12913 (match_operand:XF 3 "div_operator" "")
12914 (const_string "fdiv")
12916 (const_string "fop")))
12917 (set_attr "mode" "<MODE>")])
12919 (define_insn "*fop_xf_5_i387"
12920 [(set (match_operand:XF 0 "register_operand" "=f,f")
12921 (match_operator:XF 3 "binary_fp_operator"
12922 [(match_operand:XF 1 "register_operand" "0,f")
12924 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12926 "* return output_387_binary_op (insn, operands);"
12927 [(set (attr "type")
12928 (cond [(match_operand:XF 3 "mult_operator" "")
12929 (const_string "fmul")
12930 (match_operand:XF 3 "div_operator" "")
12931 (const_string "fdiv")
12933 (const_string "fop")))
12934 (set_attr "mode" "<MODE>")])
12936 (define_insn "*fop_xf_6_i387"
12937 [(set (match_operand:XF 0 "register_operand" "=f,f")
12938 (match_operator:XF 3 "binary_fp_operator"
12940 (match_operand:MODEF 1 "register_operand" "0,f"))
12942 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12944 "* return output_387_binary_op (insn, operands);"
12945 [(set (attr "type")
12946 (cond [(match_operand:XF 3 "mult_operator" "")
12947 (const_string "fmul")
12948 (match_operand:XF 3 "div_operator" "")
12949 (const_string "fdiv")
12951 (const_string "fop")))
12952 (set_attr "mode" "<MODE>")])
12955 [(set (match_operand 0 "register_operand" "")
12956 (match_operator 3 "binary_fp_operator"
12957 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12958 (match_operand 2 "register_operand" "")]))]
12960 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12961 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12964 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12965 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12966 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12967 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12968 GET_MODE (operands[3]),
12971 ix86_free_from_memory (GET_MODE (operands[1]));
12976 [(set (match_operand 0 "register_operand" "")
12977 (match_operator 3 "binary_fp_operator"
12978 [(match_operand 1 "register_operand" "")
12979 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12981 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12982 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12985 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12986 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12987 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12988 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12989 GET_MODE (operands[3]),
12992 ix86_free_from_memory (GET_MODE (operands[2]));
12996 ;; FPU special functions.
12998 ;; This pattern implements a no-op XFmode truncation for
12999 ;; all fancy i386 XFmode math functions.
13001 (define_insn "truncxf<mode>2_i387_noop_unspec"
13002 [(set (match_operand:MODEF 0 "register_operand" "=f")
13003 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13004 UNSPEC_TRUNC_NOOP))]
13005 "TARGET_USE_FANCY_MATH_387"
13006 "* return output_387_reg_move (insn, operands);"
13007 [(set_attr "type" "fmov")
13008 (set_attr "mode" "<MODE>")])
13010 (define_insn "sqrtxf2"
13011 [(set (match_operand:XF 0 "register_operand" "=f")
13012 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13013 "TARGET_USE_FANCY_MATH_387"
13015 [(set_attr "type" "fpspc")
13016 (set_attr "mode" "XF")
13017 (set_attr "athlon_decode" "direct")
13018 (set_attr "amdfam10_decode" "direct")
13019 (set_attr "bdver1_decode" "direct")])
13021 (define_insn "sqrt_extend<mode>xf2_i387"
13022 [(set (match_operand:XF 0 "register_operand" "=f")
13025 (match_operand:MODEF 1 "register_operand" "0"))))]
13026 "TARGET_USE_FANCY_MATH_387"
13028 [(set_attr "type" "fpspc")
13029 (set_attr "mode" "XF")
13030 (set_attr "athlon_decode" "direct")
13031 (set_attr "amdfam10_decode" "direct")
13032 (set_attr "bdver1_decode" "direct")])
13034 (define_insn "*rsqrtsf2_sse"
13035 [(set (match_operand:SF 0 "register_operand" "=x")
13036 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13039 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13040 [(set_attr "type" "sse")
13041 (set_attr "atom_sse_attr" "rcp")
13042 (set_attr "prefix" "maybe_vex")
13043 (set_attr "mode" "SF")])
13045 (define_expand "rsqrtsf2"
13046 [(set (match_operand:SF 0 "register_operand" "")
13047 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13051 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13055 (define_insn "*sqrt<mode>2_sse"
13056 [(set (match_operand:MODEF 0 "register_operand" "=x")
13058 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13059 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13060 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13061 [(set_attr "type" "sse")
13062 (set_attr "atom_sse_attr" "sqrt")
13063 (set_attr "prefix" "maybe_vex")
13064 (set_attr "mode" "<MODE>")
13065 (set_attr "athlon_decode" "*")
13066 (set_attr "amdfam10_decode" "*")
13067 (set_attr "bdver1_decode" "*")])
13069 (define_expand "sqrt<mode>2"
13070 [(set (match_operand:MODEF 0 "register_operand" "")
13072 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13073 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13074 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13076 if (<MODE>mode == SFmode
13077 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13078 && flag_finite_math_only && !flag_trapping_math
13079 && flag_unsafe_math_optimizations)
13081 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13085 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13087 rtx op0 = gen_reg_rtx (XFmode);
13088 rtx op1 = force_reg (<MODE>mode, operands[1]);
13090 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13091 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13096 (define_insn "fpremxf4_i387"
13097 [(set (match_operand:XF 0 "register_operand" "=f")
13098 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13099 (match_operand:XF 3 "register_operand" "1")]
13101 (set (match_operand:XF 1 "register_operand" "=u")
13102 (unspec:XF [(match_dup 2) (match_dup 3)]
13104 (set (reg:CCFP FPSR_REG)
13105 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13107 "TARGET_USE_FANCY_MATH_387"
13109 [(set_attr "type" "fpspc")
13110 (set_attr "mode" "XF")])
13112 (define_expand "fmodxf3"
13113 [(use (match_operand:XF 0 "register_operand" ""))
13114 (use (match_operand:XF 1 "general_operand" ""))
13115 (use (match_operand:XF 2 "general_operand" ""))]
13116 "TARGET_USE_FANCY_MATH_387"
13118 rtx label = gen_label_rtx ();
13120 rtx op1 = gen_reg_rtx (XFmode);
13121 rtx op2 = gen_reg_rtx (XFmode);
13123 emit_move_insn (op2, operands[2]);
13124 emit_move_insn (op1, operands[1]);
13126 emit_label (label);
13127 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13128 ix86_emit_fp_unordered_jump (label);
13129 LABEL_NUSES (label) = 1;
13131 emit_move_insn (operands[0], op1);
13135 (define_expand "fmod<mode>3"
13136 [(use (match_operand:MODEF 0 "register_operand" ""))
13137 (use (match_operand:MODEF 1 "general_operand" ""))
13138 (use (match_operand:MODEF 2 "general_operand" ""))]
13139 "TARGET_USE_FANCY_MATH_387"
13141 rtx (*gen_truncxf) (rtx, rtx);
13143 rtx label = gen_label_rtx ();
13145 rtx op1 = gen_reg_rtx (XFmode);
13146 rtx op2 = gen_reg_rtx (XFmode);
13148 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13149 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13151 emit_label (label);
13152 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13153 ix86_emit_fp_unordered_jump (label);
13154 LABEL_NUSES (label) = 1;
13156 /* Truncate the result properly for strict SSE math. */
13157 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13158 && !TARGET_MIX_SSE_I387)
13159 gen_truncxf = gen_truncxf<mode>2;
13161 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13163 emit_insn (gen_truncxf (operands[0], op1));
13167 (define_insn "fprem1xf4_i387"
13168 [(set (match_operand:XF 0 "register_operand" "=f")
13169 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13170 (match_operand:XF 3 "register_operand" "1")]
13172 (set (match_operand:XF 1 "register_operand" "=u")
13173 (unspec:XF [(match_dup 2) (match_dup 3)]
13175 (set (reg:CCFP FPSR_REG)
13176 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13178 "TARGET_USE_FANCY_MATH_387"
13180 [(set_attr "type" "fpspc")
13181 (set_attr "mode" "XF")])
13183 (define_expand "remainderxf3"
13184 [(use (match_operand:XF 0 "register_operand" ""))
13185 (use (match_operand:XF 1 "general_operand" ""))
13186 (use (match_operand:XF 2 "general_operand" ""))]
13187 "TARGET_USE_FANCY_MATH_387"
13189 rtx label = gen_label_rtx ();
13191 rtx op1 = gen_reg_rtx (XFmode);
13192 rtx op2 = gen_reg_rtx (XFmode);
13194 emit_move_insn (op2, operands[2]);
13195 emit_move_insn (op1, operands[1]);
13197 emit_label (label);
13198 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13199 ix86_emit_fp_unordered_jump (label);
13200 LABEL_NUSES (label) = 1;
13202 emit_move_insn (operands[0], op1);
13206 (define_expand "remainder<mode>3"
13207 [(use (match_operand:MODEF 0 "register_operand" ""))
13208 (use (match_operand:MODEF 1 "general_operand" ""))
13209 (use (match_operand:MODEF 2 "general_operand" ""))]
13210 "TARGET_USE_FANCY_MATH_387"
13212 rtx (*gen_truncxf) (rtx, rtx);
13214 rtx label = gen_label_rtx ();
13216 rtx op1 = gen_reg_rtx (XFmode);
13217 rtx op2 = gen_reg_rtx (XFmode);
13219 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13220 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13222 emit_label (label);
13224 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13225 ix86_emit_fp_unordered_jump (label);
13226 LABEL_NUSES (label) = 1;
13228 /* Truncate the result properly for strict SSE math. */
13229 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13230 && !TARGET_MIX_SSE_I387)
13231 gen_truncxf = gen_truncxf<mode>2;
13233 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13235 emit_insn (gen_truncxf (operands[0], op1));
13239 (define_insn "*sinxf2_i387"
13240 [(set (match_operand:XF 0 "register_operand" "=f")
13241 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13242 "TARGET_USE_FANCY_MATH_387
13243 && flag_unsafe_math_optimizations"
13245 [(set_attr "type" "fpspc")
13246 (set_attr "mode" "XF")])
13248 (define_insn "*sin_extend<mode>xf2_i387"
13249 [(set (match_operand:XF 0 "register_operand" "=f")
13250 (unspec:XF [(float_extend:XF
13251 (match_operand:MODEF 1 "register_operand" "0"))]
13253 "TARGET_USE_FANCY_MATH_387
13254 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13255 || TARGET_MIX_SSE_I387)
13256 && flag_unsafe_math_optimizations"
13258 [(set_attr "type" "fpspc")
13259 (set_attr "mode" "XF")])
13261 (define_insn "*cosxf2_i387"
13262 [(set (match_operand:XF 0 "register_operand" "=f")
13263 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13264 "TARGET_USE_FANCY_MATH_387
13265 && flag_unsafe_math_optimizations"
13267 [(set_attr "type" "fpspc")
13268 (set_attr "mode" "XF")])
13270 (define_insn "*cos_extend<mode>xf2_i387"
13271 [(set (match_operand:XF 0 "register_operand" "=f")
13272 (unspec:XF [(float_extend:XF
13273 (match_operand:MODEF 1 "register_operand" "0"))]
13275 "TARGET_USE_FANCY_MATH_387
13276 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13277 || TARGET_MIX_SSE_I387)
13278 && flag_unsafe_math_optimizations"
13280 [(set_attr "type" "fpspc")
13281 (set_attr "mode" "XF")])
13283 ;; When sincos pattern is defined, sin and cos builtin functions will be
13284 ;; expanded to sincos pattern with one of its outputs left unused.
13285 ;; CSE pass will figure out if two sincos patterns can be combined,
13286 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13287 ;; depending on the unused output.
13289 (define_insn "sincosxf3"
13290 [(set (match_operand:XF 0 "register_operand" "=f")
13291 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13292 UNSPEC_SINCOS_COS))
13293 (set (match_operand:XF 1 "register_operand" "=u")
13294 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13295 "TARGET_USE_FANCY_MATH_387
13296 && flag_unsafe_math_optimizations"
13298 [(set_attr "type" "fpspc")
13299 (set_attr "mode" "XF")])
13302 [(set (match_operand:XF 0 "register_operand" "")
13303 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13304 UNSPEC_SINCOS_COS))
13305 (set (match_operand:XF 1 "register_operand" "")
13306 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13307 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13308 && can_create_pseudo_p ()"
13309 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13312 [(set (match_operand:XF 0 "register_operand" "")
13313 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13314 UNSPEC_SINCOS_COS))
13315 (set (match_operand:XF 1 "register_operand" "")
13316 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13317 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13318 && can_create_pseudo_p ()"
13319 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13321 (define_insn "sincos_extend<mode>xf3_i387"
13322 [(set (match_operand:XF 0 "register_operand" "=f")
13323 (unspec:XF [(float_extend:XF
13324 (match_operand:MODEF 2 "register_operand" "0"))]
13325 UNSPEC_SINCOS_COS))
13326 (set (match_operand:XF 1 "register_operand" "=u")
13327 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13328 "TARGET_USE_FANCY_MATH_387
13329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13330 || TARGET_MIX_SSE_I387)
13331 && flag_unsafe_math_optimizations"
13333 [(set_attr "type" "fpspc")
13334 (set_attr "mode" "XF")])
13337 [(set (match_operand:XF 0 "register_operand" "")
13338 (unspec:XF [(float_extend:XF
13339 (match_operand:MODEF 2 "register_operand" ""))]
13340 UNSPEC_SINCOS_COS))
13341 (set (match_operand:XF 1 "register_operand" "")
13342 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13343 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13344 && can_create_pseudo_p ()"
13345 [(set (match_dup 1)
13346 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13349 [(set (match_operand:XF 0 "register_operand" "")
13350 (unspec:XF [(float_extend:XF
13351 (match_operand:MODEF 2 "register_operand" ""))]
13352 UNSPEC_SINCOS_COS))
13353 (set (match_operand:XF 1 "register_operand" "")
13354 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13355 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13356 && can_create_pseudo_p ()"
13357 [(set (match_dup 0)
13358 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13360 (define_expand "sincos<mode>3"
13361 [(use (match_operand:MODEF 0 "register_operand" ""))
13362 (use (match_operand:MODEF 1 "register_operand" ""))
13363 (use (match_operand:MODEF 2 "register_operand" ""))]
13364 "TARGET_USE_FANCY_MATH_387
13365 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13366 || TARGET_MIX_SSE_I387)
13367 && flag_unsafe_math_optimizations"
13369 rtx op0 = gen_reg_rtx (XFmode);
13370 rtx op1 = gen_reg_rtx (XFmode);
13372 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13373 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13374 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13378 (define_insn "fptanxf4_i387"
13379 [(set (match_operand:XF 0 "register_operand" "=f")
13380 (match_operand:XF 3 "const_double_operand" "F"))
13381 (set (match_operand:XF 1 "register_operand" "=u")
13382 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13384 "TARGET_USE_FANCY_MATH_387
13385 && flag_unsafe_math_optimizations
13386 && standard_80387_constant_p (operands[3]) == 2"
13388 [(set_attr "type" "fpspc")
13389 (set_attr "mode" "XF")])
13391 (define_insn "fptan_extend<mode>xf4_i387"
13392 [(set (match_operand:MODEF 0 "register_operand" "=f")
13393 (match_operand:MODEF 3 "const_double_operand" "F"))
13394 (set (match_operand:XF 1 "register_operand" "=u")
13395 (unspec:XF [(float_extend:XF
13396 (match_operand:MODEF 2 "register_operand" "0"))]
13398 "TARGET_USE_FANCY_MATH_387
13399 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13400 || TARGET_MIX_SSE_I387)
13401 && flag_unsafe_math_optimizations
13402 && standard_80387_constant_p (operands[3]) == 2"
13404 [(set_attr "type" "fpspc")
13405 (set_attr "mode" "XF")])
13407 (define_expand "tanxf2"
13408 [(use (match_operand:XF 0 "register_operand" ""))
13409 (use (match_operand:XF 1 "register_operand" ""))]
13410 "TARGET_USE_FANCY_MATH_387
13411 && flag_unsafe_math_optimizations"
13413 rtx one = gen_reg_rtx (XFmode);
13414 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13416 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13420 (define_expand "tan<mode>2"
13421 [(use (match_operand:MODEF 0 "register_operand" ""))
13422 (use (match_operand:MODEF 1 "register_operand" ""))]
13423 "TARGET_USE_FANCY_MATH_387
13424 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13425 || TARGET_MIX_SSE_I387)
13426 && flag_unsafe_math_optimizations"
13428 rtx op0 = gen_reg_rtx (XFmode);
13430 rtx one = gen_reg_rtx (<MODE>mode);
13431 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13433 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13434 operands[1], op2));
13435 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13439 (define_insn "*fpatanxf3_i387"
13440 [(set (match_operand:XF 0 "register_operand" "=f")
13441 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13442 (match_operand:XF 2 "register_operand" "u")]
13444 (clobber (match_scratch:XF 3 "=2"))]
13445 "TARGET_USE_FANCY_MATH_387
13446 && flag_unsafe_math_optimizations"
13448 [(set_attr "type" "fpspc")
13449 (set_attr "mode" "XF")])
13451 (define_insn "fpatan_extend<mode>xf3_i387"
13452 [(set (match_operand:XF 0 "register_operand" "=f")
13453 (unspec:XF [(float_extend:XF
13454 (match_operand:MODEF 1 "register_operand" "0"))
13456 (match_operand:MODEF 2 "register_operand" "u"))]
13458 (clobber (match_scratch:XF 3 "=2"))]
13459 "TARGET_USE_FANCY_MATH_387
13460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13461 || TARGET_MIX_SSE_I387)
13462 && flag_unsafe_math_optimizations"
13464 [(set_attr "type" "fpspc")
13465 (set_attr "mode" "XF")])
13467 (define_expand "atan2xf3"
13468 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13469 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13470 (match_operand:XF 1 "register_operand" "")]
13472 (clobber (match_scratch:XF 3 ""))])]
13473 "TARGET_USE_FANCY_MATH_387
13474 && flag_unsafe_math_optimizations")
13476 (define_expand "atan2<mode>3"
13477 [(use (match_operand:MODEF 0 "register_operand" ""))
13478 (use (match_operand:MODEF 1 "register_operand" ""))
13479 (use (match_operand:MODEF 2 "register_operand" ""))]
13480 "TARGET_USE_FANCY_MATH_387
13481 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13482 || TARGET_MIX_SSE_I387)
13483 && flag_unsafe_math_optimizations"
13485 rtx op0 = gen_reg_rtx (XFmode);
13487 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13488 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13492 (define_expand "atanxf2"
13493 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13494 (unspec:XF [(match_dup 2)
13495 (match_operand:XF 1 "register_operand" "")]
13497 (clobber (match_scratch:XF 3 ""))])]
13498 "TARGET_USE_FANCY_MATH_387
13499 && flag_unsafe_math_optimizations"
13501 operands[2] = gen_reg_rtx (XFmode);
13502 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13505 (define_expand "atan<mode>2"
13506 [(use (match_operand:MODEF 0 "register_operand" ""))
13507 (use (match_operand:MODEF 1 "register_operand" ""))]
13508 "TARGET_USE_FANCY_MATH_387
13509 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13510 || TARGET_MIX_SSE_I387)
13511 && flag_unsafe_math_optimizations"
13513 rtx op0 = gen_reg_rtx (XFmode);
13515 rtx op2 = gen_reg_rtx (<MODE>mode);
13516 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13518 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13519 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13523 (define_expand "asinxf2"
13524 [(set (match_dup 2)
13525 (mult:XF (match_operand:XF 1 "register_operand" "")
13527 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13528 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13529 (parallel [(set (match_operand:XF 0 "register_operand" "")
13530 (unspec:XF [(match_dup 5) (match_dup 1)]
13532 (clobber (match_scratch:XF 6 ""))])]
13533 "TARGET_USE_FANCY_MATH_387
13534 && flag_unsafe_math_optimizations"
13538 if (optimize_insn_for_size_p ())
13541 for (i = 2; i < 6; i++)
13542 operands[i] = gen_reg_rtx (XFmode);
13544 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13547 (define_expand "asin<mode>2"
13548 [(use (match_operand:MODEF 0 "register_operand" ""))
13549 (use (match_operand:MODEF 1 "general_operand" ""))]
13550 "TARGET_USE_FANCY_MATH_387
13551 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13552 || TARGET_MIX_SSE_I387)
13553 && flag_unsafe_math_optimizations"
13555 rtx op0 = gen_reg_rtx (XFmode);
13556 rtx op1 = gen_reg_rtx (XFmode);
13558 if (optimize_insn_for_size_p ())
13561 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13562 emit_insn (gen_asinxf2 (op0, op1));
13563 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13567 (define_expand "acosxf2"
13568 [(set (match_dup 2)
13569 (mult:XF (match_operand:XF 1 "register_operand" "")
13571 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13572 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13573 (parallel [(set (match_operand:XF 0 "register_operand" "")
13574 (unspec:XF [(match_dup 1) (match_dup 5)]
13576 (clobber (match_scratch:XF 6 ""))])]
13577 "TARGET_USE_FANCY_MATH_387
13578 && flag_unsafe_math_optimizations"
13582 if (optimize_insn_for_size_p ())
13585 for (i = 2; i < 6; i++)
13586 operands[i] = gen_reg_rtx (XFmode);
13588 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13591 (define_expand "acos<mode>2"
13592 [(use (match_operand:MODEF 0 "register_operand" ""))
13593 (use (match_operand:MODEF 1 "general_operand" ""))]
13594 "TARGET_USE_FANCY_MATH_387
13595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13596 || TARGET_MIX_SSE_I387)
13597 && flag_unsafe_math_optimizations"
13599 rtx op0 = gen_reg_rtx (XFmode);
13600 rtx op1 = gen_reg_rtx (XFmode);
13602 if (optimize_insn_for_size_p ())
13605 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13606 emit_insn (gen_acosxf2 (op0, op1));
13607 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13611 (define_insn "fyl2xxf3_i387"
13612 [(set (match_operand:XF 0 "register_operand" "=f")
13613 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13614 (match_operand:XF 2 "register_operand" "u")]
13616 (clobber (match_scratch:XF 3 "=2"))]
13617 "TARGET_USE_FANCY_MATH_387
13618 && flag_unsafe_math_optimizations"
13620 [(set_attr "type" "fpspc")
13621 (set_attr "mode" "XF")])
13623 (define_insn "fyl2x_extend<mode>xf3_i387"
13624 [(set (match_operand:XF 0 "register_operand" "=f")
13625 (unspec:XF [(float_extend:XF
13626 (match_operand:MODEF 1 "register_operand" "0"))
13627 (match_operand:XF 2 "register_operand" "u")]
13629 (clobber (match_scratch:XF 3 "=2"))]
13630 "TARGET_USE_FANCY_MATH_387
13631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13632 || TARGET_MIX_SSE_I387)
13633 && flag_unsafe_math_optimizations"
13635 [(set_attr "type" "fpspc")
13636 (set_attr "mode" "XF")])
13638 (define_expand "logxf2"
13639 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13640 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13641 (match_dup 2)] UNSPEC_FYL2X))
13642 (clobber (match_scratch:XF 3 ""))])]
13643 "TARGET_USE_FANCY_MATH_387
13644 && flag_unsafe_math_optimizations"
13646 operands[2] = gen_reg_rtx (XFmode);
13647 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13650 (define_expand "log<mode>2"
13651 [(use (match_operand:MODEF 0 "register_operand" ""))
13652 (use (match_operand:MODEF 1 "register_operand" ""))]
13653 "TARGET_USE_FANCY_MATH_387
13654 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13655 || TARGET_MIX_SSE_I387)
13656 && flag_unsafe_math_optimizations"
13658 rtx op0 = gen_reg_rtx (XFmode);
13660 rtx op2 = gen_reg_rtx (XFmode);
13661 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13663 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13664 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13668 (define_expand "log10xf2"
13669 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13670 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13671 (match_dup 2)] UNSPEC_FYL2X))
13672 (clobber (match_scratch:XF 3 ""))])]
13673 "TARGET_USE_FANCY_MATH_387
13674 && flag_unsafe_math_optimizations"
13676 operands[2] = gen_reg_rtx (XFmode);
13677 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13680 (define_expand "log10<mode>2"
13681 [(use (match_operand:MODEF 0 "register_operand" ""))
13682 (use (match_operand:MODEF 1 "register_operand" ""))]
13683 "TARGET_USE_FANCY_MATH_387
13684 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13685 || TARGET_MIX_SSE_I387)
13686 && flag_unsafe_math_optimizations"
13688 rtx op0 = gen_reg_rtx (XFmode);
13690 rtx op2 = gen_reg_rtx (XFmode);
13691 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13693 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13694 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13698 (define_expand "log2xf2"
13699 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13700 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13701 (match_dup 2)] UNSPEC_FYL2X))
13702 (clobber (match_scratch:XF 3 ""))])]
13703 "TARGET_USE_FANCY_MATH_387
13704 && flag_unsafe_math_optimizations"
13706 operands[2] = gen_reg_rtx (XFmode);
13707 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13710 (define_expand "log2<mode>2"
13711 [(use (match_operand:MODEF 0 "register_operand" ""))
13712 (use (match_operand:MODEF 1 "register_operand" ""))]
13713 "TARGET_USE_FANCY_MATH_387
13714 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13715 || TARGET_MIX_SSE_I387)
13716 && flag_unsafe_math_optimizations"
13718 rtx op0 = gen_reg_rtx (XFmode);
13720 rtx op2 = gen_reg_rtx (XFmode);
13721 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13723 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13724 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13728 (define_insn "fyl2xp1xf3_i387"
13729 [(set (match_operand:XF 0 "register_operand" "=f")
13730 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13731 (match_operand:XF 2 "register_operand" "u")]
13733 (clobber (match_scratch:XF 3 "=2"))]
13734 "TARGET_USE_FANCY_MATH_387
13735 && flag_unsafe_math_optimizations"
13737 [(set_attr "type" "fpspc")
13738 (set_attr "mode" "XF")])
13740 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13741 [(set (match_operand:XF 0 "register_operand" "=f")
13742 (unspec:XF [(float_extend:XF
13743 (match_operand:MODEF 1 "register_operand" "0"))
13744 (match_operand:XF 2 "register_operand" "u")]
13746 (clobber (match_scratch:XF 3 "=2"))]
13747 "TARGET_USE_FANCY_MATH_387
13748 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13749 || TARGET_MIX_SSE_I387)
13750 && flag_unsafe_math_optimizations"
13752 [(set_attr "type" "fpspc")
13753 (set_attr "mode" "XF")])
13755 (define_expand "log1pxf2"
13756 [(use (match_operand:XF 0 "register_operand" ""))
13757 (use (match_operand:XF 1 "register_operand" ""))]
13758 "TARGET_USE_FANCY_MATH_387
13759 && flag_unsafe_math_optimizations"
13761 if (optimize_insn_for_size_p ())
13764 ix86_emit_i387_log1p (operands[0], operands[1]);
13768 (define_expand "log1p<mode>2"
13769 [(use (match_operand:MODEF 0 "register_operand" ""))
13770 (use (match_operand:MODEF 1 "register_operand" ""))]
13771 "TARGET_USE_FANCY_MATH_387
13772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13773 || TARGET_MIX_SSE_I387)
13774 && flag_unsafe_math_optimizations"
13778 if (optimize_insn_for_size_p ())
13781 op0 = gen_reg_rtx (XFmode);
13783 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13785 ix86_emit_i387_log1p (op0, operands[1]);
13786 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13790 (define_insn "fxtractxf3_i387"
13791 [(set (match_operand:XF 0 "register_operand" "=f")
13792 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13793 UNSPEC_XTRACT_FRACT))
13794 (set (match_operand:XF 1 "register_operand" "=u")
13795 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13796 "TARGET_USE_FANCY_MATH_387
13797 && flag_unsafe_math_optimizations"
13799 [(set_attr "type" "fpspc")
13800 (set_attr "mode" "XF")])
13802 (define_insn "fxtract_extend<mode>xf3_i387"
13803 [(set (match_operand:XF 0 "register_operand" "=f")
13804 (unspec:XF [(float_extend:XF
13805 (match_operand:MODEF 2 "register_operand" "0"))]
13806 UNSPEC_XTRACT_FRACT))
13807 (set (match_operand:XF 1 "register_operand" "=u")
13808 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13809 "TARGET_USE_FANCY_MATH_387
13810 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13811 || TARGET_MIX_SSE_I387)
13812 && flag_unsafe_math_optimizations"
13814 [(set_attr "type" "fpspc")
13815 (set_attr "mode" "XF")])
13817 (define_expand "logbxf2"
13818 [(parallel [(set (match_dup 2)
13819 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13820 UNSPEC_XTRACT_FRACT))
13821 (set (match_operand:XF 0 "register_operand" "")
13822 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13823 "TARGET_USE_FANCY_MATH_387
13824 && flag_unsafe_math_optimizations"
13825 "operands[2] = gen_reg_rtx (XFmode);")
13827 (define_expand "logb<mode>2"
13828 [(use (match_operand:MODEF 0 "register_operand" ""))
13829 (use (match_operand:MODEF 1 "register_operand" ""))]
13830 "TARGET_USE_FANCY_MATH_387
13831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13832 || TARGET_MIX_SSE_I387)
13833 && flag_unsafe_math_optimizations"
13835 rtx op0 = gen_reg_rtx (XFmode);
13836 rtx op1 = gen_reg_rtx (XFmode);
13838 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13839 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13843 (define_expand "ilogbxf2"
13844 [(use (match_operand:SI 0 "register_operand" ""))
13845 (use (match_operand:XF 1 "register_operand" ""))]
13846 "TARGET_USE_FANCY_MATH_387
13847 && flag_unsafe_math_optimizations"
13851 if (optimize_insn_for_size_p ())
13854 op0 = gen_reg_rtx (XFmode);
13855 op1 = gen_reg_rtx (XFmode);
13857 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13858 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13862 (define_expand "ilogb<mode>2"
13863 [(use (match_operand:SI 0 "register_operand" ""))
13864 (use (match_operand:MODEF 1 "register_operand" ""))]
13865 "TARGET_USE_FANCY_MATH_387
13866 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13867 || TARGET_MIX_SSE_I387)
13868 && flag_unsafe_math_optimizations"
13872 if (optimize_insn_for_size_p ())
13875 op0 = gen_reg_rtx (XFmode);
13876 op1 = gen_reg_rtx (XFmode);
13878 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13879 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13883 (define_insn "*f2xm1xf2_i387"
13884 [(set (match_operand:XF 0 "register_operand" "=f")
13885 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13887 "TARGET_USE_FANCY_MATH_387
13888 && flag_unsafe_math_optimizations"
13890 [(set_attr "type" "fpspc")
13891 (set_attr "mode" "XF")])
13893 (define_insn "*fscalexf4_i387"
13894 [(set (match_operand:XF 0 "register_operand" "=f")
13895 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13896 (match_operand:XF 3 "register_operand" "1")]
13897 UNSPEC_FSCALE_FRACT))
13898 (set (match_operand:XF 1 "register_operand" "=u")
13899 (unspec:XF [(match_dup 2) (match_dup 3)]
13900 UNSPEC_FSCALE_EXP))]
13901 "TARGET_USE_FANCY_MATH_387
13902 && flag_unsafe_math_optimizations"
13904 [(set_attr "type" "fpspc")
13905 (set_attr "mode" "XF")])
13907 (define_expand "expNcorexf3"
13908 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13909 (match_operand:XF 2 "register_operand" "")))
13910 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13911 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13912 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13913 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13914 (parallel [(set (match_operand:XF 0 "register_operand" "")
13915 (unspec:XF [(match_dup 8) (match_dup 4)]
13916 UNSPEC_FSCALE_FRACT))
13918 (unspec:XF [(match_dup 8) (match_dup 4)]
13919 UNSPEC_FSCALE_EXP))])]
13920 "TARGET_USE_FANCY_MATH_387
13921 && flag_unsafe_math_optimizations"
13925 if (optimize_insn_for_size_p ())
13928 for (i = 3; i < 10; i++)
13929 operands[i] = gen_reg_rtx (XFmode);
13931 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13934 (define_expand "expxf2"
13935 [(use (match_operand:XF 0 "register_operand" ""))
13936 (use (match_operand:XF 1 "register_operand" ""))]
13937 "TARGET_USE_FANCY_MATH_387
13938 && flag_unsafe_math_optimizations"
13942 if (optimize_insn_for_size_p ())
13945 op2 = gen_reg_rtx (XFmode);
13946 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13948 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13952 (define_expand "exp<mode>2"
13953 [(use (match_operand:MODEF 0 "register_operand" ""))
13954 (use (match_operand:MODEF 1 "general_operand" ""))]
13955 "TARGET_USE_FANCY_MATH_387
13956 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13957 || TARGET_MIX_SSE_I387)
13958 && flag_unsafe_math_optimizations"
13962 if (optimize_insn_for_size_p ())
13965 op0 = gen_reg_rtx (XFmode);
13966 op1 = gen_reg_rtx (XFmode);
13968 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13969 emit_insn (gen_expxf2 (op0, op1));
13970 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13974 (define_expand "exp10xf2"
13975 [(use (match_operand:XF 0 "register_operand" ""))
13976 (use (match_operand:XF 1 "register_operand" ""))]
13977 "TARGET_USE_FANCY_MATH_387
13978 && flag_unsafe_math_optimizations"
13982 if (optimize_insn_for_size_p ())
13985 op2 = gen_reg_rtx (XFmode);
13986 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13988 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13992 (define_expand "exp10<mode>2"
13993 [(use (match_operand:MODEF 0 "register_operand" ""))
13994 (use (match_operand:MODEF 1 "general_operand" ""))]
13995 "TARGET_USE_FANCY_MATH_387
13996 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13997 || TARGET_MIX_SSE_I387)
13998 && flag_unsafe_math_optimizations"
14002 if (optimize_insn_for_size_p ())
14005 op0 = gen_reg_rtx (XFmode);
14006 op1 = gen_reg_rtx (XFmode);
14008 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14009 emit_insn (gen_exp10xf2 (op0, op1));
14010 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14014 (define_expand "exp2xf2"
14015 [(use (match_operand:XF 0 "register_operand" ""))
14016 (use (match_operand:XF 1 "register_operand" ""))]
14017 "TARGET_USE_FANCY_MATH_387
14018 && flag_unsafe_math_optimizations"
14022 if (optimize_insn_for_size_p ())
14025 op2 = gen_reg_rtx (XFmode);
14026 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14028 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14032 (define_expand "exp2<mode>2"
14033 [(use (match_operand:MODEF 0 "register_operand" ""))
14034 (use (match_operand:MODEF 1 "general_operand" ""))]
14035 "TARGET_USE_FANCY_MATH_387
14036 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14037 || TARGET_MIX_SSE_I387)
14038 && flag_unsafe_math_optimizations"
14042 if (optimize_insn_for_size_p ())
14045 op0 = gen_reg_rtx (XFmode);
14046 op1 = gen_reg_rtx (XFmode);
14048 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14049 emit_insn (gen_exp2xf2 (op0, op1));
14050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14054 (define_expand "expm1xf2"
14055 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14057 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14058 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14059 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14060 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14061 (parallel [(set (match_dup 7)
14062 (unspec:XF [(match_dup 6) (match_dup 4)]
14063 UNSPEC_FSCALE_FRACT))
14065 (unspec:XF [(match_dup 6) (match_dup 4)]
14066 UNSPEC_FSCALE_EXP))])
14067 (parallel [(set (match_dup 10)
14068 (unspec:XF [(match_dup 9) (match_dup 8)]
14069 UNSPEC_FSCALE_FRACT))
14070 (set (match_dup 11)
14071 (unspec:XF [(match_dup 9) (match_dup 8)]
14072 UNSPEC_FSCALE_EXP))])
14073 (set (match_dup 12) (minus:XF (match_dup 10)
14074 (float_extend:XF (match_dup 13))))
14075 (set (match_operand:XF 0 "register_operand" "")
14076 (plus:XF (match_dup 12) (match_dup 7)))]
14077 "TARGET_USE_FANCY_MATH_387
14078 && flag_unsafe_math_optimizations"
14082 if (optimize_insn_for_size_p ())
14085 for (i = 2; i < 13; i++)
14086 operands[i] = gen_reg_rtx (XFmode);
14089 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14091 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14094 (define_expand "expm1<mode>2"
14095 [(use (match_operand:MODEF 0 "register_operand" ""))
14096 (use (match_operand:MODEF 1 "general_operand" ""))]
14097 "TARGET_USE_FANCY_MATH_387
14098 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14099 || TARGET_MIX_SSE_I387)
14100 && flag_unsafe_math_optimizations"
14104 if (optimize_insn_for_size_p ())
14107 op0 = gen_reg_rtx (XFmode);
14108 op1 = gen_reg_rtx (XFmode);
14110 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14111 emit_insn (gen_expm1xf2 (op0, op1));
14112 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14116 (define_expand "ldexpxf3"
14117 [(set (match_dup 3)
14118 (float:XF (match_operand:SI 2 "register_operand" "")))
14119 (parallel [(set (match_operand:XF 0 " register_operand" "")
14120 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14122 UNSPEC_FSCALE_FRACT))
14124 (unspec:XF [(match_dup 1) (match_dup 3)]
14125 UNSPEC_FSCALE_EXP))])]
14126 "TARGET_USE_FANCY_MATH_387
14127 && flag_unsafe_math_optimizations"
14129 if (optimize_insn_for_size_p ())
14132 operands[3] = gen_reg_rtx (XFmode);
14133 operands[4] = gen_reg_rtx (XFmode);
14136 (define_expand "ldexp<mode>3"
14137 [(use (match_operand:MODEF 0 "register_operand" ""))
14138 (use (match_operand:MODEF 1 "general_operand" ""))
14139 (use (match_operand:SI 2 "register_operand" ""))]
14140 "TARGET_USE_FANCY_MATH_387
14141 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14142 || TARGET_MIX_SSE_I387)
14143 && flag_unsafe_math_optimizations"
14147 if (optimize_insn_for_size_p ())
14150 op0 = gen_reg_rtx (XFmode);
14151 op1 = gen_reg_rtx (XFmode);
14153 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14154 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14155 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14159 (define_expand "scalbxf3"
14160 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14161 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14162 (match_operand:XF 2 "register_operand" "")]
14163 UNSPEC_FSCALE_FRACT))
14165 (unspec:XF [(match_dup 1) (match_dup 2)]
14166 UNSPEC_FSCALE_EXP))])]
14167 "TARGET_USE_FANCY_MATH_387
14168 && flag_unsafe_math_optimizations"
14170 if (optimize_insn_for_size_p ())
14173 operands[3] = gen_reg_rtx (XFmode);
14176 (define_expand "scalb<mode>3"
14177 [(use (match_operand:MODEF 0 "register_operand" ""))
14178 (use (match_operand:MODEF 1 "general_operand" ""))
14179 (use (match_operand:MODEF 2 "general_operand" ""))]
14180 "TARGET_USE_FANCY_MATH_387
14181 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14182 || TARGET_MIX_SSE_I387)
14183 && flag_unsafe_math_optimizations"
14187 if (optimize_insn_for_size_p ())
14190 op0 = gen_reg_rtx (XFmode);
14191 op1 = gen_reg_rtx (XFmode);
14192 op2 = gen_reg_rtx (XFmode);
14194 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14195 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14196 emit_insn (gen_scalbxf3 (op0, op1, op2));
14197 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14201 (define_expand "significandxf2"
14202 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14203 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14204 UNSPEC_XTRACT_FRACT))
14206 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14207 "TARGET_USE_FANCY_MATH_387
14208 && flag_unsafe_math_optimizations"
14209 "operands[2] = gen_reg_rtx (XFmode);")
14211 (define_expand "significand<mode>2"
14212 [(use (match_operand:MODEF 0 "register_operand" ""))
14213 (use (match_operand:MODEF 1 "register_operand" ""))]
14214 "TARGET_USE_FANCY_MATH_387
14215 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14216 || TARGET_MIX_SSE_I387)
14217 && flag_unsafe_math_optimizations"
14219 rtx op0 = gen_reg_rtx (XFmode);
14220 rtx op1 = gen_reg_rtx (XFmode);
14222 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14223 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14228 (define_insn "sse4_1_round<mode>2"
14229 [(set (match_operand:MODEF 0 "register_operand" "=x")
14230 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14231 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14234 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14235 [(set_attr "type" "ssecvt")
14236 (set_attr "prefix_extra" "1")
14237 (set_attr "prefix" "maybe_vex")
14238 (set_attr "mode" "<MODE>")])
14240 (define_insn "rintxf2"
14241 [(set (match_operand:XF 0 "register_operand" "=f")
14242 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14244 "TARGET_USE_FANCY_MATH_387
14245 && flag_unsafe_math_optimizations"
14247 [(set_attr "type" "fpspc")
14248 (set_attr "mode" "XF")])
14250 (define_expand "rint<mode>2"
14251 [(use (match_operand:MODEF 0 "register_operand" ""))
14252 (use (match_operand:MODEF 1 "register_operand" ""))]
14253 "(TARGET_USE_FANCY_MATH_387
14254 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14255 || TARGET_MIX_SSE_I387)
14256 && flag_unsafe_math_optimizations)
14257 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14258 && !flag_trapping_math)"
14260 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14261 && !flag_trapping_math)
14263 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14266 emit_insn (gen_sse4_1_round<mode>2
14267 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14269 ix86_expand_rint (operand0, operand1);
14273 rtx op0 = gen_reg_rtx (XFmode);
14274 rtx op1 = gen_reg_rtx (XFmode);
14276 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14277 emit_insn (gen_rintxf2 (op0, op1));
14279 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14284 (define_expand "round<mode>2"
14285 [(match_operand:MODEF 0 "register_operand" "")
14286 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14287 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14288 && !flag_trapping_math && !flag_rounding_math"
14290 if (optimize_insn_for_size_p ())
14292 if (TARGET_64BIT || (<MODE>mode != DFmode))
14293 ix86_expand_round (operand0, operand1);
14295 ix86_expand_rounddf_32 (operand0, operand1);
14299 (define_insn_and_split "*fistdi2_1"
14300 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14301 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14303 "TARGET_USE_FANCY_MATH_387
14304 && can_create_pseudo_p ()"
14309 if (memory_operand (operands[0], VOIDmode))
14310 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14313 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14314 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14319 [(set_attr "type" "fpspc")
14320 (set_attr "mode" "DI")])
14322 (define_insn "fistdi2"
14323 [(set (match_operand:DI 0 "memory_operand" "=m")
14324 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14326 (clobber (match_scratch:XF 2 "=&1f"))]
14327 "TARGET_USE_FANCY_MATH_387"
14328 "* return output_fix_trunc (insn, operands, 0);"
14329 [(set_attr "type" "fpspc")
14330 (set_attr "mode" "DI")])
14332 (define_insn "fistdi2_with_temp"
14333 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14334 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14336 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14337 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14338 "TARGET_USE_FANCY_MATH_387"
14340 [(set_attr "type" "fpspc")
14341 (set_attr "mode" "DI")])
14344 [(set (match_operand:DI 0 "register_operand" "")
14345 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14347 (clobber (match_operand:DI 2 "memory_operand" ""))
14348 (clobber (match_scratch 3 ""))]
14350 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14351 (clobber (match_dup 3))])
14352 (set (match_dup 0) (match_dup 2))])
14355 [(set (match_operand:DI 0 "memory_operand" "")
14356 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14358 (clobber (match_operand:DI 2 "memory_operand" ""))
14359 (clobber (match_scratch 3 ""))]
14361 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14362 (clobber (match_dup 3))])])
14364 (define_insn_and_split "*fist<mode>2_1"
14365 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14366 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14368 "TARGET_USE_FANCY_MATH_387
14369 && can_create_pseudo_p ()"
14374 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14375 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14379 [(set_attr "type" "fpspc")
14380 (set_attr "mode" "<MODE>")])
14382 (define_insn "fist<mode>2"
14383 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14384 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14386 "TARGET_USE_FANCY_MATH_387"
14387 "* return output_fix_trunc (insn, operands, 0);"
14388 [(set_attr "type" "fpspc")
14389 (set_attr "mode" "<MODE>")])
14391 (define_insn "fist<mode>2_with_temp"
14392 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14393 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14395 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14396 "TARGET_USE_FANCY_MATH_387"
14398 [(set_attr "type" "fpspc")
14399 (set_attr "mode" "<MODE>")])
14402 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14403 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14405 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14407 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14408 (set (match_dup 0) (match_dup 2))])
14411 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14412 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14414 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14416 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14418 (define_expand "lrintxf<mode>2"
14419 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14420 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14422 "TARGET_USE_FANCY_MATH_387")
14424 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14425 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14426 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14427 UNSPEC_FIX_NOTRUNC))]
14428 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14429 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14431 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14432 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14433 (match_operand:MODEF 1 "register_operand" "")]
14434 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14435 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14436 && !flag_trapping_math && !flag_rounding_math"
14438 if (optimize_insn_for_size_p ())
14440 ix86_expand_lround (operand0, operand1);
14444 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14445 (define_insn_and_split "frndintxf2_floor"
14446 [(set (match_operand:XF 0 "register_operand" "")
14447 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14448 UNSPEC_FRNDINT_FLOOR))
14449 (clobber (reg:CC FLAGS_REG))]
14450 "TARGET_USE_FANCY_MATH_387
14451 && flag_unsafe_math_optimizations
14452 && can_create_pseudo_p ()"
14457 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14459 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14460 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14462 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14463 operands[2], operands[3]));
14466 [(set_attr "type" "frndint")
14467 (set_attr "i387_cw" "floor")
14468 (set_attr "mode" "XF")])
14470 (define_insn "frndintxf2_floor_i387"
14471 [(set (match_operand:XF 0 "register_operand" "=f")
14472 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14473 UNSPEC_FRNDINT_FLOOR))
14474 (use (match_operand:HI 2 "memory_operand" "m"))
14475 (use (match_operand:HI 3 "memory_operand" "m"))]
14476 "TARGET_USE_FANCY_MATH_387
14477 && flag_unsafe_math_optimizations"
14478 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14479 [(set_attr "type" "frndint")
14480 (set_attr "i387_cw" "floor")
14481 (set_attr "mode" "XF")])
14483 (define_expand "floorxf2"
14484 [(use (match_operand:XF 0 "register_operand" ""))
14485 (use (match_operand:XF 1 "register_operand" ""))]
14486 "TARGET_USE_FANCY_MATH_387
14487 && flag_unsafe_math_optimizations"
14489 if (optimize_insn_for_size_p ())
14491 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14495 (define_expand "floor<mode>2"
14496 [(use (match_operand:MODEF 0 "register_operand" ""))
14497 (use (match_operand:MODEF 1 "register_operand" ""))]
14498 "(TARGET_USE_FANCY_MATH_387
14499 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14500 || TARGET_MIX_SSE_I387)
14501 && flag_unsafe_math_optimizations)
14502 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14503 && !flag_trapping_math)"
14505 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14506 && !flag_trapping_math
14507 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14509 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14512 emit_insn (gen_sse4_1_round<mode>2
14513 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14514 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14515 ix86_expand_floorceil (operand0, operand1, true);
14517 ix86_expand_floorceildf_32 (operand0, operand1, true);
14523 if (optimize_insn_for_size_p ())
14526 op0 = gen_reg_rtx (XFmode);
14527 op1 = gen_reg_rtx (XFmode);
14528 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14529 emit_insn (gen_frndintxf2_floor (op0, op1));
14531 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14536 (define_insn_and_split "*fist<mode>2_floor_1"
14537 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14538 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14539 UNSPEC_FIST_FLOOR))
14540 (clobber (reg:CC FLAGS_REG))]
14541 "TARGET_USE_FANCY_MATH_387
14542 && flag_unsafe_math_optimizations
14543 && can_create_pseudo_p ()"
14548 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14550 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14551 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14552 if (memory_operand (operands[0], VOIDmode))
14553 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14554 operands[2], operands[3]));
14557 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14558 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14559 operands[2], operands[3],
14564 [(set_attr "type" "fistp")
14565 (set_attr "i387_cw" "floor")
14566 (set_attr "mode" "<MODE>")])
14568 (define_insn "fistdi2_floor"
14569 [(set (match_operand:DI 0 "memory_operand" "=m")
14570 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14571 UNSPEC_FIST_FLOOR))
14572 (use (match_operand:HI 2 "memory_operand" "m"))
14573 (use (match_operand:HI 3 "memory_operand" "m"))
14574 (clobber (match_scratch:XF 4 "=&1f"))]
14575 "TARGET_USE_FANCY_MATH_387
14576 && flag_unsafe_math_optimizations"
14577 "* return output_fix_trunc (insn, operands, 0);"
14578 [(set_attr "type" "fistp")
14579 (set_attr "i387_cw" "floor")
14580 (set_attr "mode" "DI")])
14582 (define_insn "fistdi2_floor_with_temp"
14583 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14584 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14585 UNSPEC_FIST_FLOOR))
14586 (use (match_operand:HI 2 "memory_operand" "m,m"))
14587 (use (match_operand:HI 3 "memory_operand" "m,m"))
14588 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14589 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14590 "TARGET_USE_FANCY_MATH_387
14591 && flag_unsafe_math_optimizations"
14593 [(set_attr "type" "fistp")
14594 (set_attr "i387_cw" "floor")
14595 (set_attr "mode" "DI")])
14598 [(set (match_operand:DI 0 "register_operand" "")
14599 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14600 UNSPEC_FIST_FLOOR))
14601 (use (match_operand:HI 2 "memory_operand" ""))
14602 (use (match_operand:HI 3 "memory_operand" ""))
14603 (clobber (match_operand:DI 4 "memory_operand" ""))
14604 (clobber (match_scratch 5 ""))]
14606 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14607 (use (match_dup 2))
14608 (use (match_dup 3))
14609 (clobber (match_dup 5))])
14610 (set (match_dup 0) (match_dup 4))])
14613 [(set (match_operand:DI 0 "memory_operand" "")
14614 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14615 UNSPEC_FIST_FLOOR))
14616 (use (match_operand:HI 2 "memory_operand" ""))
14617 (use (match_operand:HI 3 "memory_operand" ""))
14618 (clobber (match_operand:DI 4 "memory_operand" ""))
14619 (clobber (match_scratch 5 ""))]
14621 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14622 (use (match_dup 2))
14623 (use (match_dup 3))
14624 (clobber (match_dup 5))])])
14626 (define_insn "fist<mode>2_floor"
14627 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14628 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14629 UNSPEC_FIST_FLOOR))
14630 (use (match_operand:HI 2 "memory_operand" "m"))
14631 (use (match_operand:HI 3 "memory_operand" "m"))]
14632 "TARGET_USE_FANCY_MATH_387
14633 && flag_unsafe_math_optimizations"
14634 "* return output_fix_trunc (insn, operands, 0);"
14635 [(set_attr "type" "fistp")
14636 (set_attr "i387_cw" "floor")
14637 (set_attr "mode" "<MODE>")])
14639 (define_insn "fist<mode>2_floor_with_temp"
14640 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14641 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14642 UNSPEC_FIST_FLOOR))
14643 (use (match_operand:HI 2 "memory_operand" "m,m"))
14644 (use (match_operand:HI 3 "memory_operand" "m,m"))
14645 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14646 "TARGET_USE_FANCY_MATH_387
14647 && flag_unsafe_math_optimizations"
14649 [(set_attr "type" "fistp")
14650 (set_attr "i387_cw" "floor")
14651 (set_attr "mode" "<MODE>")])
14654 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14655 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14656 UNSPEC_FIST_FLOOR))
14657 (use (match_operand:HI 2 "memory_operand" ""))
14658 (use (match_operand:HI 3 "memory_operand" ""))
14659 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14661 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14662 UNSPEC_FIST_FLOOR))
14663 (use (match_dup 2))
14664 (use (match_dup 3))])
14665 (set (match_dup 0) (match_dup 4))])
14668 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14669 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14670 UNSPEC_FIST_FLOOR))
14671 (use (match_operand:HI 2 "memory_operand" ""))
14672 (use (match_operand:HI 3 "memory_operand" ""))
14673 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14675 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14676 UNSPEC_FIST_FLOOR))
14677 (use (match_dup 2))
14678 (use (match_dup 3))])])
14680 (define_expand "lfloorxf<mode>2"
14681 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14682 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14683 UNSPEC_FIST_FLOOR))
14684 (clobber (reg:CC FLAGS_REG))])]
14685 "TARGET_USE_FANCY_MATH_387
14686 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14687 && flag_unsafe_math_optimizations")
14689 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14690 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14691 (match_operand:MODEF 1 "register_operand" "")]
14692 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14693 && !flag_trapping_math"
14695 if (TARGET_64BIT && optimize_insn_for_size_p ())
14697 ix86_expand_lfloorceil (operand0, operand1, true);
14701 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14702 (define_insn_and_split "frndintxf2_ceil"
14703 [(set (match_operand:XF 0 "register_operand" "")
14704 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14705 UNSPEC_FRNDINT_CEIL))
14706 (clobber (reg:CC FLAGS_REG))]
14707 "TARGET_USE_FANCY_MATH_387
14708 && flag_unsafe_math_optimizations
14709 && can_create_pseudo_p ()"
14714 ix86_optimize_mode_switching[I387_CEIL] = 1;
14716 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14717 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14719 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14720 operands[2], operands[3]));
14723 [(set_attr "type" "frndint")
14724 (set_attr "i387_cw" "ceil")
14725 (set_attr "mode" "XF")])
14727 (define_insn "frndintxf2_ceil_i387"
14728 [(set (match_operand:XF 0 "register_operand" "=f")
14729 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14730 UNSPEC_FRNDINT_CEIL))
14731 (use (match_operand:HI 2 "memory_operand" "m"))
14732 (use (match_operand:HI 3 "memory_operand" "m"))]
14733 "TARGET_USE_FANCY_MATH_387
14734 && flag_unsafe_math_optimizations"
14735 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14736 [(set_attr "type" "frndint")
14737 (set_attr "i387_cw" "ceil")
14738 (set_attr "mode" "XF")])
14740 (define_expand "ceilxf2"
14741 [(use (match_operand:XF 0 "register_operand" ""))
14742 (use (match_operand:XF 1 "register_operand" ""))]
14743 "TARGET_USE_FANCY_MATH_387
14744 && flag_unsafe_math_optimizations"
14746 if (optimize_insn_for_size_p ())
14748 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14752 (define_expand "ceil<mode>2"
14753 [(use (match_operand:MODEF 0 "register_operand" ""))
14754 (use (match_operand:MODEF 1 "register_operand" ""))]
14755 "(TARGET_USE_FANCY_MATH_387
14756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14757 || TARGET_MIX_SSE_I387)
14758 && flag_unsafe_math_optimizations)
14759 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14760 && !flag_trapping_math)"
14762 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14763 && !flag_trapping_math
14764 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14767 emit_insn (gen_sse4_1_round<mode>2
14768 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14769 else if (optimize_insn_for_size_p ())
14771 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14772 ix86_expand_floorceil (operand0, operand1, false);
14774 ix86_expand_floorceildf_32 (operand0, operand1, false);
14780 if (optimize_insn_for_size_p ())
14783 op0 = gen_reg_rtx (XFmode);
14784 op1 = gen_reg_rtx (XFmode);
14785 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14786 emit_insn (gen_frndintxf2_ceil (op0, op1));
14788 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14793 (define_insn_and_split "*fist<mode>2_ceil_1"
14794 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14795 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14797 (clobber (reg:CC FLAGS_REG))]
14798 "TARGET_USE_FANCY_MATH_387
14799 && flag_unsafe_math_optimizations
14800 && can_create_pseudo_p ()"
14805 ix86_optimize_mode_switching[I387_CEIL] = 1;
14807 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14808 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14809 if (memory_operand (operands[0], VOIDmode))
14810 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14811 operands[2], operands[3]));
14814 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14815 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14816 operands[2], operands[3],
14821 [(set_attr "type" "fistp")
14822 (set_attr "i387_cw" "ceil")
14823 (set_attr "mode" "<MODE>")])
14825 (define_insn "fistdi2_ceil"
14826 [(set (match_operand:DI 0 "memory_operand" "=m")
14827 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14829 (use (match_operand:HI 2 "memory_operand" "m"))
14830 (use (match_operand:HI 3 "memory_operand" "m"))
14831 (clobber (match_scratch:XF 4 "=&1f"))]
14832 "TARGET_USE_FANCY_MATH_387
14833 && flag_unsafe_math_optimizations"
14834 "* return output_fix_trunc (insn, operands, 0);"
14835 [(set_attr "type" "fistp")
14836 (set_attr "i387_cw" "ceil")
14837 (set_attr "mode" "DI")])
14839 (define_insn "fistdi2_ceil_with_temp"
14840 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14841 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14843 (use (match_operand:HI 2 "memory_operand" "m,m"))
14844 (use (match_operand:HI 3 "memory_operand" "m,m"))
14845 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14846 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14847 "TARGET_USE_FANCY_MATH_387
14848 && flag_unsafe_math_optimizations"
14850 [(set_attr "type" "fistp")
14851 (set_attr "i387_cw" "ceil")
14852 (set_attr "mode" "DI")])
14855 [(set (match_operand:DI 0 "register_operand" "")
14856 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14858 (use (match_operand:HI 2 "memory_operand" ""))
14859 (use (match_operand:HI 3 "memory_operand" ""))
14860 (clobber (match_operand:DI 4 "memory_operand" ""))
14861 (clobber (match_scratch 5 ""))]
14863 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14864 (use (match_dup 2))
14865 (use (match_dup 3))
14866 (clobber (match_dup 5))])
14867 (set (match_dup 0) (match_dup 4))])
14870 [(set (match_operand:DI 0 "memory_operand" "")
14871 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14873 (use (match_operand:HI 2 "memory_operand" ""))
14874 (use (match_operand:HI 3 "memory_operand" ""))
14875 (clobber (match_operand:DI 4 "memory_operand" ""))
14876 (clobber (match_scratch 5 ""))]
14878 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14879 (use (match_dup 2))
14880 (use (match_dup 3))
14881 (clobber (match_dup 5))])])
14883 (define_insn "fist<mode>2_ceil"
14884 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14885 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14887 (use (match_operand:HI 2 "memory_operand" "m"))
14888 (use (match_operand:HI 3 "memory_operand" "m"))]
14889 "TARGET_USE_FANCY_MATH_387
14890 && flag_unsafe_math_optimizations"
14891 "* return output_fix_trunc (insn, operands, 0);"
14892 [(set_attr "type" "fistp")
14893 (set_attr "i387_cw" "ceil")
14894 (set_attr "mode" "<MODE>")])
14896 (define_insn "fist<mode>2_ceil_with_temp"
14897 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14898 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14900 (use (match_operand:HI 2 "memory_operand" "m,m"))
14901 (use (match_operand:HI 3 "memory_operand" "m,m"))
14902 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14903 "TARGET_USE_FANCY_MATH_387
14904 && flag_unsafe_math_optimizations"
14906 [(set_attr "type" "fistp")
14907 (set_attr "i387_cw" "ceil")
14908 (set_attr "mode" "<MODE>")])
14911 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14912 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14914 (use (match_operand:HI 2 "memory_operand" ""))
14915 (use (match_operand:HI 3 "memory_operand" ""))
14916 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14918 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14920 (use (match_dup 2))
14921 (use (match_dup 3))])
14922 (set (match_dup 0) (match_dup 4))])
14925 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14926 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14928 (use (match_operand:HI 2 "memory_operand" ""))
14929 (use (match_operand:HI 3 "memory_operand" ""))
14930 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14932 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14934 (use (match_dup 2))
14935 (use (match_dup 3))])])
14937 (define_expand "lceilxf<mode>2"
14938 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14939 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14941 (clobber (reg:CC FLAGS_REG))])]
14942 "TARGET_USE_FANCY_MATH_387
14943 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14944 && flag_unsafe_math_optimizations")
14946 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14947 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14948 (match_operand:MODEF 1 "register_operand" "")]
14949 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14950 && !flag_trapping_math"
14952 ix86_expand_lfloorceil (operand0, operand1, false);
14956 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14957 (define_insn_and_split "frndintxf2_trunc"
14958 [(set (match_operand:XF 0 "register_operand" "")
14959 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14960 UNSPEC_FRNDINT_TRUNC))
14961 (clobber (reg:CC FLAGS_REG))]
14962 "TARGET_USE_FANCY_MATH_387
14963 && flag_unsafe_math_optimizations
14964 && can_create_pseudo_p ()"
14969 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14971 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14972 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14974 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14975 operands[2], operands[3]));
14978 [(set_attr "type" "frndint")
14979 (set_attr "i387_cw" "trunc")
14980 (set_attr "mode" "XF")])
14982 (define_insn "frndintxf2_trunc_i387"
14983 [(set (match_operand:XF 0 "register_operand" "=f")
14984 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14985 UNSPEC_FRNDINT_TRUNC))
14986 (use (match_operand:HI 2 "memory_operand" "m"))
14987 (use (match_operand:HI 3 "memory_operand" "m"))]
14988 "TARGET_USE_FANCY_MATH_387
14989 && flag_unsafe_math_optimizations"
14990 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14991 [(set_attr "type" "frndint")
14992 (set_attr "i387_cw" "trunc")
14993 (set_attr "mode" "XF")])
14995 (define_expand "btruncxf2"
14996 [(use (match_operand:XF 0 "register_operand" ""))
14997 (use (match_operand:XF 1 "register_operand" ""))]
14998 "TARGET_USE_FANCY_MATH_387
14999 && flag_unsafe_math_optimizations"
15001 if (optimize_insn_for_size_p ())
15003 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15007 (define_expand "btrunc<mode>2"
15008 [(use (match_operand:MODEF 0 "register_operand" ""))
15009 (use (match_operand:MODEF 1 "register_operand" ""))]
15010 "(TARGET_USE_FANCY_MATH_387
15011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15012 || TARGET_MIX_SSE_I387)
15013 && flag_unsafe_math_optimizations)
15014 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15015 && !flag_trapping_math)"
15017 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15018 && !flag_trapping_math
15019 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15022 emit_insn (gen_sse4_1_round<mode>2
15023 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15024 else if (optimize_insn_for_size_p ())
15026 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15027 ix86_expand_trunc (operand0, operand1);
15029 ix86_expand_truncdf_32 (operand0, operand1);
15035 if (optimize_insn_for_size_p ())
15038 op0 = gen_reg_rtx (XFmode);
15039 op1 = gen_reg_rtx (XFmode);
15040 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15041 emit_insn (gen_frndintxf2_trunc (op0, op1));
15043 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15048 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15049 (define_insn_and_split "frndintxf2_mask_pm"
15050 [(set (match_operand:XF 0 "register_operand" "")
15051 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15052 UNSPEC_FRNDINT_MASK_PM))
15053 (clobber (reg:CC FLAGS_REG))]
15054 "TARGET_USE_FANCY_MATH_387
15055 && flag_unsafe_math_optimizations
15056 && can_create_pseudo_p ()"
15061 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15063 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15064 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15066 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15067 operands[2], operands[3]));
15070 [(set_attr "type" "frndint")
15071 (set_attr "i387_cw" "mask_pm")
15072 (set_attr "mode" "XF")])
15074 (define_insn "frndintxf2_mask_pm_i387"
15075 [(set (match_operand:XF 0 "register_operand" "=f")
15076 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15077 UNSPEC_FRNDINT_MASK_PM))
15078 (use (match_operand:HI 2 "memory_operand" "m"))
15079 (use (match_operand:HI 3 "memory_operand" "m"))]
15080 "TARGET_USE_FANCY_MATH_387
15081 && flag_unsafe_math_optimizations"
15082 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15083 [(set_attr "type" "frndint")
15084 (set_attr "i387_cw" "mask_pm")
15085 (set_attr "mode" "XF")])
15087 (define_expand "nearbyintxf2"
15088 [(use (match_operand:XF 0 "register_operand" ""))
15089 (use (match_operand:XF 1 "register_operand" ""))]
15090 "TARGET_USE_FANCY_MATH_387
15091 && flag_unsafe_math_optimizations"
15093 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15097 (define_expand "nearbyint<mode>2"
15098 [(use (match_operand:MODEF 0 "register_operand" ""))
15099 (use (match_operand:MODEF 1 "register_operand" ""))]
15100 "TARGET_USE_FANCY_MATH_387
15101 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15102 || TARGET_MIX_SSE_I387)
15103 && flag_unsafe_math_optimizations"
15105 rtx op0 = gen_reg_rtx (XFmode);
15106 rtx op1 = gen_reg_rtx (XFmode);
15108 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15109 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15111 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15115 (define_insn "fxam<mode>2_i387"
15116 [(set (match_operand:HI 0 "register_operand" "=a")
15118 [(match_operand:X87MODEF 1 "register_operand" "f")]
15120 "TARGET_USE_FANCY_MATH_387"
15121 "fxam\n\tfnstsw\t%0"
15122 [(set_attr "type" "multi")
15123 (set_attr "length" "4")
15124 (set_attr "unit" "i387")
15125 (set_attr "mode" "<MODE>")])
15127 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15128 [(set (match_operand:HI 0 "register_operand" "")
15130 [(match_operand:MODEF 1 "memory_operand" "")]
15132 "TARGET_USE_FANCY_MATH_387
15133 && can_create_pseudo_p ()"
15136 [(set (match_dup 2)(match_dup 1))
15138 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15140 operands[2] = gen_reg_rtx (<MODE>mode);
15142 MEM_VOLATILE_P (operands[1]) = 1;
15144 [(set_attr "type" "multi")
15145 (set_attr "unit" "i387")
15146 (set_attr "mode" "<MODE>")])
15148 (define_expand "isinfxf2"
15149 [(use (match_operand:SI 0 "register_operand" ""))
15150 (use (match_operand:XF 1 "register_operand" ""))]
15151 "TARGET_USE_FANCY_MATH_387
15152 && TARGET_C99_FUNCTIONS"
15154 rtx mask = GEN_INT (0x45);
15155 rtx val = GEN_INT (0x05);
15159 rtx scratch = gen_reg_rtx (HImode);
15160 rtx res = gen_reg_rtx (QImode);
15162 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15164 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15165 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15166 cond = gen_rtx_fmt_ee (EQ, QImode,
15167 gen_rtx_REG (CCmode, FLAGS_REG),
15169 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15170 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15174 (define_expand "isinf<mode>2"
15175 [(use (match_operand:SI 0 "register_operand" ""))
15176 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15177 "TARGET_USE_FANCY_MATH_387
15178 && TARGET_C99_FUNCTIONS
15179 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15181 rtx mask = GEN_INT (0x45);
15182 rtx val = GEN_INT (0x05);
15186 rtx scratch = gen_reg_rtx (HImode);
15187 rtx res = gen_reg_rtx (QImode);
15189 /* Remove excess precision by forcing value through memory. */
15190 if (memory_operand (operands[1], VOIDmode))
15191 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15194 enum ix86_stack_slot slot = (virtuals_instantiated
15197 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15199 emit_move_insn (temp, operands[1]);
15200 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15203 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15204 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15205 cond = gen_rtx_fmt_ee (EQ, QImode,
15206 gen_rtx_REG (CCmode, FLAGS_REG),
15208 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15209 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15213 (define_expand "signbitxf2"
15214 [(use (match_operand:SI 0 "register_operand" ""))
15215 (use (match_operand:XF 1 "register_operand" ""))]
15216 "TARGET_USE_FANCY_MATH_387"
15218 rtx scratch = gen_reg_rtx (HImode);
15220 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15221 emit_insn (gen_andsi3 (operands[0],
15222 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15226 (define_insn "movmsk_df"
15227 [(set (match_operand:SI 0 "register_operand" "=r")
15229 [(match_operand:DF 1 "register_operand" "x")]
15231 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15232 "%vmovmskpd\t{%1, %0|%0, %1}"
15233 [(set_attr "type" "ssemov")
15234 (set_attr "prefix" "maybe_vex")
15235 (set_attr "mode" "DF")])
15237 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15238 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15239 (define_expand "signbitdf2"
15240 [(use (match_operand:SI 0 "register_operand" ""))
15241 (use (match_operand:DF 1 "register_operand" ""))]
15242 "TARGET_USE_FANCY_MATH_387
15243 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15245 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15247 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15248 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15252 rtx scratch = gen_reg_rtx (HImode);
15254 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15255 emit_insn (gen_andsi3 (operands[0],
15256 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15261 (define_expand "signbitsf2"
15262 [(use (match_operand:SI 0 "register_operand" ""))
15263 (use (match_operand:SF 1 "register_operand" ""))]
15264 "TARGET_USE_FANCY_MATH_387
15265 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15267 rtx scratch = gen_reg_rtx (HImode);
15269 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15270 emit_insn (gen_andsi3 (operands[0],
15271 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15275 ;; Block operation instructions
15278 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15281 [(set_attr "length" "1")
15282 (set_attr "length_immediate" "0")
15283 (set_attr "modrm" "0")])
15285 (define_expand "movmem<mode>"
15286 [(use (match_operand:BLK 0 "memory_operand" ""))
15287 (use (match_operand:BLK 1 "memory_operand" ""))
15288 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15289 (use (match_operand:SWI48 3 "const_int_operand" ""))
15290 (use (match_operand:SI 4 "const_int_operand" ""))
15291 (use (match_operand:SI 5 "const_int_operand" ""))]
15294 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15295 operands[4], operands[5]))
15301 ;; Most CPUs don't like single string operations
15302 ;; Handle this case here to simplify previous expander.
15304 (define_expand "strmov"
15305 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15306 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15307 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15308 (clobber (reg:CC FLAGS_REG))])
15309 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15310 (clobber (reg:CC FLAGS_REG))])]
15313 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15315 /* If .md ever supports :P for Pmode, these can be directly
15316 in the pattern above. */
15317 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15318 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15320 /* Can't use this if the user has appropriated esi or edi. */
15321 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15322 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15324 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15325 operands[2], operands[3],
15326 operands[5], operands[6]));
15330 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15333 (define_expand "strmov_singleop"
15334 [(parallel [(set (match_operand 1 "memory_operand" "")
15335 (match_operand 3 "memory_operand" ""))
15336 (set (match_operand 0 "register_operand" "")
15337 (match_operand 4 "" ""))
15338 (set (match_operand 2 "register_operand" "")
15339 (match_operand 5 "" ""))])]
15341 "ix86_current_function_needs_cld = 1;")
15343 (define_insn "*strmovdi_rex_1"
15344 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15345 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15346 (set (match_operand:DI 0 "register_operand" "=D")
15347 (plus:DI (match_dup 2)
15349 (set (match_operand:DI 1 "register_operand" "=S")
15350 (plus:DI (match_dup 3)
15354 [(set_attr "type" "str")
15355 (set_attr "memory" "both")
15356 (set_attr "mode" "DI")])
15358 (define_insn "*strmovsi_1"
15359 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15360 (mem:SI (match_operand:P 3 "register_operand" "1")))
15361 (set (match_operand:P 0 "register_operand" "=D")
15362 (plus:P (match_dup 2)
15364 (set (match_operand:P 1 "register_operand" "=S")
15365 (plus:P (match_dup 3)
15369 [(set_attr "type" "str")
15370 (set_attr "memory" "both")
15371 (set_attr "mode" "SI")])
15373 (define_insn "*strmovhi_1"
15374 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15375 (mem:HI (match_operand:P 3 "register_operand" "1")))
15376 (set (match_operand:P 0 "register_operand" "=D")
15377 (plus:P (match_dup 2)
15379 (set (match_operand:P 1 "register_operand" "=S")
15380 (plus:P (match_dup 3)
15384 [(set_attr "type" "str")
15385 (set_attr "memory" "both")
15386 (set_attr "mode" "HI")])
15388 (define_insn "*strmovqi_1"
15389 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15390 (mem:QI (match_operand:P 3 "register_operand" "1")))
15391 (set (match_operand:P 0 "register_operand" "=D")
15392 (plus:P (match_dup 2)
15394 (set (match_operand:P 1 "register_operand" "=S")
15395 (plus:P (match_dup 3)
15399 [(set_attr "type" "str")
15400 (set_attr "memory" "both")
15401 (set (attr "prefix_rex")
15403 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15405 (const_string "*")))
15406 (set_attr "mode" "QI")])
15408 (define_expand "rep_mov"
15409 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15410 (set (match_operand 0 "register_operand" "")
15411 (match_operand 5 "" ""))
15412 (set (match_operand 2 "register_operand" "")
15413 (match_operand 6 "" ""))
15414 (set (match_operand 1 "memory_operand" "")
15415 (match_operand 3 "memory_operand" ""))
15416 (use (match_dup 4))])]
15418 "ix86_current_function_needs_cld = 1;")
15420 (define_insn "*rep_movdi_rex64"
15421 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15422 (set (match_operand:DI 0 "register_operand" "=D")
15423 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15425 (match_operand:DI 3 "register_operand" "0")))
15426 (set (match_operand:DI 1 "register_operand" "=S")
15427 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15428 (match_operand:DI 4 "register_operand" "1")))
15429 (set (mem:BLK (match_dup 3))
15430 (mem:BLK (match_dup 4)))
15431 (use (match_dup 5))]
15434 [(set_attr "type" "str")
15435 (set_attr "prefix_rep" "1")
15436 (set_attr "memory" "both")
15437 (set_attr "mode" "DI")])
15439 (define_insn "*rep_movsi"
15440 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15441 (set (match_operand:P 0 "register_operand" "=D")
15442 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15444 (match_operand:P 3 "register_operand" "0")))
15445 (set (match_operand:P 1 "register_operand" "=S")
15446 (plus:P (ashift:P (match_dup 5) (const_int 2))
15447 (match_operand:P 4 "register_operand" "1")))
15448 (set (mem:BLK (match_dup 3))
15449 (mem:BLK (match_dup 4)))
15450 (use (match_dup 5))]
15452 "rep{%;} movs{l|d}"
15453 [(set_attr "type" "str")
15454 (set_attr "prefix_rep" "1")
15455 (set_attr "memory" "both")
15456 (set_attr "mode" "SI")])
15458 (define_insn "*rep_movqi"
15459 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15460 (set (match_operand:P 0 "register_operand" "=D")
15461 (plus:P (match_operand:P 3 "register_operand" "0")
15462 (match_operand:P 5 "register_operand" "2")))
15463 (set (match_operand:P 1 "register_operand" "=S")
15464 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15465 (set (mem:BLK (match_dup 3))
15466 (mem:BLK (match_dup 4)))
15467 (use (match_dup 5))]
15470 [(set_attr "type" "str")
15471 (set_attr "prefix_rep" "1")
15472 (set_attr "memory" "both")
15473 (set_attr "mode" "QI")])
15475 (define_expand "setmem<mode>"
15476 [(use (match_operand:BLK 0 "memory_operand" ""))
15477 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15478 (use (match_operand:QI 2 "nonmemory_operand" ""))
15479 (use (match_operand 3 "const_int_operand" ""))
15480 (use (match_operand:SI 4 "const_int_operand" ""))
15481 (use (match_operand:SI 5 "const_int_operand" ""))]
15484 if (ix86_expand_setmem (operands[0], operands[1],
15485 operands[2], operands[3],
15486 operands[4], operands[5]))
15492 ;; Most CPUs don't like single string operations
15493 ;; Handle this case here to simplify previous expander.
15495 (define_expand "strset"
15496 [(set (match_operand 1 "memory_operand" "")
15497 (match_operand 2 "register_operand" ""))
15498 (parallel [(set (match_operand 0 "register_operand" "")
15500 (clobber (reg:CC FLAGS_REG))])]
15503 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15504 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15506 /* If .md ever supports :P for Pmode, this can be directly
15507 in the pattern above. */
15508 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15509 GEN_INT (GET_MODE_SIZE (GET_MODE
15511 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15513 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15519 (define_expand "strset_singleop"
15520 [(parallel [(set (match_operand 1 "memory_operand" "")
15521 (match_operand 2 "register_operand" ""))
15522 (set (match_operand 0 "register_operand" "")
15523 (match_operand 3 "" ""))])]
15525 "ix86_current_function_needs_cld = 1;")
15527 (define_insn "*strsetdi_rex_1"
15528 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15529 (match_operand:DI 2 "register_operand" "a"))
15530 (set (match_operand:DI 0 "register_operand" "=D")
15531 (plus:DI (match_dup 1)
15535 [(set_attr "type" "str")
15536 (set_attr "memory" "store")
15537 (set_attr "mode" "DI")])
15539 (define_insn "*strsetsi_1"
15540 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15541 (match_operand:SI 2 "register_operand" "a"))
15542 (set (match_operand:P 0 "register_operand" "=D")
15543 (plus:P (match_dup 1)
15547 [(set_attr "type" "str")
15548 (set_attr "memory" "store")
15549 (set_attr "mode" "SI")])
15551 (define_insn "*strsethi_1"
15552 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15553 (match_operand:HI 2 "register_operand" "a"))
15554 (set (match_operand:P 0 "register_operand" "=D")
15555 (plus:P (match_dup 1)
15559 [(set_attr "type" "str")
15560 (set_attr "memory" "store")
15561 (set_attr "mode" "HI")])
15563 (define_insn "*strsetqi_1"
15564 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15565 (match_operand:QI 2 "register_operand" "a"))
15566 (set (match_operand:P 0 "register_operand" "=D")
15567 (plus:P (match_dup 1)
15571 [(set_attr "type" "str")
15572 (set_attr "memory" "store")
15573 (set (attr "prefix_rex")
15575 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15577 (const_string "*")))
15578 (set_attr "mode" "QI")])
15580 (define_expand "rep_stos"
15581 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15582 (set (match_operand 0 "register_operand" "")
15583 (match_operand 4 "" ""))
15584 (set (match_operand 2 "memory_operand" "") (const_int 0))
15585 (use (match_operand 3 "register_operand" ""))
15586 (use (match_dup 1))])]
15588 "ix86_current_function_needs_cld = 1;")
15590 (define_insn "*rep_stosdi_rex64"
15591 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15592 (set (match_operand:DI 0 "register_operand" "=D")
15593 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15595 (match_operand:DI 3 "register_operand" "0")))
15596 (set (mem:BLK (match_dup 3))
15598 (use (match_operand:DI 2 "register_operand" "a"))
15599 (use (match_dup 4))]
15602 [(set_attr "type" "str")
15603 (set_attr "prefix_rep" "1")
15604 (set_attr "memory" "store")
15605 (set_attr "mode" "DI")])
15607 (define_insn "*rep_stossi"
15608 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15609 (set (match_operand:P 0 "register_operand" "=D")
15610 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15612 (match_operand:P 3 "register_operand" "0")))
15613 (set (mem:BLK (match_dup 3))
15615 (use (match_operand:SI 2 "register_operand" "a"))
15616 (use (match_dup 4))]
15618 "rep{%;} stos{l|d}"
15619 [(set_attr "type" "str")
15620 (set_attr "prefix_rep" "1")
15621 (set_attr "memory" "store")
15622 (set_attr "mode" "SI")])
15624 (define_insn "*rep_stosqi"
15625 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15626 (set (match_operand:P 0 "register_operand" "=D")
15627 (plus:P (match_operand:P 3 "register_operand" "0")
15628 (match_operand:P 4 "register_operand" "1")))
15629 (set (mem:BLK (match_dup 3))
15631 (use (match_operand:QI 2 "register_operand" "a"))
15632 (use (match_dup 4))]
15635 [(set_attr "type" "str")
15636 (set_attr "prefix_rep" "1")
15637 (set_attr "memory" "store")
15638 (set (attr "prefix_rex")
15640 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15642 (const_string "*")))
15643 (set_attr "mode" "QI")])
15645 (define_expand "cmpstrnsi"
15646 [(set (match_operand:SI 0 "register_operand" "")
15647 (compare:SI (match_operand:BLK 1 "general_operand" "")
15648 (match_operand:BLK 2 "general_operand" "")))
15649 (use (match_operand 3 "general_operand" ""))
15650 (use (match_operand 4 "immediate_operand" ""))]
15653 rtx addr1, addr2, out, outlow, count, countreg, align;
15655 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15658 /* Can't use this if the user has appropriated esi or edi. */
15659 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15664 out = gen_reg_rtx (SImode);
15666 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15667 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15668 if (addr1 != XEXP (operands[1], 0))
15669 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15670 if (addr2 != XEXP (operands[2], 0))
15671 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15673 count = operands[3];
15674 countreg = ix86_zero_extend_to_Pmode (count);
15676 /* %%% Iff we are testing strict equality, we can use known alignment
15677 to good advantage. This may be possible with combine, particularly
15678 once cc0 is dead. */
15679 align = operands[4];
15681 if (CONST_INT_P (count))
15683 if (INTVAL (count) == 0)
15685 emit_move_insn (operands[0], const0_rtx);
15688 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15689 operands[1], operands[2]));
15693 rtx (*gen_cmp) (rtx, rtx);
15695 gen_cmp = (TARGET_64BIT
15696 ? gen_cmpdi_1 : gen_cmpsi_1);
15698 emit_insn (gen_cmp (countreg, countreg));
15699 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15700 operands[1], operands[2]));
15703 outlow = gen_lowpart (QImode, out);
15704 emit_insn (gen_cmpintqi (outlow));
15705 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15707 if (operands[0] != out)
15708 emit_move_insn (operands[0], out);
15713 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15715 (define_expand "cmpintqi"
15716 [(set (match_dup 1)
15717 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15719 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15720 (parallel [(set (match_operand:QI 0 "register_operand" "")
15721 (minus:QI (match_dup 1)
15723 (clobber (reg:CC FLAGS_REG))])]
15726 operands[1] = gen_reg_rtx (QImode);
15727 operands[2] = gen_reg_rtx (QImode);
15730 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15731 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15733 (define_expand "cmpstrnqi_nz_1"
15734 [(parallel [(set (reg:CC FLAGS_REG)
15735 (compare:CC (match_operand 4 "memory_operand" "")
15736 (match_operand 5 "memory_operand" "")))
15737 (use (match_operand 2 "register_operand" ""))
15738 (use (match_operand:SI 3 "immediate_operand" ""))
15739 (clobber (match_operand 0 "register_operand" ""))
15740 (clobber (match_operand 1 "register_operand" ""))
15741 (clobber (match_dup 2))])]
15743 "ix86_current_function_needs_cld = 1;")
15745 (define_insn "*cmpstrnqi_nz_1"
15746 [(set (reg:CC FLAGS_REG)
15747 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15748 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15749 (use (match_operand:P 6 "register_operand" "2"))
15750 (use (match_operand:SI 3 "immediate_operand" "i"))
15751 (clobber (match_operand:P 0 "register_operand" "=S"))
15752 (clobber (match_operand:P 1 "register_operand" "=D"))
15753 (clobber (match_operand:P 2 "register_operand" "=c"))]
15756 [(set_attr "type" "str")
15757 (set_attr "mode" "QI")
15758 (set (attr "prefix_rex")
15760 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15762 (const_string "*")))
15763 (set_attr "prefix_rep" "1")])
15765 ;; The same, but the count is not known to not be zero.
15767 (define_expand "cmpstrnqi_1"
15768 [(parallel [(set (reg:CC FLAGS_REG)
15769 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15771 (compare:CC (match_operand 4 "memory_operand" "")
15772 (match_operand 5 "memory_operand" ""))
15774 (use (match_operand:SI 3 "immediate_operand" ""))
15775 (use (reg:CC FLAGS_REG))
15776 (clobber (match_operand 0 "register_operand" ""))
15777 (clobber (match_operand 1 "register_operand" ""))
15778 (clobber (match_dup 2))])]
15780 "ix86_current_function_needs_cld = 1;")
15782 (define_insn "*cmpstrnqi_1"
15783 [(set (reg:CC FLAGS_REG)
15784 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15786 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15787 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15789 (use (match_operand:SI 3 "immediate_operand" "i"))
15790 (use (reg:CC FLAGS_REG))
15791 (clobber (match_operand:P 0 "register_operand" "=S"))
15792 (clobber (match_operand:P 1 "register_operand" "=D"))
15793 (clobber (match_operand:P 2 "register_operand" "=c"))]
15796 [(set_attr "type" "str")
15797 (set_attr "mode" "QI")
15798 (set (attr "prefix_rex")
15800 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15802 (const_string "*")))
15803 (set_attr "prefix_rep" "1")])
15805 (define_expand "strlen<mode>"
15806 [(set (match_operand:SWI48x 0 "register_operand" "")
15807 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15808 (match_operand:QI 2 "immediate_operand" "")
15809 (match_operand 3 "immediate_operand" "")]
15813 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15819 (define_expand "strlenqi_1"
15820 [(parallel [(set (match_operand 0 "register_operand" "")
15821 (match_operand 2 "" ""))
15822 (clobber (match_operand 1 "register_operand" ""))
15823 (clobber (reg:CC FLAGS_REG))])]
15825 "ix86_current_function_needs_cld = 1;")
15827 (define_insn "*strlenqi_1"
15828 [(set (match_operand:P 0 "register_operand" "=&c")
15829 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15830 (match_operand:QI 2 "register_operand" "a")
15831 (match_operand:P 3 "immediate_operand" "i")
15832 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15833 (clobber (match_operand:P 1 "register_operand" "=D"))
15834 (clobber (reg:CC FLAGS_REG))]
15837 [(set_attr "type" "str")
15838 (set_attr "mode" "QI")
15839 (set (attr "prefix_rex")
15841 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15843 (const_string "*")))
15844 (set_attr "prefix_rep" "1")])
15846 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15847 ;; handled in combine, but it is not currently up to the task.
15848 ;; When used for their truth value, the cmpstrn* expanders generate
15857 ;; The intermediate three instructions are unnecessary.
15859 ;; This one handles cmpstrn*_nz_1...
15862 (set (reg:CC FLAGS_REG)
15863 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15864 (mem:BLK (match_operand 5 "register_operand" ""))))
15865 (use (match_operand 6 "register_operand" ""))
15866 (use (match_operand:SI 3 "immediate_operand" ""))
15867 (clobber (match_operand 0 "register_operand" ""))
15868 (clobber (match_operand 1 "register_operand" ""))
15869 (clobber (match_operand 2 "register_operand" ""))])
15870 (set (match_operand:QI 7 "register_operand" "")
15871 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15872 (set (match_operand:QI 8 "register_operand" "")
15873 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15874 (set (reg FLAGS_REG)
15875 (compare (match_dup 7) (match_dup 8)))
15877 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15879 (set (reg:CC FLAGS_REG)
15880 (compare:CC (mem:BLK (match_dup 4))
15881 (mem:BLK (match_dup 5))))
15882 (use (match_dup 6))
15883 (use (match_dup 3))
15884 (clobber (match_dup 0))
15885 (clobber (match_dup 1))
15886 (clobber (match_dup 2))])])
15888 ;; ...and this one handles cmpstrn*_1.
15891 (set (reg:CC FLAGS_REG)
15892 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15894 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15895 (mem:BLK (match_operand 5 "register_operand" "")))
15897 (use (match_operand:SI 3 "immediate_operand" ""))
15898 (use (reg:CC FLAGS_REG))
15899 (clobber (match_operand 0 "register_operand" ""))
15900 (clobber (match_operand 1 "register_operand" ""))
15901 (clobber (match_operand 2 "register_operand" ""))])
15902 (set (match_operand:QI 7 "register_operand" "")
15903 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15904 (set (match_operand:QI 8 "register_operand" "")
15905 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15906 (set (reg FLAGS_REG)
15907 (compare (match_dup 7) (match_dup 8)))
15909 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15911 (set (reg:CC FLAGS_REG)
15912 (if_then_else:CC (ne (match_dup 6)
15914 (compare:CC (mem:BLK (match_dup 4))
15915 (mem:BLK (match_dup 5)))
15917 (use (match_dup 3))
15918 (use (reg:CC FLAGS_REG))
15919 (clobber (match_dup 0))
15920 (clobber (match_dup 1))
15921 (clobber (match_dup 2))])])
15923 ;; Conditional move instructions.
15925 (define_expand "mov<mode>cc"
15926 [(set (match_operand:SWIM 0 "register_operand" "")
15927 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15928 (match_operand:SWIM 2 "general_operand" "")
15929 (match_operand:SWIM 3 "general_operand" "")))]
15931 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15933 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15934 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15935 ;; So just document what we're doing explicitly.
15937 (define_expand "x86_mov<mode>cc_0_m1"
15939 [(set (match_operand:SWI48 0 "register_operand" "")
15940 (if_then_else:SWI48
15941 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15942 [(match_operand 1 "flags_reg_operand" "")
15946 (clobber (reg:CC FLAGS_REG))])])
15948 (define_insn "*x86_mov<mode>cc_0_m1"
15949 [(set (match_operand:SWI48 0 "register_operand" "=r")
15950 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15951 [(reg FLAGS_REG) (const_int 0)])
15954 (clobber (reg:CC FLAGS_REG))]
15956 "sbb{<imodesuffix>}\t%0, %0"
15957 ; Since we don't have the proper number of operands for an alu insn,
15958 ; fill in all the blanks.
15959 [(set_attr "type" "alu")
15960 (set_attr "use_carry" "1")
15961 (set_attr "pent_pair" "pu")
15962 (set_attr "memory" "none")
15963 (set_attr "imm_disp" "false")
15964 (set_attr "mode" "<MODE>")
15965 (set_attr "length_immediate" "0")])
15967 (define_insn "*x86_mov<mode>cc_0_m1_se"
15968 [(set (match_operand:SWI48 0 "register_operand" "=r")
15969 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15970 [(reg FLAGS_REG) (const_int 0)])
15973 (clobber (reg:CC FLAGS_REG))]
15975 "sbb{<imodesuffix>}\t%0, %0"
15976 [(set_attr "type" "alu")
15977 (set_attr "use_carry" "1")
15978 (set_attr "pent_pair" "pu")
15979 (set_attr "memory" "none")
15980 (set_attr "imm_disp" "false")
15981 (set_attr "mode" "<MODE>")
15982 (set_attr "length_immediate" "0")])
15984 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15985 [(set (match_operand:SWI48 0 "register_operand" "=r")
15986 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15987 [(reg FLAGS_REG) (const_int 0)])))]
15989 "sbb{<imodesuffix>}\t%0, %0"
15990 [(set_attr "type" "alu")
15991 (set_attr "use_carry" "1")
15992 (set_attr "pent_pair" "pu")
15993 (set_attr "memory" "none")
15994 (set_attr "imm_disp" "false")
15995 (set_attr "mode" "<MODE>")
15996 (set_attr "length_immediate" "0")])
15998 (define_insn "*mov<mode>cc_noc"
15999 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16000 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16001 [(reg FLAGS_REG) (const_int 0)])
16002 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16003 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16004 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16006 cmov%O2%C1\t{%2, %0|%0, %2}
16007 cmov%O2%c1\t{%3, %0|%0, %3}"
16008 [(set_attr "type" "icmov")
16009 (set_attr "mode" "<MODE>")])
16011 (define_insn_and_split "*movqicc_noc"
16012 [(set (match_operand:QI 0 "register_operand" "=r,r")
16013 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16014 [(match_operand 4 "flags_reg_operand" "")
16016 (match_operand:QI 2 "register_operand" "r,0")
16017 (match_operand:QI 3 "register_operand" "0,r")))]
16018 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16020 "&& reload_completed"
16021 [(set (match_dup 0)
16022 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16025 "operands[0] = gen_lowpart (SImode, operands[0]);
16026 operands[2] = gen_lowpart (SImode, operands[2]);
16027 operands[3] = gen_lowpart (SImode, operands[3]);"
16028 [(set_attr "type" "icmov")
16029 (set_attr "mode" "SI")])
16031 (define_expand "mov<mode>cc"
16032 [(set (match_operand:X87MODEF 0 "register_operand" "")
16033 (if_then_else:X87MODEF
16034 (match_operand 1 "ix86_fp_comparison_operator" "")
16035 (match_operand:X87MODEF 2 "register_operand" "")
16036 (match_operand:X87MODEF 3 "register_operand" "")))]
16037 "(TARGET_80387 && TARGET_CMOVE)
16038 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16039 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16041 (define_insn "*movxfcc_1"
16042 [(set (match_operand:XF 0 "register_operand" "=f,f")
16043 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16044 [(reg FLAGS_REG) (const_int 0)])
16045 (match_operand:XF 2 "register_operand" "f,0")
16046 (match_operand:XF 3 "register_operand" "0,f")))]
16047 "TARGET_80387 && TARGET_CMOVE"
16049 fcmov%F1\t{%2, %0|%0, %2}
16050 fcmov%f1\t{%3, %0|%0, %3}"
16051 [(set_attr "type" "fcmov")
16052 (set_attr "mode" "XF")])
16054 (define_insn "*movdfcc_1_rex64"
16055 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16056 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16057 [(reg FLAGS_REG) (const_int 0)])
16058 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16059 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16060 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16061 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16063 fcmov%F1\t{%2, %0|%0, %2}
16064 fcmov%f1\t{%3, %0|%0, %3}
16065 cmov%O2%C1\t{%2, %0|%0, %2}
16066 cmov%O2%c1\t{%3, %0|%0, %3}"
16067 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16068 (set_attr "mode" "DF,DF,DI,DI")])
16070 (define_insn "*movdfcc_1"
16071 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16072 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16073 [(reg FLAGS_REG) (const_int 0)])
16074 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16075 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16076 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16077 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16079 fcmov%F1\t{%2, %0|%0, %2}
16080 fcmov%f1\t{%3, %0|%0, %3}
16083 [(set_attr "type" "fcmov,fcmov,multi,multi")
16084 (set_attr "mode" "DF,DF,DI,DI")])
16087 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16088 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16089 [(match_operand 4 "flags_reg_operand" "")
16091 (match_operand:DF 2 "nonimmediate_operand" "")
16092 (match_operand:DF 3 "nonimmediate_operand" "")))]
16093 "!TARGET_64BIT && reload_completed"
16094 [(set (match_dup 2)
16095 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16099 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16103 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16104 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16107 (define_insn "*movsfcc_1_387"
16108 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16109 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16110 [(reg FLAGS_REG) (const_int 0)])
16111 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16112 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16113 "TARGET_80387 && TARGET_CMOVE
16114 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16116 fcmov%F1\t{%2, %0|%0, %2}
16117 fcmov%f1\t{%3, %0|%0, %3}
16118 cmov%O2%C1\t{%2, %0|%0, %2}
16119 cmov%O2%c1\t{%3, %0|%0, %3}"
16120 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16121 (set_attr "mode" "SF,SF,SI,SI")])
16123 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16124 ;; the scalar versions to have only XMM registers as operands.
16126 ;; XOP conditional move
16127 (define_insn "*xop_pcmov_<mode>"
16128 [(set (match_operand:MODEF 0 "register_operand" "=x")
16129 (if_then_else:MODEF
16130 (match_operand:MODEF 1 "register_operand" "x")
16131 (match_operand:MODEF 2 "register_operand" "x")
16132 (match_operand:MODEF 3 "register_operand" "x")))]
16134 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16135 [(set_attr "type" "sse4arg")])
16137 ;; These versions of the min/max patterns are intentionally ignorant of
16138 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16139 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16140 ;; are undefined in this condition, we're certain this is correct.
16142 (define_insn "<code><mode>3"
16143 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16145 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16146 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16147 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16149 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16150 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16151 [(set_attr "isa" "noavx,avx")
16152 (set_attr "prefix" "orig,vex")
16153 (set_attr "type" "sseadd")
16154 (set_attr "mode" "<MODE>")])
16156 ;; These versions of the min/max patterns implement exactly the operations
16157 ;; min = (op1 < op2 ? op1 : op2)
16158 ;; max = (!(op1 < op2) ? op1 : op2)
16159 ;; Their operands are not commutative, and thus they may be used in the
16160 ;; presence of -0.0 and NaN.
16162 (define_insn "*ieee_smin<mode>3"
16163 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16165 [(match_operand:MODEF 1 "register_operand" "0,x")
16166 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16168 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16170 min<ssemodesuffix>\t{%2, %0|%0, %2}
16171 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16172 [(set_attr "isa" "noavx,avx")
16173 (set_attr "prefix" "orig,vex")
16174 (set_attr "type" "sseadd")
16175 (set_attr "mode" "<MODE>")])
16177 (define_insn "*ieee_smax<mode>3"
16178 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16180 [(match_operand:MODEF 1 "register_operand" "0,x")
16181 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16183 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16185 max<ssemodesuffix>\t{%2, %0|%0, %2}
16186 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16187 [(set_attr "isa" "noavx,avx")
16188 (set_attr "prefix" "orig,vex")
16189 (set_attr "type" "sseadd")
16190 (set_attr "mode" "<MODE>")])
16192 ;; Make two stack loads independent:
16194 ;; fld %st(0) -> fld bb
16195 ;; fmul bb fmul %st(1), %st
16197 ;; Actually we only match the last two instructions for simplicity.
16199 [(set (match_operand 0 "fp_register_operand" "")
16200 (match_operand 1 "fp_register_operand" ""))
16202 (match_operator 2 "binary_fp_operator"
16204 (match_operand 3 "memory_operand" "")]))]
16205 "REGNO (operands[0]) != REGNO (operands[1])"
16206 [(set (match_dup 0) (match_dup 3))
16207 (set (match_dup 0) (match_dup 4))]
16209 ;; The % modifier is not operational anymore in peephole2's, so we have to
16210 ;; swap the operands manually in the case of addition and multiplication.
16211 "if (COMMUTATIVE_ARITH_P (operands[2]))
16212 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16213 GET_MODE (operands[2]),
16214 operands[0], operands[1]);
16216 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16217 GET_MODE (operands[2]),
16218 operands[1], operands[0]);")
16220 ;; Conditional addition patterns
16221 (define_expand "add<mode>cc"
16222 [(match_operand:SWI 0 "register_operand" "")
16223 (match_operand 1 "ordered_comparison_operator" "")
16224 (match_operand:SWI 2 "register_operand" "")
16225 (match_operand:SWI 3 "const_int_operand" "")]
16227 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16229 ;; Misc patterns (?)
16231 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16232 ;; Otherwise there will be nothing to keep
16234 ;; [(set (reg ebp) (reg esp))]
16235 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16236 ;; (clobber (eflags)]
16237 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16239 ;; in proper program order.
16241 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16242 [(set (match_operand:P 0 "register_operand" "=r,r")
16243 (plus:P (match_operand:P 1 "register_operand" "0,r")
16244 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16245 (clobber (reg:CC FLAGS_REG))
16246 (clobber (mem:BLK (scratch)))]
16249 switch (get_attr_type (insn))
16252 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16255 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16256 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16257 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16259 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16262 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16263 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16266 [(set (attr "type")
16267 (cond [(and (eq_attr "alternative" "0")
16268 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16269 (const_string "alu")
16270 (match_operand:<MODE> 2 "const0_operand" "")
16271 (const_string "imov")
16273 (const_string "lea")))
16274 (set (attr "length_immediate")
16275 (cond [(eq_attr "type" "imov")
16277 (and (eq_attr "type" "alu")
16278 (match_operand 2 "const128_operand" ""))
16281 (const_string "*")))
16282 (set_attr "mode" "<MODE>")])
16284 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16285 [(set (match_operand:P 0 "register_operand" "=r")
16286 (minus:P (match_operand:P 1 "register_operand" "0")
16287 (match_operand:P 2 "register_operand" "r")))
16288 (clobber (reg:CC FLAGS_REG))
16289 (clobber (mem:BLK (scratch)))]
16291 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16292 [(set_attr "type" "alu")
16293 (set_attr "mode" "<MODE>")])
16295 (define_insn "allocate_stack_worker_probe_<mode>"
16296 [(set (match_operand:P 0 "register_operand" "=a")
16297 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16298 UNSPECV_STACK_PROBE))
16299 (clobber (reg:CC FLAGS_REG))]
16300 "ix86_target_stack_probe ()"
16301 "call\t___chkstk_ms"
16302 [(set_attr "type" "multi")
16303 (set_attr "length" "5")])
16305 (define_expand "allocate_stack"
16306 [(match_operand 0 "register_operand" "")
16307 (match_operand 1 "general_operand" "")]
16308 "ix86_target_stack_probe ()"
16312 #ifndef CHECK_STACK_LIMIT
16313 #define CHECK_STACK_LIMIT 0
16316 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16317 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16319 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16320 stack_pointer_rtx, 0, OPTAB_DIRECT);
16321 if (x != stack_pointer_rtx)
16322 emit_move_insn (stack_pointer_rtx, x);
16326 x = copy_to_mode_reg (Pmode, operands[1]);
16328 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16330 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16331 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16332 stack_pointer_rtx, 0, OPTAB_DIRECT);
16333 if (x != stack_pointer_rtx)
16334 emit_move_insn (stack_pointer_rtx, x);
16337 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16341 ;; Use IOR for stack probes, this is shorter.
16342 (define_expand "probe_stack"
16343 [(match_operand 0 "memory_operand" "")]
16346 rtx (*gen_ior3) (rtx, rtx, rtx);
16348 gen_ior3 = (GET_MODE (operands[0]) == DImode
16349 ? gen_iordi3 : gen_iorsi3);
16351 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16355 (define_insn "adjust_stack_and_probe<mode>"
16356 [(set (match_operand:P 0 "register_operand" "=r")
16357 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16358 UNSPECV_PROBE_STACK_RANGE))
16359 (set (reg:P SP_REG)
16360 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16361 (clobber (reg:CC FLAGS_REG))
16362 (clobber (mem:BLK (scratch)))]
16364 "* return output_adjust_stack_and_probe (operands[0]);"
16365 [(set_attr "type" "multi")])
16367 (define_insn "probe_stack_range<mode>"
16368 [(set (match_operand:P 0 "register_operand" "=r")
16369 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16370 (match_operand:P 2 "const_int_operand" "n")]
16371 UNSPECV_PROBE_STACK_RANGE))
16372 (clobber (reg:CC FLAGS_REG))]
16374 "* return output_probe_stack_range (operands[0], operands[2]);"
16375 [(set_attr "type" "multi")])
16377 (define_expand "builtin_setjmp_receiver"
16378 [(label_ref (match_operand 0 "" ""))]
16379 "!TARGET_64BIT && flag_pic"
16385 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16386 rtx label_rtx = gen_label_rtx ();
16387 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16388 xops[0] = xops[1] = picreg;
16389 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16390 ix86_expand_binary_operator (MINUS, SImode, xops);
16394 emit_insn (gen_set_got (pic_offset_table_rtx));
16398 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16401 [(set (match_operand 0 "register_operand" "")
16402 (match_operator 3 "promotable_binary_operator"
16403 [(match_operand 1 "register_operand" "")
16404 (match_operand 2 "aligned_operand" "")]))
16405 (clobber (reg:CC FLAGS_REG))]
16406 "! TARGET_PARTIAL_REG_STALL && reload_completed
16407 && ((GET_MODE (operands[0]) == HImode
16408 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16409 /* ??? next two lines just !satisfies_constraint_K (...) */
16410 || !CONST_INT_P (operands[2])
16411 || satisfies_constraint_K (operands[2])))
16412 || (GET_MODE (operands[0]) == QImode
16413 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16414 [(parallel [(set (match_dup 0)
16415 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16416 (clobber (reg:CC FLAGS_REG))])]
16417 "operands[0] = gen_lowpart (SImode, operands[0]);
16418 operands[1] = gen_lowpart (SImode, operands[1]);
16419 if (GET_CODE (operands[3]) != ASHIFT)
16420 operands[2] = gen_lowpart (SImode, operands[2]);
16421 PUT_MODE (operands[3], SImode);")
16423 ; Promote the QImode tests, as i386 has encoding of the AND
16424 ; instruction with 32-bit sign-extended immediate and thus the
16425 ; instruction size is unchanged, except in the %eax case for
16426 ; which it is increased by one byte, hence the ! optimize_size.
16428 [(set (match_operand 0 "flags_reg_operand" "")
16429 (match_operator 2 "compare_operator"
16430 [(and (match_operand 3 "aligned_operand" "")
16431 (match_operand 4 "const_int_operand" ""))
16433 (set (match_operand 1 "register_operand" "")
16434 (and (match_dup 3) (match_dup 4)))]
16435 "! TARGET_PARTIAL_REG_STALL && reload_completed
16436 && optimize_insn_for_speed_p ()
16437 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16438 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16439 /* Ensure that the operand will remain sign-extended immediate. */
16440 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16441 [(parallel [(set (match_dup 0)
16442 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16445 (and:SI (match_dup 3) (match_dup 4)))])]
16448 = gen_int_mode (INTVAL (operands[4])
16449 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16450 operands[1] = gen_lowpart (SImode, operands[1]);
16451 operands[3] = gen_lowpart (SImode, operands[3]);
16454 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16455 ; the TEST instruction with 32-bit sign-extended immediate and thus
16456 ; the instruction size would at least double, which is not what we
16457 ; want even with ! optimize_size.
16459 [(set (match_operand 0 "flags_reg_operand" "")
16460 (match_operator 1 "compare_operator"
16461 [(and (match_operand:HI 2 "aligned_operand" "")
16462 (match_operand:HI 3 "const_int_operand" ""))
16464 "! TARGET_PARTIAL_REG_STALL && reload_completed
16465 && ! TARGET_FAST_PREFIX
16466 && optimize_insn_for_speed_p ()
16467 /* Ensure that the operand will remain sign-extended immediate. */
16468 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16469 [(set (match_dup 0)
16470 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16474 = gen_int_mode (INTVAL (operands[3])
16475 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16476 operands[2] = gen_lowpart (SImode, operands[2]);
16480 [(set (match_operand 0 "register_operand" "")
16481 (neg (match_operand 1 "register_operand" "")))
16482 (clobber (reg:CC FLAGS_REG))]
16483 "! TARGET_PARTIAL_REG_STALL && reload_completed
16484 && (GET_MODE (operands[0]) == HImode
16485 || (GET_MODE (operands[0]) == QImode
16486 && (TARGET_PROMOTE_QImode
16487 || optimize_insn_for_size_p ())))"
16488 [(parallel [(set (match_dup 0)
16489 (neg:SI (match_dup 1)))
16490 (clobber (reg:CC FLAGS_REG))])]
16491 "operands[0] = gen_lowpart (SImode, operands[0]);
16492 operands[1] = gen_lowpart (SImode, operands[1]);")
16495 [(set (match_operand 0 "register_operand" "")
16496 (not (match_operand 1 "register_operand" "")))]
16497 "! TARGET_PARTIAL_REG_STALL && reload_completed
16498 && (GET_MODE (operands[0]) == HImode
16499 || (GET_MODE (operands[0]) == QImode
16500 && (TARGET_PROMOTE_QImode
16501 || optimize_insn_for_size_p ())))"
16502 [(set (match_dup 0)
16503 (not:SI (match_dup 1)))]
16504 "operands[0] = gen_lowpart (SImode, operands[0]);
16505 operands[1] = gen_lowpart (SImode, operands[1]);")
16508 [(set (match_operand 0 "register_operand" "")
16509 (if_then_else (match_operator 1 "ordered_comparison_operator"
16510 [(reg FLAGS_REG) (const_int 0)])
16511 (match_operand 2 "register_operand" "")
16512 (match_operand 3 "register_operand" "")))]
16513 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16514 && (GET_MODE (operands[0]) == HImode
16515 || (GET_MODE (operands[0]) == QImode
16516 && (TARGET_PROMOTE_QImode
16517 || optimize_insn_for_size_p ())))"
16518 [(set (match_dup 0)
16519 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16520 "operands[0] = gen_lowpart (SImode, operands[0]);
16521 operands[2] = gen_lowpart (SImode, operands[2]);
16522 operands[3] = gen_lowpart (SImode, operands[3]);")
16524 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16525 ;; transform a complex memory operation into two memory to register operations.
16527 ;; Don't push memory operands
16529 [(set (match_operand:SWI 0 "push_operand" "")
16530 (match_operand:SWI 1 "memory_operand" ""))
16531 (match_scratch:SWI 2 "<r>")]
16532 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16533 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16534 [(set (match_dup 2) (match_dup 1))
16535 (set (match_dup 0) (match_dup 2))])
16537 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16540 [(set (match_operand:SF 0 "push_operand" "")
16541 (match_operand:SF 1 "memory_operand" ""))
16542 (match_scratch:SF 2 "r")]
16543 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16544 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16545 [(set (match_dup 2) (match_dup 1))
16546 (set (match_dup 0) (match_dup 2))])
16548 ;; Don't move an immediate directly to memory when the instruction
16551 [(match_scratch:SWI124 1 "<r>")
16552 (set (match_operand:SWI124 0 "memory_operand" "")
16554 "optimize_insn_for_speed_p ()
16555 && !TARGET_USE_MOV0
16556 && TARGET_SPLIT_LONG_MOVES
16557 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16558 && peep2_regno_dead_p (0, FLAGS_REG)"
16559 [(parallel [(set (match_dup 2) (const_int 0))
16560 (clobber (reg:CC FLAGS_REG))])
16561 (set (match_dup 0) (match_dup 1))]
16562 "operands[2] = gen_lowpart (SImode, operands[1]);")
16565 [(match_scratch:SWI124 2 "<r>")
16566 (set (match_operand:SWI124 0 "memory_operand" "")
16567 (match_operand:SWI124 1 "immediate_operand" ""))]
16568 "optimize_insn_for_speed_p ()
16569 && TARGET_SPLIT_LONG_MOVES
16570 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16571 [(set (match_dup 2) (match_dup 1))
16572 (set (match_dup 0) (match_dup 2))])
16574 ;; Don't compare memory with zero, load and use a test instead.
16576 [(set (match_operand 0 "flags_reg_operand" "")
16577 (match_operator 1 "compare_operator"
16578 [(match_operand:SI 2 "memory_operand" "")
16580 (match_scratch:SI 3 "r")]
16581 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16582 [(set (match_dup 3) (match_dup 2))
16583 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16585 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16586 ;; Don't split NOTs with a displacement operand, because resulting XOR
16587 ;; will not be pairable anyway.
16589 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16590 ;; represented using a modRM byte. The XOR replacement is long decoded,
16591 ;; so this split helps here as well.
16593 ;; Note: Can't do this as a regular split because we can't get proper
16594 ;; lifetime information then.
16597 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16598 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16599 "optimize_insn_for_speed_p ()
16600 && ((TARGET_NOT_UNPAIRABLE
16601 && (!MEM_P (operands[0])
16602 || !memory_displacement_operand (operands[0], <MODE>mode)))
16603 || (TARGET_NOT_VECTORMODE
16604 && long_memory_operand (operands[0], <MODE>mode)))
16605 && peep2_regno_dead_p (0, FLAGS_REG)"
16606 [(parallel [(set (match_dup 0)
16607 (xor:SWI124 (match_dup 1) (const_int -1)))
16608 (clobber (reg:CC FLAGS_REG))])])
16610 ;; Non pairable "test imm, reg" instructions can be translated to
16611 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16612 ;; byte opcode instead of two, have a short form for byte operands),
16613 ;; so do it for other CPUs as well. Given that the value was dead,
16614 ;; this should not create any new dependencies. Pass on the sub-word
16615 ;; versions if we're concerned about partial register stalls.
16618 [(set (match_operand 0 "flags_reg_operand" "")
16619 (match_operator 1 "compare_operator"
16620 [(and:SI (match_operand:SI 2 "register_operand" "")
16621 (match_operand:SI 3 "immediate_operand" ""))
16623 "ix86_match_ccmode (insn, CCNOmode)
16624 && (true_regnum (operands[2]) != AX_REG
16625 || satisfies_constraint_K (operands[3]))
16626 && peep2_reg_dead_p (1, operands[2])"
16628 [(set (match_dup 0)
16629 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16632 (and:SI (match_dup 2) (match_dup 3)))])])
16634 ;; We don't need to handle HImode case, because it will be promoted to SImode
16635 ;; on ! TARGET_PARTIAL_REG_STALL
16638 [(set (match_operand 0 "flags_reg_operand" "")
16639 (match_operator 1 "compare_operator"
16640 [(and:QI (match_operand:QI 2 "register_operand" "")
16641 (match_operand:QI 3 "immediate_operand" ""))
16643 "! TARGET_PARTIAL_REG_STALL
16644 && ix86_match_ccmode (insn, CCNOmode)
16645 && true_regnum (operands[2]) != AX_REG
16646 && peep2_reg_dead_p (1, operands[2])"
16648 [(set (match_dup 0)
16649 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16652 (and:QI (match_dup 2) (match_dup 3)))])])
16655 [(set (match_operand 0 "flags_reg_operand" "")
16656 (match_operator 1 "compare_operator"
16659 (match_operand 2 "ext_register_operand" "")
16662 (match_operand 3 "const_int_operand" ""))
16664 "! TARGET_PARTIAL_REG_STALL
16665 && ix86_match_ccmode (insn, CCNOmode)
16666 && true_regnum (operands[2]) != AX_REG
16667 && peep2_reg_dead_p (1, operands[2])"
16668 [(parallel [(set (match_dup 0)
16677 (set (zero_extract:SI (match_dup 2)
16685 (match_dup 3)))])])
16687 ;; Don't do logical operations with memory inputs.
16689 [(match_scratch:SI 2 "r")
16690 (parallel [(set (match_operand:SI 0 "register_operand" "")
16691 (match_operator:SI 3 "arith_or_logical_operator"
16693 (match_operand:SI 1 "memory_operand" "")]))
16694 (clobber (reg:CC FLAGS_REG))])]
16695 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16696 [(set (match_dup 2) (match_dup 1))
16697 (parallel [(set (match_dup 0)
16698 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16699 (clobber (reg:CC FLAGS_REG))])])
16702 [(match_scratch:SI 2 "r")
16703 (parallel [(set (match_operand:SI 0 "register_operand" "")
16704 (match_operator:SI 3 "arith_or_logical_operator"
16705 [(match_operand:SI 1 "memory_operand" "")
16707 (clobber (reg:CC FLAGS_REG))])]
16708 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16709 [(set (match_dup 2) (match_dup 1))
16710 (parallel [(set (match_dup 0)
16711 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16712 (clobber (reg:CC FLAGS_REG))])])
16714 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16715 ;; refers to the destination of the load!
16718 [(set (match_operand:SI 0 "register_operand" "")
16719 (match_operand:SI 1 "register_operand" ""))
16720 (parallel [(set (match_dup 0)
16721 (match_operator:SI 3 "commutative_operator"
16723 (match_operand:SI 2 "memory_operand" "")]))
16724 (clobber (reg:CC FLAGS_REG))])]
16725 "REGNO (operands[0]) != REGNO (operands[1])
16726 && GENERAL_REGNO_P (REGNO (operands[0]))
16727 && GENERAL_REGNO_P (REGNO (operands[1]))"
16728 [(set (match_dup 0) (match_dup 4))
16729 (parallel [(set (match_dup 0)
16730 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16731 (clobber (reg:CC FLAGS_REG))])]
16732 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16735 [(set (match_operand 0 "register_operand" "")
16736 (match_operand 1 "register_operand" ""))
16738 (match_operator 3 "commutative_operator"
16740 (match_operand 2 "memory_operand" "")]))]
16741 "REGNO (operands[0]) != REGNO (operands[1])
16742 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16743 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16744 [(set (match_dup 0) (match_dup 2))
16746 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16748 ; Don't do logical operations with memory outputs
16750 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16751 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16752 ; the same decoder scheduling characteristics as the original.
16755 [(match_scratch:SI 2 "r")
16756 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16757 (match_operator:SI 3 "arith_or_logical_operator"
16759 (match_operand:SI 1 "nonmemory_operand" "")]))
16760 (clobber (reg:CC FLAGS_REG))])]
16761 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16762 /* Do not split stack checking probes. */
16763 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16764 [(set (match_dup 2) (match_dup 0))
16765 (parallel [(set (match_dup 2)
16766 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16767 (clobber (reg:CC FLAGS_REG))])
16768 (set (match_dup 0) (match_dup 2))])
16771 [(match_scratch:SI 2 "r")
16772 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16773 (match_operator:SI 3 "arith_or_logical_operator"
16774 [(match_operand:SI 1 "nonmemory_operand" "")
16776 (clobber (reg:CC FLAGS_REG))])]
16777 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16778 /* Do not split stack checking probes. */
16779 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16780 [(set (match_dup 2) (match_dup 0))
16781 (parallel [(set (match_dup 2)
16782 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16783 (clobber (reg:CC FLAGS_REG))])
16784 (set (match_dup 0) (match_dup 2))])
16786 ;; Attempt to always use XOR for zeroing registers.
16788 [(set (match_operand 0 "register_operand" "")
16789 (match_operand 1 "const0_operand" ""))]
16790 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16791 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16792 && GENERAL_REG_P (operands[0])
16793 && peep2_regno_dead_p (0, FLAGS_REG)"
16794 [(parallel [(set (match_dup 0) (const_int 0))
16795 (clobber (reg:CC FLAGS_REG))])]
16796 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16799 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16801 "(GET_MODE (operands[0]) == QImode
16802 || GET_MODE (operands[0]) == HImode)
16803 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16804 && peep2_regno_dead_p (0, FLAGS_REG)"
16805 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16806 (clobber (reg:CC FLAGS_REG))])])
16808 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16810 [(set (match_operand:SWI248 0 "register_operand" "")
16812 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16813 && peep2_regno_dead_p (0, FLAGS_REG)"
16814 [(parallel [(set (match_dup 0) (const_int -1))
16815 (clobber (reg:CC FLAGS_REG))])]
16817 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16818 operands[0] = gen_lowpart (SImode, operands[0]);
16821 ;; Attempt to convert simple lea to add/shift.
16822 ;; These can be created by move expanders.
16825 [(set (match_operand:SWI48 0 "register_operand" "")
16826 (plus:SWI48 (match_dup 0)
16827 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16828 "peep2_regno_dead_p (0, FLAGS_REG)"
16829 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16830 (clobber (reg:CC FLAGS_REG))])])
16833 [(set (match_operand:SI 0 "register_operand" "")
16834 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16835 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16837 && peep2_regno_dead_p (0, FLAGS_REG)
16838 && REGNO (operands[0]) == REGNO (operands[1])"
16839 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16840 (clobber (reg:CC FLAGS_REG))])]
16841 "operands[2] = gen_lowpart (SImode, operands[2]);")
16844 [(set (match_operand:SWI48 0 "register_operand" "")
16845 (mult:SWI48 (match_dup 0)
16846 (match_operand:SWI48 1 "const_int_operand" "")))]
16847 "exact_log2 (INTVAL (operands[1])) >= 0
16848 && peep2_regno_dead_p (0, FLAGS_REG)"
16849 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16850 (clobber (reg:CC FLAGS_REG))])]
16851 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16854 [(set (match_operand:SI 0 "register_operand" "")
16855 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16856 (match_operand:DI 2 "const_int_operand" "")) 0))]
16858 && exact_log2 (INTVAL (operands[2])) >= 0
16859 && REGNO (operands[0]) == REGNO (operands[1])
16860 && peep2_regno_dead_p (0, FLAGS_REG)"
16861 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16862 (clobber (reg:CC FLAGS_REG))])]
16863 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16865 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16866 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16867 ;; On many CPUs it is also faster, since special hardware to avoid esp
16868 ;; dependencies is present.
16870 ;; While some of these conversions may be done using splitters, we use
16871 ;; peepholes in order to allow combine_stack_adjustments pass to see
16872 ;; nonobfuscated RTL.
16874 ;; Convert prologue esp subtractions to push.
16875 ;; We need register to push. In order to keep verify_flow_info happy we have
16877 ;; - use scratch and clobber it in order to avoid dependencies
16878 ;; - use already live register
16879 ;; We can't use the second way right now, since there is no reliable way how to
16880 ;; verify that given register is live. First choice will also most likely in
16881 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16882 ;; call clobbered registers are dead. We may want to use base pointer as an
16883 ;; alternative when no register is available later.
16886 [(match_scratch:P 1 "r")
16887 (parallel [(set (reg:P SP_REG)
16888 (plus:P (reg:P SP_REG)
16889 (match_operand:P 0 "const_int_operand" "")))
16890 (clobber (reg:CC FLAGS_REG))
16891 (clobber (mem:BLK (scratch)))])]
16892 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16893 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16894 [(clobber (match_dup 1))
16895 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16896 (clobber (mem:BLK (scratch)))])])
16899 [(match_scratch:P 1 "r")
16900 (parallel [(set (reg:P SP_REG)
16901 (plus:P (reg:P SP_REG)
16902 (match_operand:P 0 "const_int_operand" "")))
16903 (clobber (reg:CC FLAGS_REG))
16904 (clobber (mem:BLK (scratch)))])]
16905 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16906 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16907 [(clobber (match_dup 1))
16908 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16909 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16910 (clobber (mem:BLK (scratch)))])])
16912 ;; Convert esp subtractions to push.
16914 [(match_scratch:P 1 "r")
16915 (parallel [(set (reg:P SP_REG)
16916 (plus:P (reg:P SP_REG)
16917 (match_operand:P 0 "const_int_operand" "")))
16918 (clobber (reg:CC FLAGS_REG))])]
16919 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16920 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16921 [(clobber (match_dup 1))
16922 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16925 [(match_scratch:P 1 "r")
16926 (parallel [(set (reg:P SP_REG)
16927 (plus:P (reg:P SP_REG)
16928 (match_operand:P 0 "const_int_operand" "")))
16929 (clobber (reg:CC FLAGS_REG))])]
16930 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16931 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16932 [(clobber (match_dup 1))
16933 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16934 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16936 ;; Convert epilogue deallocator to pop.
16938 [(match_scratch:P 1 "r")
16939 (parallel [(set (reg:P SP_REG)
16940 (plus:P (reg:P SP_REG)
16941 (match_operand:P 0 "const_int_operand" "")))
16942 (clobber (reg:CC FLAGS_REG))
16943 (clobber (mem:BLK (scratch)))])]
16944 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16945 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16946 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16947 (clobber (mem:BLK (scratch)))])])
16949 ;; Two pops case is tricky, since pop causes dependency
16950 ;; on destination register. We use two registers if available.
16952 [(match_scratch:P 1 "r")
16953 (match_scratch:P 2 "r")
16954 (parallel [(set (reg:P SP_REG)
16955 (plus:P (reg:P SP_REG)
16956 (match_operand:P 0 "const_int_operand" "")))
16957 (clobber (reg:CC FLAGS_REG))
16958 (clobber (mem:BLK (scratch)))])]
16959 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16960 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16961 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16962 (clobber (mem:BLK (scratch)))])
16963 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16966 [(match_scratch:P 1 "r")
16967 (parallel [(set (reg:P SP_REG)
16968 (plus:P (reg:P SP_REG)
16969 (match_operand:P 0 "const_int_operand" "")))
16970 (clobber (reg:CC FLAGS_REG))
16971 (clobber (mem:BLK (scratch)))])]
16972 "optimize_insn_for_size_p ()
16973 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16974 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16975 (clobber (mem:BLK (scratch)))])
16976 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16978 ;; Convert esp additions to pop.
16980 [(match_scratch:P 1 "r")
16981 (parallel [(set (reg:P SP_REG)
16982 (plus:P (reg:P SP_REG)
16983 (match_operand:P 0 "const_int_operand" "")))
16984 (clobber (reg:CC FLAGS_REG))])]
16985 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16986 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16988 ;; Two pops case is tricky, since pop causes dependency
16989 ;; on destination register. We use two registers if available.
16991 [(match_scratch:P 1 "r")
16992 (match_scratch:P 2 "r")
16993 (parallel [(set (reg:P SP_REG)
16994 (plus:P (reg:P SP_REG)
16995 (match_operand:P 0 "const_int_operand" "")))
16996 (clobber (reg:CC FLAGS_REG))])]
16997 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16998 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16999 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17002 [(match_scratch:P 1 "r")
17003 (parallel [(set (reg:P SP_REG)
17004 (plus:P (reg:P SP_REG)
17005 (match_operand:P 0 "const_int_operand" "")))
17006 (clobber (reg:CC FLAGS_REG))])]
17007 "optimize_insn_for_size_p ()
17008 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17009 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17010 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17012 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17013 ;; required and register dies. Similarly for 128 to -128.
17015 [(set (match_operand 0 "flags_reg_operand" "")
17016 (match_operator 1 "compare_operator"
17017 [(match_operand 2 "register_operand" "")
17018 (match_operand 3 "const_int_operand" "")]))]
17019 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17020 && incdec_operand (operands[3], GET_MODE (operands[3])))
17021 || (!TARGET_FUSE_CMP_AND_BRANCH
17022 && INTVAL (operands[3]) == 128))
17023 && ix86_match_ccmode (insn, CCGCmode)
17024 && peep2_reg_dead_p (1, operands[2])"
17025 [(parallel [(set (match_dup 0)
17026 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17027 (clobber (match_dup 2))])])
17029 ;; Convert imul by three, five and nine into lea
17032 [(set (match_operand:SWI48 0 "register_operand" "")
17033 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17034 (match_operand:SWI48 2 "const_int_operand" "")))
17035 (clobber (reg:CC FLAGS_REG))])]
17036 "INTVAL (operands[2]) == 3
17037 || INTVAL (operands[2]) == 5
17038 || INTVAL (operands[2]) == 9"
17039 [(set (match_dup 0)
17040 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17042 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17046 [(set (match_operand:SWI48 0 "register_operand" "")
17047 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17048 (match_operand:SWI48 2 "const_int_operand" "")))
17049 (clobber (reg:CC FLAGS_REG))])]
17050 "optimize_insn_for_speed_p ()
17051 && (INTVAL (operands[2]) == 3
17052 || INTVAL (operands[2]) == 5
17053 || INTVAL (operands[2]) == 9)"
17054 [(set (match_dup 0) (match_dup 1))
17056 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17058 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17060 ;; imul $32bit_imm, mem, reg is vector decoded, while
17061 ;; imul $32bit_imm, reg, reg is direct decoded.
17063 [(match_scratch:SWI48 3 "r")
17064 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17065 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17066 (match_operand:SWI48 2 "immediate_operand" "")))
17067 (clobber (reg:CC FLAGS_REG))])]
17068 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17069 && !satisfies_constraint_K (operands[2])"
17070 [(set (match_dup 3) (match_dup 1))
17071 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17072 (clobber (reg:CC FLAGS_REG))])])
17075 [(match_scratch:SI 3 "r")
17076 (parallel [(set (match_operand:DI 0 "register_operand" "")
17078 (mult:SI (match_operand:SI 1 "memory_operand" "")
17079 (match_operand:SI 2 "immediate_operand" ""))))
17080 (clobber (reg:CC FLAGS_REG))])]
17082 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17083 && !satisfies_constraint_K (operands[2])"
17084 [(set (match_dup 3) (match_dup 1))
17085 (parallel [(set (match_dup 0)
17086 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17087 (clobber (reg:CC FLAGS_REG))])])
17089 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17090 ;; Convert it into imul reg, reg
17091 ;; It would be better to force assembler to encode instruction using long
17092 ;; immediate, but there is apparently no way to do so.
17094 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17096 (match_operand:SWI248 1 "nonimmediate_operand" "")
17097 (match_operand:SWI248 2 "const_int_operand" "")))
17098 (clobber (reg:CC FLAGS_REG))])
17099 (match_scratch:SWI248 3 "r")]
17100 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17101 && satisfies_constraint_K (operands[2])"
17102 [(set (match_dup 3) (match_dup 2))
17103 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17104 (clobber (reg:CC FLAGS_REG))])]
17106 if (!rtx_equal_p (operands[0], operands[1]))
17107 emit_move_insn (operands[0], operands[1]);
17110 ;; After splitting up read-modify operations, array accesses with memory
17111 ;; operands might end up in form:
17113 ;; movl 4(%esp), %edx
17115 ;; instead of pre-splitting:
17117 ;; addl 4(%esp), %eax
17119 ;; movl 4(%esp), %edx
17120 ;; leal (%edx,%eax,4), %eax
17123 [(match_scratch:P 5 "r")
17124 (parallel [(set (match_operand 0 "register_operand" "")
17125 (ashift (match_operand 1 "register_operand" "")
17126 (match_operand 2 "const_int_operand" "")))
17127 (clobber (reg:CC FLAGS_REG))])
17128 (parallel [(set (match_operand 3 "register_operand" "")
17129 (plus (match_dup 0)
17130 (match_operand 4 "x86_64_general_operand" "")))
17131 (clobber (reg:CC FLAGS_REG))])]
17132 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17133 /* Validate MODE for lea. */
17134 && ((!TARGET_PARTIAL_REG_STALL
17135 && (GET_MODE (operands[0]) == QImode
17136 || GET_MODE (operands[0]) == HImode))
17137 || GET_MODE (operands[0]) == SImode
17138 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17139 && (rtx_equal_p (operands[0], operands[3])
17140 || peep2_reg_dead_p (2, operands[0]))
17141 /* We reorder load and the shift. */
17142 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17143 [(set (match_dup 5) (match_dup 4))
17144 (set (match_dup 0) (match_dup 1))]
17146 enum machine_mode op1mode = GET_MODE (operands[1]);
17147 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17148 int scale = 1 << INTVAL (operands[2]);
17149 rtx index = gen_lowpart (Pmode, operands[1]);
17150 rtx base = gen_lowpart (Pmode, operands[5]);
17151 rtx dest = gen_lowpart (mode, operands[3]);
17153 operands[1] = gen_rtx_PLUS (Pmode, base,
17154 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17155 operands[5] = base;
17157 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17158 if (op1mode != Pmode)
17159 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17160 operands[0] = dest;
17163 ;; Call-value patterns last so that the wildcard operand does not
17164 ;; disrupt insn-recog's switch tables.
17166 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17168 [(set (match_operand 0 "" "")
17169 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17170 (match_operand:SI 2 "" "")))
17171 (set (reg:SI SP_REG)
17172 (plus:SI (reg:SI SP_REG)
17173 (match_operand:SI 3 "immediate_operand" "")))])
17174 (unspec [(match_operand 4 "const_int_operand" "")]
17175 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17176 "TARGET_VZEROUPPER && !TARGET_64BIT"
17178 "&& reload_completed"
17180 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17181 [(set_attr "type" "callv")])
17183 (define_insn "*call_value_pop_0"
17184 [(set (match_operand 0 "" "")
17185 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17186 (match_operand:SI 2 "" "")))
17187 (set (reg:SI SP_REG)
17188 (plus:SI (reg:SI SP_REG)
17189 (match_operand:SI 3 "immediate_operand" "")))]
17191 { return ix86_output_call_insn (insn, operands[1], 1); }
17192 [(set_attr "type" "callv")])
17194 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17196 [(set (match_operand 0 "" "")
17197 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17198 (match_operand:SI 2 "" "")))
17199 (set (reg:SI SP_REG)
17200 (plus:SI (reg:SI SP_REG)
17201 (match_operand:SI 3 "immediate_operand" "i")))])
17202 (unspec [(match_operand 4 "const_int_operand" "")]
17203 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17204 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17206 "&& reload_completed"
17208 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17209 [(set_attr "type" "callv")])
17211 (define_insn "*call_value_pop_1"
17212 [(set (match_operand 0 "" "")
17213 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17214 (match_operand:SI 2 "" "")))
17215 (set (reg:SI SP_REG)
17216 (plus:SI (reg:SI SP_REG)
17217 (match_operand:SI 3 "immediate_operand" "i")))]
17218 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17219 { return ix86_output_call_insn (insn, operands[1], 1); }
17220 [(set_attr "type" "callv")])
17222 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17224 [(set (match_operand 0 "" "")
17225 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17226 (match_operand:SI 2 "" "")))
17227 (set (reg:SI SP_REG)
17228 (plus:SI (reg:SI SP_REG)
17229 (match_operand:SI 3 "immediate_operand" "i,i")))])
17230 (unspec [(match_operand 4 "const_int_operand" "")]
17231 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17232 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17234 "&& reload_completed"
17236 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17237 [(set_attr "type" "callv")])
17239 (define_insn "*sibcall_value_pop_1"
17240 [(set (match_operand 0 "" "")
17241 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17242 (match_operand:SI 2 "" "")))
17243 (set (reg:SI SP_REG)
17244 (plus:SI (reg:SI SP_REG)
17245 (match_operand:SI 3 "immediate_operand" "i,i")))]
17246 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17247 { return ix86_output_call_insn (insn, operands[1], 1); }
17248 [(set_attr "type" "callv")])
17250 (define_insn_and_split "*call_value_0_vzeroupper"
17251 [(set (match_operand 0 "" "")
17252 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17253 (match_operand:SI 2 "" "")))
17254 (unspec [(match_operand 3 "const_int_operand" "")]
17255 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17256 "TARGET_VZEROUPPER && !TARGET_64BIT"
17258 "&& reload_completed"
17260 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17261 [(set_attr "type" "callv")])
17263 (define_insn "*call_value_0"
17264 [(set (match_operand 0 "" "")
17265 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17266 (match_operand:SI 2 "" "")))]
17268 { return ix86_output_call_insn (insn, operands[1], 1); }
17269 [(set_attr "type" "callv")])
17271 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17272 [(set (match_operand 0 "" "")
17273 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17274 (match_operand:DI 2 "const_int_operand" "")))
17275 (unspec [(match_operand 3 "const_int_operand" "")]
17276 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17277 "TARGET_VZEROUPPER && TARGET_64BIT"
17279 "&& reload_completed"
17281 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17282 [(set_attr "type" "callv")])
17284 (define_insn "*call_value_0_rex64"
17285 [(set (match_operand 0 "" "")
17286 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17287 (match_operand:DI 2 "const_int_operand" "")))]
17289 { return ix86_output_call_insn (insn, operands[1], 1); }
17290 [(set_attr "type" "callv")])
17292 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17294 [(set (match_operand 0 "" "")
17295 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17296 (match_operand:DI 2 "const_int_operand" "")))
17297 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17298 (clobber (reg:TI XMM6_REG))
17299 (clobber (reg:TI XMM7_REG))
17300 (clobber (reg:TI XMM8_REG))
17301 (clobber (reg:TI XMM9_REG))
17302 (clobber (reg:TI XMM10_REG))
17303 (clobber (reg:TI XMM11_REG))
17304 (clobber (reg:TI XMM12_REG))
17305 (clobber (reg:TI XMM13_REG))
17306 (clobber (reg:TI XMM14_REG))
17307 (clobber (reg:TI XMM15_REG))
17308 (clobber (reg:DI SI_REG))
17309 (clobber (reg:DI DI_REG))])
17310 (unspec [(match_operand 3 "const_int_operand" "")]
17311 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17312 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17314 "&& reload_completed"
17316 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17317 [(set_attr "type" "callv")])
17319 (define_insn "*call_value_0_rex64_ms_sysv"
17320 [(set (match_operand 0 "" "")
17321 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17322 (match_operand:DI 2 "const_int_operand" "")))
17323 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17324 (clobber (reg:TI XMM6_REG))
17325 (clobber (reg:TI XMM7_REG))
17326 (clobber (reg:TI XMM8_REG))
17327 (clobber (reg:TI XMM9_REG))
17328 (clobber (reg:TI XMM10_REG))
17329 (clobber (reg:TI XMM11_REG))
17330 (clobber (reg:TI XMM12_REG))
17331 (clobber (reg:TI XMM13_REG))
17332 (clobber (reg:TI XMM14_REG))
17333 (clobber (reg:TI XMM15_REG))
17334 (clobber (reg:DI SI_REG))
17335 (clobber (reg:DI DI_REG))]
17336 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17337 { return ix86_output_call_insn (insn, operands[1], 1); }
17338 [(set_attr "type" "callv")])
17340 (define_insn_and_split "*call_value_1_vzeroupper"
17341 [(set (match_operand 0 "" "")
17342 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17343 (match_operand:SI 2 "" "")))
17344 (unspec [(match_operand 3 "const_int_operand" "")]
17345 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17346 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17348 "&& reload_completed"
17350 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17351 [(set_attr "type" "callv")])
17353 (define_insn "*call_value_1"
17354 [(set (match_operand 0 "" "")
17355 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17356 (match_operand:SI 2 "" "")))]
17357 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17358 { return ix86_output_call_insn (insn, operands[1], 1); }
17359 [(set_attr "type" "callv")])
17361 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17362 [(set (match_operand 0 "" "")
17363 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17364 (match_operand:SI 2 "" "")))
17365 (unspec [(match_operand 3 "const_int_operand" "")]
17366 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17367 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17369 "&& reload_completed"
17371 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17372 [(set_attr "type" "callv")])
17374 (define_insn "*sibcall_value_1"
17375 [(set (match_operand 0 "" "")
17376 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17377 (match_operand:SI 2 "" "")))]
17378 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17379 { return ix86_output_call_insn (insn, operands[1], 1); }
17380 [(set_attr "type" "callv")])
17382 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17383 [(set (match_operand 0 "" "")
17384 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17385 (match_operand:DI 2 "" "")))
17386 (unspec [(match_operand 3 "const_int_operand" "")]
17387 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17388 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17389 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17391 "&& reload_completed"
17393 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17394 [(set_attr "type" "callv")])
17396 (define_insn "*call_value_1_rex64"
17397 [(set (match_operand 0 "" "")
17398 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17399 (match_operand:DI 2 "" "")))]
17400 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17401 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17402 { return ix86_output_call_insn (insn, operands[1], 1); }
17403 [(set_attr "type" "callv")])
17405 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17407 [(set (match_operand 0 "" "")
17408 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17409 (match_operand:DI 2 "" "")))
17410 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17411 (clobber (reg:TI XMM6_REG))
17412 (clobber (reg:TI XMM7_REG))
17413 (clobber (reg:TI XMM8_REG))
17414 (clobber (reg:TI XMM9_REG))
17415 (clobber (reg:TI XMM10_REG))
17416 (clobber (reg:TI XMM11_REG))
17417 (clobber (reg:TI XMM12_REG))
17418 (clobber (reg:TI XMM13_REG))
17419 (clobber (reg:TI XMM14_REG))
17420 (clobber (reg:TI XMM15_REG))
17421 (clobber (reg:DI SI_REG))
17422 (clobber (reg:DI DI_REG))])
17423 (unspec [(match_operand 3 "const_int_operand" "")]
17424 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17425 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17427 "&& reload_completed"
17429 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17430 [(set_attr "type" "callv")])
17432 (define_insn "*call_value_1_rex64_ms_sysv"
17433 [(set (match_operand 0 "" "")
17434 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17435 (match_operand:DI 2 "" "")))
17436 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17437 (clobber (reg:TI XMM6_REG))
17438 (clobber (reg:TI XMM7_REG))
17439 (clobber (reg:TI XMM8_REG))
17440 (clobber (reg:TI XMM9_REG))
17441 (clobber (reg:TI XMM10_REG))
17442 (clobber (reg:TI XMM11_REG))
17443 (clobber (reg:TI XMM12_REG))
17444 (clobber (reg:TI XMM13_REG))
17445 (clobber (reg:TI XMM14_REG))
17446 (clobber (reg:TI XMM15_REG))
17447 (clobber (reg:DI SI_REG))
17448 (clobber (reg:DI DI_REG))]
17449 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17450 { return ix86_output_call_insn (insn, operands[1], 1); }
17451 [(set_attr "type" "callv")])
17453 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17454 [(set (match_operand 0 "" "")
17455 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17456 (match_operand:DI 2 "" "")))
17457 (unspec [(match_operand 3 "const_int_operand" "")]
17458 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17459 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17461 "&& reload_completed"
17463 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17464 [(set_attr "type" "callv")])
17466 (define_insn "*call_value_1_rex64_large"
17467 [(set (match_operand 0 "" "")
17468 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17469 (match_operand:DI 2 "" "")))]
17470 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17471 { return ix86_output_call_insn (insn, operands[1], 1); }
17472 [(set_attr "type" "callv")])
17474 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17475 [(set (match_operand 0 "" "")
17476 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17477 (match_operand:DI 2 "" "")))
17478 (unspec [(match_operand 3 "const_int_operand" "")]
17479 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17480 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17482 "&& reload_completed"
17484 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17485 [(set_attr "type" "callv")])
17487 (define_insn "*sibcall_value_1_rex64"
17488 [(set (match_operand 0 "" "")
17489 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17490 (match_operand:DI 2 "" "")))]
17491 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17492 { return ix86_output_call_insn (insn, operands[1], 1); }
17493 [(set_attr "type" "callv")])
17495 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17496 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17497 ;; caught for use by garbage collectors and the like. Using an insn that
17498 ;; maps to SIGILL makes it more likely the program will rightfully die.
17499 ;; Keeping with tradition, "6" is in honor of #UD.
17500 (define_insn "trap"
17501 [(trap_if (const_int 1) (const_int 6))]
17503 { return ASM_SHORT "0x0b0f"; }
17504 [(set_attr "length" "2")])
17506 (define_expand "prefetch"
17507 [(prefetch (match_operand 0 "address_operand" "")
17508 (match_operand:SI 1 "const_int_operand" "")
17509 (match_operand:SI 2 "const_int_operand" ""))]
17510 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17512 int rw = INTVAL (operands[1]);
17513 int locality = INTVAL (operands[2]);
17515 gcc_assert (rw == 0 || rw == 1);
17516 gcc_assert (locality >= 0 && locality <= 3);
17517 gcc_assert (GET_MODE (operands[0]) == Pmode
17518 || GET_MODE (operands[0]) == VOIDmode);
17520 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17521 supported by SSE counterpart or the SSE prefetch is not available
17522 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17524 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17525 operands[2] = GEN_INT (3);
17527 operands[1] = const0_rtx;
17530 (define_insn "*prefetch_sse_<mode>"
17531 [(prefetch (match_operand:P 0 "address_operand" "p")
17533 (match_operand:SI 1 "const_int_operand" ""))]
17534 "TARGET_PREFETCH_SSE"
17536 static const char * const patterns[4] = {
17537 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17540 int locality = INTVAL (operands[1]);
17541 gcc_assert (locality >= 0 && locality <= 3);
17543 return patterns[locality];
17545 [(set_attr "type" "sse")
17546 (set_attr "atom_sse_attr" "prefetch")
17547 (set (attr "length_address")
17548 (symbol_ref "memory_address_length (operands[0])"))
17549 (set_attr "memory" "none")])
17551 (define_insn "*prefetch_3dnow_<mode>"
17552 [(prefetch (match_operand:P 0 "address_operand" "p")
17553 (match_operand:SI 1 "const_int_operand" "n")
17557 if (INTVAL (operands[1]) == 0)
17558 return "prefetch\t%a0";
17560 return "prefetchw\t%a0";
17562 [(set_attr "type" "mmx")
17563 (set (attr "length_address")
17564 (symbol_ref "memory_address_length (operands[0])"))
17565 (set_attr "memory" "none")])
17567 (define_expand "stack_protect_set"
17568 [(match_operand 0 "memory_operand" "")
17569 (match_operand 1 "memory_operand" "")]
17572 rtx (*insn)(rtx, rtx);
17574 #ifdef TARGET_THREAD_SSP_OFFSET
17575 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17576 insn = (TARGET_64BIT
17577 ? gen_stack_tls_protect_set_di
17578 : gen_stack_tls_protect_set_si);
17580 insn = (TARGET_64BIT
17581 ? gen_stack_protect_set_di
17582 : gen_stack_protect_set_si);
17585 emit_insn (insn (operands[0], operands[1]));
17589 (define_insn "stack_protect_set_<mode>"
17590 [(set (match_operand:P 0 "memory_operand" "=m")
17591 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17592 (set (match_scratch:P 2 "=&r") (const_int 0))
17593 (clobber (reg:CC FLAGS_REG))]
17595 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17596 [(set_attr "type" "multi")])
17598 (define_insn "stack_tls_protect_set_<mode>"
17599 [(set (match_operand:P 0 "memory_operand" "=m")
17600 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17601 UNSPEC_SP_TLS_SET))
17602 (set (match_scratch:P 2 "=&r") (const_int 0))
17603 (clobber (reg:CC FLAGS_REG))]
17605 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17606 [(set_attr "type" "multi")])
17608 (define_expand "stack_protect_test"
17609 [(match_operand 0 "memory_operand" "")
17610 (match_operand 1 "memory_operand" "")
17611 (match_operand 2 "" "")]
17614 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17616 rtx (*insn)(rtx, rtx, rtx);
17618 #ifdef TARGET_THREAD_SSP_OFFSET
17619 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17620 insn = (TARGET_64BIT
17621 ? gen_stack_tls_protect_test_di
17622 : gen_stack_tls_protect_test_si);
17624 insn = (TARGET_64BIT
17625 ? gen_stack_protect_test_di
17626 : gen_stack_protect_test_si);
17629 emit_insn (insn (flags, operands[0], operands[1]));
17631 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17632 flags, const0_rtx, operands[2]));
17636 (define_insn "stack_protect_test_<mode>"
17637 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17638 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17639 (match_operand:P 2 "memory_operand" "m")]
17641 (clobber (match_scratch:P 3 "=&r"))]
17643 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17644 [(set_attr "type" "multi")])
17646 (define_insn "stack_tls_protect_test_<mode>"
17647 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17648 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17649 (match_operand:P 2 "const_int_operand" "i")]
17650 UNSPEC_SP_TLS_TEST))
17651 (clobber (match_scratch:P 3 "=r"))]
17653 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17654 [(set_attr "type" "multi")])
17656 (define_insn "sse4_2_crc32<mode>"
17657 [(set (match_operand:SI 0 "register_operand" "=r")
17659 [(match_operand:SI 1 "register_operand" "0")
17660 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17662 "TARGET_SSE4_2 || TARGET_CRC32"
17663 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17664 [(set_attr "type" "sselog1")
17665 (set_attr "prefix_rep" "1")
17666 (set_attr "prefix_extra" "1")
17667 (set (attr "prefix_data16")
17668 (if_then_else (match_operand:HI 2 "" "")
17670 (const_string "*")))
17671 (set (attr "prefix_rex")
17672 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17674 (const_string "*")))
17675 (set_attr "mode" "SI")])
17677 (define_insn "sse4_2_crc32di"
17678 [(set (match_operand:DI 0 "register_operand" "=r")
17680 [(match_operand:DI 1 "register_operand" "0")
17681 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17683 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17684 "crc32{q}\t{%2, %0|%0, %2}"
17685 [(set_attr "type" "sselog1")
17686 (set_attr "prefix_rep" "1")
17687 (set_attr "prefix_extra" "1")
17688 (set_attr "mode" "DI")])
17690 (define_expand "rdpmc"
17691 [(match_operand:DI 0 "register_operand" "")
17692 (match_operand:SI 1 "register_operand" "")]
17695 rtx reg = gen_reg_rtx (DImode);
17698 /* Force operand 1 into ECX. */
17699 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17700 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17701 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17706 rtvec vec = rtvec_alloc (2);
17707 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17708 rtx upper = gen_reg_rtx (DImode);
17709 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17710 gen_rtvec (1, const0_rtx),
17712 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17713 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17715 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17716 NULL, 1, OPTAB_DIRECT);
17717 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17721 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17722 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17726 (define_insn "*rdpmc"
17727 [(set (match_operand:DI 0 "register_operand" "=A")
17728 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17732 [(set_attr "type" "other")
17733 (set_attr "length" "2")])
17735 (define_insn "*rdpmc_rex64"
17736 [(set (match_operand:DI 0 "register_operand" "=a")
17737 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17739 (set (match_operand:DI 1 "register_operand" "=d")
17740 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17743 [(set_attr "type" "other")
17744 (set_attr "length" "2")])
17746 (define_expand "rdtsc"
17747 [(set (match_operand:DI 0 "register_operand" "")
17748 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17753 rtvec vec = rtvec_alloc (2);
17754 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17755 rtx upper = gen_reg_rtx (DImode);
17756 rtx lower = gen_reg_rtx (DImode);
17757 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17758 gen_rtvec (1, const0_rtx),
17760 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17761 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17763 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17764 NULL, 1, OPTAB_DIRECT);
17765 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17767 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17772 (define_insn "*rdtsc"
17773 [(set (match_operand:DI 0 "register_operand" "=A")
17774 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17777 [(set_attr "type" "other")
17778 (set_attr "length" "2")])
17780 (define_insn "*rdtsc_rex64"
17781 [(set (match_operand:DI 0 "register_operand" "=a")
17782 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17783 (set (match_operand:DI 1 "register_operand" "=d")
17784 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17787 [(set_attr "type" "other")
17788 (set_attr "length" "2")])
17790 (define_expand "rdtscp"
17791 [(match_operand:DI 0 "register_operand" "")
17792 (match_operand:SI 1 "memory_operand" "")]
17795 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17796 gen_rtvec (1, const0_rtx),
17798 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17799 gen_rtvec (1, const0_rtx),
17801 rtx reg = gen_reg_rtx (DImode);
17802 rtx tmp = gen_reg_rtx (SImode);
17806 rtvec vec = rtvec_alloc (3);
17807 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17808 rtx upper = gen_reg_rtx (DImode);
17809 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17810 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17811 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17813 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17814 NULL, 1, OPTAB_DIRECT);
17815 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17820 rtvec vec = rtvec_alloc (2);
17821 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17822 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17823 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17826 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17827 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17831 (define_insn "*rdtscp"
17832 [(set (match_operand:DI 0 "register_operand" "=A")
17833 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17834 (set (match_operand:SI 1 "register_operand" "=c")
17835 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17838 [(set_attr "type" "other")
17839 (set_attr "length" "3")])
17841 (define_insn "*rdtscp_rex64"
17842 [(set (match_operand:DI 0 "register_operand" "=a")
17843 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17844 (set (match_operand:DI 1 "register_operand" "=d")
17845 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17846 (set (match_operand:SI 2 "register_operand" "=c")
17847 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17850 [(set_attr "type" "other")
17851 (set_attr "length" "3")])
17853 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17855 ;; LWP instructions
17857 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17859 (define_expand "lwp_llwpcb"
17860 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17861 UNSPECV_LLWP_INTRINSIC)]
17864 (define_insn "*lwp_llwpcb<mode>1"
17865 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17866 UNSPECV_LLWP_INTRINSIC)]
17869 [(set_attr "type" "lwp")
17870 (set_attr "mode" "<MODE>")
17871 (set_attr "length" "5")])
17873 (define_expand "lwp_slwpcb"
17874 [(set (match_operand 0 "register_operand" "=r")
17875 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17880 insn = (TARGET_64BIT
17882 : gen_lwp_slwpcbsi);
17884 emit_insn (insn (operands[0]));
17888 (define_insn "lwp_slwpcb<mode>"
17889 [(set (match_operand:P 0 "register_operand" "=r")
17890 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17893 [(set_attr "type" "lwp")
17894 (set_attr "mode" "<MODE>")
17895 (set_attr "length" "5")])
17897 (define_expand "lwp_lwpval<mode>3"
17898 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17899 (match_operand:SI 2 "nonimmediate_operand" "rm")
17900 (match_operand:SI 3 "const_int_operand" "i")]
17901 UNSPECV_LWPVAL_INTRINSIC)]
17903 "/* Avoid unused variable warning. */
17906 (define_insn "*lwp_lwpval<mode>3_1"
17907 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17908 (match_operand:SI 1 "nonimmediate_operand" "rm")
17909 (match_operand:SI 2 "const_int_operand" "i")]
17910 UNSPECV_LWPVAL_INTRINSIC)]
17912 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17913 [(set_attr "type" "lwp")
17914 (set_attr "mode" "<MODE>")
17915 (set (attr "length")
17916 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17918 (define_expand "lwp_lwpins<mode>3"
17919 [(set (reg:CCC FLAGS_REG)
17920 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17921 (match_operand:SI 2 "nonimmediate_operand" "rm")
17922 (match_operand:SI 3 "const_int_operand" "i")]
17923 UNSPECV_LWPINS_INTRINSIC))
17924 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17925 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17928 (define_insn "*lwp_lwpins<mode>3_1"
17929 [(set (reg:CCC FLAGS_REG)
17930 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17931 (match_operand:SI 1 "nonimmediate_operand" "rm")
17932 (match_operand:SI 2 "const_int_operand" "i")]
17933 UNSPECV_LWPINS_INTRINSIC))]
17935 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17936 [(set_attr "type" "lwp")
17937 (set_attr "mode" "<MODE>")
17938 (set (attr "length")
17939 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17941 (define_insn "rdfsbase<mode>"
17942 [(set (match_operand:SWI48 0 "register_operand" "=r")
17943 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17944 "TARGET_64BIT && TARGET_FSGSBASE"
17946 [(set_attr "type" "other")
17947 (set_attr "prefix_extra" "2")])
17949 (define_insn "rdgsbase<mode>"
17950 [(set (match_operand:SWI48 0 "register_operand" "=r")
17951 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17952 "TARGET_64BIT && TARGET_FSGSBASE"
17954 [(set_attr "type" "other")
17955 (set_attr "prefix_extra" "2")])
17957 (define_insn "wrfsbase<mode>"
17958 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17960 "TARGET_64BIT && TARGET_FSGSBASE"
17962 [(set_attr "type" "other")
17963 (set_attr "prefix_extra" "2")])
17965 (define_insn "wrgsbase<mode>"
17966 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17968 "TARGET_64BIT && TARGET_FSGSBASE"
17970 [(set_attr "type" "other")
17971 (set_attr "prefix_extra" "2")])
17973 (define_insn "rdrand<mode>_1"
17974 [(set (match_operand:SWI248 0 "register_operand" "=r")
17975 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17976 (set (reg:CCC FLAGS_REG)
17977 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17980 [(set_attr "type" "other")
17981 (set_attr "prefix_extra" "1")])
17985 (include "sync.md")