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
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
97 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_CALL_NEEDS_VZEROUPPER
111 ;; For SSE/MMX support:
129 UNSPEC_MS_TO_SYSV_CALL
131 ;; Generic math support
133 UNSPEC_IEEE_MIN ; not commutative
134 UNSPEC_IEEE_MAX ; not commutative
136 ;; x87 Floating point
152 UNSPEC_FRNDINT_MASK_PM
156 ;; x87 Double output FP
188 ;; For SSE4.1 support
198 ;; For SSE4.2 support
205 UNSPEC_XOP_UNSIGNED_CMP
216 UNSPEC_AESKEYGENASSIST
218 ;; For PCLMUL support
234 (define_c_enum "unspecv" [
237 UNSPECV_PROBE_STACK_RANGE
257 UNSPECV_LLWP_INTRINSIC
258 UNSPECV_SLWP_INTRINSIC
259 UNSPECV_LWPVAL_INTRINSIC
260 UNSPECV_LWPINS_INTRINSIC
266 UNSPECV_SPLIT_STACK_RETURN
269 ;; Constants to represent pcomtrue/pcomfalse variants
279 ;; Constants used in the XOP pperm instruction
281 [(PPERM_SRC 0x00) /* copy source */
282 (PPERM_INVERT 0x20) /* invert source */
283 (PPERM_REVERSE 0x40) /* bit reverse source */
284 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
285 (PPERM_ZERO 0x80) /* all 0's */
286 (PPERM_ONES 0xa0) /* all 1's */
287 (PPERM_SIGN 0xc0) /* propagate sign bit */
288 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
289 (PPERM_SRC1 0x00) /* use first source byte */
290 (PPERM_SRC2 0x10) /* use second source byte */
293 ;; Registers by name.
346 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
349 ;; In C guard expressions, put expressions which may be compile-time
350 ;; constants first. This allows for better optimization. For
351 ;; example, write "TARGET_64BIT && reload_completed", not
352 ;; "reload_completed && TARGET_64BIT".
356 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
357 generic64,amdfam10,bdver1"
358 (const (symbol_ref "ix86_schedule")))
360 ;; A basic instruction type. Refinements due to arguments to be
361 ;; provided in other attributes.
364 alu,alu1,negnot,imov,imovx,lea,
365 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
366 icmp,test,ibr,setcc,icmov,
367 push,pop,call,callv,leave,
369 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
370 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
371 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
372 ssemuladd,sse4arg,lwp,
373 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
374 (const_string "other"))
376 ;; Main data type used by the insn
378 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
379 (const_string "unknown"))
381 ;; The CPU unit operations uses.
382 (define_attr "unit" "integer,i387,sse,mmx,unknown"
383 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
384 (const_string "i387")
385 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
387 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
389 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
391 (eq_attr "type" "other")
392 (const_string "unknown")]
393 (const_string "integer")))
395 ;; The (bounding maximum) length of an instruction immediate.
396 (define_attr "length_immediate" ""
397 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
400 (eq_attr "unit" "i387,sse,mmx")
402 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
404 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
405 (eq_attr "type" "imov,test")
406 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
407 (eq_attr "type" "call")
408 (if_then_else (match_operand 0 "constant_call_address_operand" "")
411 (eq_attr "type" "callv")
412 (if_then_else (match_operand 1 "constant_call_address_operand" "")
415 ;; We don't know the size before shorten_branches. Expect
416 ;; the instruction to fit for better scheduling.
417 (eq_attr "type" "ibr")
420 (symbol_ref "/* Update immediate_length and other attributes! */
421 gcc_unreachable (),1")))
423 ;; The (bounding maximum) length of an instruction address.
424 (define_attr "length_address" ""
425 (cond [(eq_attr "type" "str,other,multi,fxch")
427 (and (eq_attr "type" "call")
428 (match_operand 0 "constant_call_address_operand" ""))
430 (and (eq_attr "type" "callv")
431 (match_operand 1 "constant_call_address_operand" ""))
434 (symbol_ref "ix86_attr_length_address_default (insn)")))
436 ;; Set when length prefix is used.
437 (define_attr "prefix_data16" ""
438 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
440 (eq_attr "mode" "HI")
442 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
447 ;; Set when string REP prefix is used.
448 (define_attr "prefix_rep" ""
449 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
451 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
456 ;; Set when 0f opcode prefix is used.
457 (define_attr "prefix_0f" ""
459 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
460 (eq_attr "unit" "sse,mmx"))
464 ;; Set when REX opcode prefix is used.
465 (define_attr "prefix_rex" ""
466 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
468 (and (eq_attr "mode" "DI")
469 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
470 (eq_attr "unit" "!mmx")))
472 (and (eq_attr "mode" "QI")
473 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
476 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
479 (and (eq_attr "type" "imovx")
480 (match_operand:QI 1 "ext_QIreg_operand" ""))
485 ;; There are also additional prefixes in 3DNOW, SSSE3.
486 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
487 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
488 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
489 (define_attr "prefix_extra" ""
490 (cond [(eq_attr "type" "ssemuladd,sse4arg")
492 (eq_attr "type" "sseiadd1,ssecvt1")
497 ;; Prefix used: original, VEX or maybe VEX.
498 (define_attr "prefix" "orig,vex,maybe_vex"
499 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
501 (const_string "orig")))
503 ;; VEX W bit is used.
504 (define_attr "prefix_vex_w" "" (const_int 0))
506 ;; The length of VEX prefix
507 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
508 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
509 ;; still prefix_0f 1, with prefix_extra 1.
510 (define_attr "length_vex" ""
511 (if_then_else (and (eq_attr "prefix_0f" "1")
512 (eq_attr "prefix_extra" "0"))
513 (if_then_else (eq_attr "prefix_vex_w" "1")
514 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
515 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
516 (if_then_else (eq_attr "prefix_vex_w" "1")
517 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
518 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
520 ;; Set when modrm byte is used.
521 (define_attr "modrm" ""
522 (cond [(eq_attr "type" "str,leave")
524 (eq_attr "unit" "i387")
526 (and (eq_attr "type" "incdec")
527 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
528 (ior (match_operand:SI 1 "register_operand" "")
529 (match_operand:HI 1 "register_operand" ""))))
531 (and (eq_attr "type" "push")
532 (not (match_operand 1 "memory_operand" "")))
534 (and (eq_attr "type" "pop")
535 (not (match_operand 0 "memory_operand" "")))
537 (and (eq_attr "type" "imov")
538 (and (not (eq_attr "mode" "DI"))
539 (ior (and (match_operand 0 "register_operand" "")
540 (match_operand 1 "immediate_operand" ""))
541 (ior (and (match_operand 0 "ax_reg_operand" "")
542 (match_operand 1 "memory_displacement_only_operand" ""))
543 (and (match_operand 0 "memory_displacement_only_operand" "")
544 (match_operand 1 "ax_reg_operand" ""))))))
546 (and (eq_attr "type" "call")
547 (match_operand 0 "constant_call_address_operand" ""))
549 (and (eq_attr "type" "callv")
550 (match_operand 1 "constant_call_address_operand" ""))
552 (and (eq_attr "type" "alu,alu1,icmp,test")
553 (match_operand 0 "ax_reg_operand" ""))
554 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
558 ;; The (bounding maximum) length of an instruction in bytes.
559 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
560 ;; Later we may want to split them and compute proper length as for
562 (define_attr "length" ""
563 (cond [(eq_attr "type" "other,multi,fistp,frndint")
565 (eq_attr "type" "fcmp")
567 (eq_attr "unit" "i387")
569 (plus (attr "prefix_data16")
570 (attr "length_address")))
571 (ior (eq_attr "prefix" "vex")
572 (and (eq_attr "prefix" "maybe_vex")
573 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
574 (plus (attr "length_vex")
575 (plus (attr "length_immediate")
577 (attr "length_address"))))]
578 (plus (plus (attr "modrm")
579 (plus (attr "prefix_0f")
580 (plus (attr "prefix_rex")
581 (plus (attr "prefix_extra")
583 (plus (attr "prefix_rep")
584 (plus (attr "prefix_data16")
585 (plus (attr "length_immediate")
586 (attr "length_address")))))))
588 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
589 ;; `store' if there is a simple memory reference therein, or `unknown'
590 ;; if the instruction is complex.
592 (define_attr "memory" "none,load,store,both,unknown"
593 (cond [(eq_attr "type" "other,multi,str,lwp")
594 (const_string "unknown")
595 (eq_attr "type" "lea,fcmov,fpspc")
596 (const_string "none")
597 (eq_attr "type" "fistp,leave")
598 (const_string "both")
599 (eq_attr "type" "frndint")
600 (const_string "load")
601 (eq_attr "type" "push")
602 (if_then_else (match_operand 1 "memory_operand" "")
603 (const_string "both")
604 (const_string "store"))
605 (eq_attr "type" "pop")
606 (if_then_else (match_operand 0 "memory_operand" "")
607 (const_string "both")
608 (const_string "load"))
609 (eq_attr "type" "setcc")
610 (if_then_else (match_operand 0 "memory_operand" "")
611 (const_string "store")
612 (const_string "none"))
613 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
614 (if_then_else (ior (match_operand 0 "memory_operand" "")
615 (match_operand 1 "memory_operand" ""))
616 (const_string "load")
617 (const_string "none"))
618 (eq_attr "type" "ibr")
619 (if_then_else (match_operand 0 "memory_operand" "")
620 (const_string "load")
621 (const_string "none"))
622 (eq_attr "type" "call")
623 (if_then_else (match_operand 0 "constant_call_address_operand" "")
624 (const_string "none")
625 (const_string "load"))
626 (eq_attr "type" "callv")
627 (if_then_else (match_operand 1 "constant_call_address_operand" "")
628 (const_string "none")
629 (const_string "load"))
630 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
631 (match_operand 1 "memory_operand" ""))
632 (const_string "both")
633 (and (match_operand 0 "memory_operand" "")
634 (match_operand 1 "memory_operand" ""))
635 (const_string "both")
636 (match_operand 0 "memory_operand" "")
637 (const_string "store")
638 (match_operand 1 "memory_operand" "")
639 (const_string "load")
641 "!alu1,negnot,ishift1,
642 imov,imovx,icmp,test,bitmanip,
644 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
645 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
646 (match_operand 2 "memory_operand" ""))
647 (const_string "load")
648 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
649 (match_operand 3 "memory_operand" ""))
650 (const_string "load")
652 (const_string "none")))
654 ;; Indicates if an instruction has both an immediate and a displacement.
656 (define_attr "imm_disp" "false,true,unknown"
657 (cond [(eq_attr "type" "other,multi")
658 (const_string "unknown")
659 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
660 (and (match_operand 0 "memory_displacement_operand" "")
661 (match_operand 1 "immediate_operand" "")))
662 (const_string "true")
663 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
664 (and (match_operand 0 "memory_displacement_operand" "")
665 (match_operand 2 "immediate_operand" "")))
666 (const_string "true")
668 (const_string "false")))
670 ;; Indicates if an FP operation has an integer source.
672 (define_attr "fp_int_src" "false,true"
673 (const_string "false"))
675 ;; Defines rounding mode of an FP operation.
677 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
678 (const_string "any"))
680 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
681 (define_attr "use_carry" "0,1" (const_string "0"))
683 ;; Define attribute to indicate unaligned ssemov insns
684 (define_attr "movu" "0,1" (const_string "0"))
686 ;; Describe a user's asm statement.
687 (define_asm_attributes
688 [(set_attr "length" "128")
689 (set_attr "type" "multi")])
691 (define_code_iterator plusminus [plus minus])
693 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
695 ;; Base name for define_insn
696 (define_code_attr plusminus_insn
697 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
698 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
700 ;; Base name for insn mnemonic.
701 (define_code_attr plusminus_mnemonic
702 [(plus "add") (ss_plus "adds") (us_plus "addus")
703 (minus "sub") (ss_minus "subs") (us_minus "subus")])
704 (define_code_attr plusminus_carry_mnemonic
705 [(plus "adc") (minus "sbb")])
707 ;; Mark commutative operators as such in constraints.
708 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
709 (minus "") (ss_minus "") (us_minus "")])
711 ;; Mapping of signed max and min
712 (define_code_iterator smaxmin [smax smin])
714 ;; Mapping of unsigned max and min
715 (define_code_iterator umaxmin [umax umin])
717 ;; Base name for integer and FP insn mnemonic
718 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
719 (umax "maxu") (umin "minu")])
720 (define_code_attr maxmin_float [(smax "max") (smin "min")])
722 ;; Mapping of logic operators
723 (define_code_iterator any_logic [and ior xor])
724 (define_code_iterator any_or [ior xor])
726 ;; Base name for insn mnemonic.
727 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
729 ;; Mapping of shift-right operators
730 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
732 ;; Base name for define_insn
733 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
735 ;; Base name for insn mnemonic.
736 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
738 ;; Mapping of rotate operators
739 (define_code_iterator any_rotate [rotate rotatert])
741 ;; Base name for define_insn
742 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
744 ;; Base name for insn mnemonic.
745 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
747 ;; Mapping of abs neg operators
748 (define_code_iterator absneg [abs neg])
750 ;; Base name for x87 insn mnemonic.
751 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
753 ;; Used in signed and unsigned widening multiplications.
754 (define_code_iterator any_extend [sign_extend zero_extend])
756 ;; Various insn prefixes for signed and unsigned operations.
757 (define_code_attr u [(sign_extend "") (zero_extend "u")
758 (div "") (udiv "u")])
759 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
761 ;; Used in signed and unsigned divisions.
762 (define_code_iterator any_div [div udiv])
764 ;; Instruction prefix for signed and unsigned operations.
765 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
766 (div "i") (udiv "")])
768 ;; 64bit single word integer modes.
769 (define_mode_iterator SWI1248x [QI HI SI DI])
771 ;; 64bit single word integer modes without QImode and HImode.
772 (define_mode_iterator SWI48x [SI DI])
774 ;; Single word integer modes.
775 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
777 ;; Single word integer modes without SImode and DImode.
778 (define_mode_iterator SWI12 [QI HI])
780 ;; Single word integer modes without DImode.
781 (define_mode_iterator SWI124 [QI HI SI])
783 ;; Single word integer modes without QImode and DImode.
784 (define_mode_iterator SWI24 [HI SI])
786 ;; Single word integer modes without QImode.
787 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
789 ;; Single word integer modes without QImode and HImode.
790 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
792 ;; All math-dependant single and double word integer modes.
793 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
794 (HI "TARGET_HIMODE_MATH")
795 SI DI (TI "TARGET_64BIT")])
797 ;; Math-dependant single word integer modes.
798 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
799 (HI "TARGET_HIMODE_MATH")
800 SI (DI "TARGET_64BIT")])
802 ;; Math-dependant single word integer modes without DImode.
803 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
804 (HI "TARGET_HIMODE_MATH")
807 ;; Math-dependant single word integer modes without QImode.
808 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
809 SI (DI "TARGET_64BIT")])
811 ;; Double word integer modes.
812 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
813 (TI "TARGET_64BIT")])
815 ;; Double word integer modes as mode attribute.
816 (define_mode_attr DWI [(SI "DI") (DI "TI")])
817 (define_mode_attr dwi [(SI "di") (DI "ti")])
819 ;; Half mode for double word integer modes.
820 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
821 (DI "TARGET_64BIT")])
823 ;; Instruction suffix for integer modes.
824 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
826 ;; Pointer size prefix for integer modes (Intel asm dialect)
827 (define_mode_attr iptrsize [(QI "BYTE")
832 ;; Register class for integer modes.
833 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
835 ;; Immediate operand constraint for integer modes.
836 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
838 ;; General operand constraint for word modes.
839 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
841 ;; Immediate operand constraint for double integer modes.
842 (define_mode_attr di [(SI "iF") (DI "e")])
844 ;; Immediate operand constraint for shifts.
845 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
847 ;; General operand predicate for integer modes.
848 (define_mode_attr general_operand
849 [(QI "general_operand")
850 (HI "general_operand")
851 (SI "general_operand")
852 (DI "x86_64_general_operand")
853 (TI "x86_64_general_operand")])
855 ;; General sign/zero extend operand predicate for integer modes.
856 (define_mode_attr general_szext_operand
857 [(QI "general_operand")
858 (HI "general_operand")
859 (SI "general_operand")
860 (DI "x86_64_szext_general_operand")])
862 ;; Immediate operand predicate for integer modes.
863 (define_mode_attr immediate_operand
864 [(QI "immediate_operand")
865 (HI "immediate_operand")
866 (SI "immediate_operand")
867 (DI "x86_64_immediate_operand")])
869 ;; Nonmemory operand predicate for integer modes.
870 (define_mode_attr nonmemory_operand
871 [(QI "nonmemory_operand")
872 (HI "nonmemory_operand")
873 (SI "nonmemory_operand")
874 (DI "x86_64_nonmemory_operand")])
876 ;; Operand predicate for shifts.
877 (define_mode_attr shift_operand
878 [(QI "nonimmediate_operand")
879 (HI "nonimmediate_operand")
880 (SI "nonimmediate_operand")
881 (DI "shiftdi_operand")
882 (TI "register_operand")])
884 ;; Operand predicate for shift argument.
885 (define_mode_attr shift_immediate_operand
886 [(QI "const_1_to_31_operand")
887 (HI "const_1_to_31_operand")
888 (SI "const_1_to_31_operand")
889 (DI "const_1_to_63_operand")])
891 ;; Input operand predicate for arithmetic left shifts.
892 (define_mode_attr ashl_input_operand
893 [(QI "nonimmediate_operand")
894 (HI "nonimmediate_operand")
895 (SI "nonimmediate_operand")
896 (DI "ashldi_input_operand")
897 (TI "reg_or_pm1_operand")])
899 ;; SSE and x87 SFmode and DFmode floating point modes
900 (define_mode_iterator MODEF [SF DF])
902 ;; All x87 floating point modes
903 (define_mode_iterator X87MODEF [SF DF XF])
905 ;; All integer modes handled by x87 fisttp operator.
906 (define_mode_iterator X87MODEI [HI SI DI])
908 ;; All integer modes handled by integer x87 operators.
909 (define_mode_iterator X87MODEI12 [HI SI])
911 ;; All integer modes handled by SSE cvtts?2si* operators.
912 (define_mode_iterator SSEMODEI24 [SI DI])
914 ;; SSE asm suffix for floating point modes
915 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
917 ;; SSE vector mode corresponding to a scalar mode
918 (define_mode_attr ssevecmode
919 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
921 ;; Instruction suffix for REX 64bit operators.
922 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
924 ;; This mode iterator allows :P to be used for patterns that operate on
925 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
926 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
928 ;; Scheduling descriptions
930 (include "pentium.md")
933 (include "athlon.md")
934 (include "bdver1.md")
939 ;; Operand and operator predicates and constraints
941 (include "predicates.md")
942 (include "constraints.md")
945 ;; Compare and branch/compare and store instructions.
947 (define_expand "cbranch<mode>4"
948 [(set (reg:CC FLAGS_REG)
949 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
950 (match_operand:SDWIM 2 "<general_operand>" "")))
951 (set (pc) (if_then_else
952 (match_operator 0 "ordered_comparison_operator"
953 [(reg:CC FLAGS_REG) (const_int 0)])
954 (label_ref (match_operand 3 "" ""))
958 if (MEM_P (operands[1]) && MEM_P (operands[2]))
959 operands[1] = force_reg (<MODE>mode, operands[1]);
960 ix86_expand_branch (GET_CODE (operands[0]),
961 operands[1], operands[2], operands[3]);
965 (define_expand "cstore<mode>4"
966 [(set (reg:CC FLAGS_REG)
967 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
968 (match_operand:SWIM 3 "<general_operand>" "")))
969 (set (match_operand:QI 0 "register_operand" "")
970 (match_operator 1 "ordered_comparison_operator"
971 [(reg:CC FLAGS_REG) (const_int 0)]))]
974 if (MEM_P (operands[2]) && MEM_P (operands[3]))
975 operands[2] = force_reg (<MODE>mode, operands[2]);
976 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
977 operands[2], operands[3]);
981 (define_expand "cmp<mode>_1"
982 [(set (reg:CC FLAGS_REG)
983 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
984 (match_operand:SWI48 1 "<general_operand>" "")))])
986 (define_insn "*cmp<mode>_ccno_1"
987 [(set (reg FLAGS_REG)
988 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
989 (match_operand:SWI 1 "const0_operand" "")))]
990 "ix86_match_ccmode (insn, CCNOmode)"
992 test{<imodesuffix>}\t%0, %0
993 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
994 [(set_attr "type" "test,icmp")
995 (set_attr "length_immediate" "0,1")
996 (set_attr "mode" "<MODE>")])
998 (define_insn "*cmp<mode>_1"
999 [(set (reg FLAGS_REG)
1000 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1001 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1002 "ix86_match_ccmode (insn, CCmode)"
1003 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1004 [(set_attr "type" "icmp")
1005 (set_attr "mode" "<MODE>")])
1007 (define_insn "*cmp<mode>_minus_1"
1008 [(set (reg FLAGS_REG)
1010 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1011 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1013 "ix86_match_ccmode (insn, CCGOCmode)"
1014 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1015 [(set_attr "type" "icmp")
1016 (set_attr "mode" "<MODE>")])
1018 (define_insn "*cmpqi_ext_1"
1019 [(set (reg FLAGS_REG)
1021 (match_operand:QI 0 "general_operand" "Qm")
1024 (match_operand 1 "ext_register_operand" "Q")
1026 (const_int 8)) 0)))]
1027 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1028 "cmp{b}\t{%h1, %0|%0, %h1}"
1029 [(set_attr "type" "icmp")
1030 (set_attr "mode" "QI")])
1032 (define_insn "*cmpqi_ext_1_rex64"
1033 [(set (reg FLAGS_REG)
1035 (match_operand:QI 0 "register_operand" "Q")
1038 (match_operand 1 "ext_register_operand" "Q")
1040 (const_int 8)) 0)))]
1041 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1042 "cmp{b}\t{%h1, %0|%0, %h1}"
1043 [(set_attr "type" "icmp")
1044 (set_attr "mode" "QI")])
1046 (define_insn "*cmpqi_ext_2"
1047 [(set (reg FLAGS_REG)
1051 (match_operand 0 "ext_register_operand" "Q")
1054 (match_operand:QI 1 "const0_operand" "")))]
1055 "ix86_match_ccmode (insn, CCNOmode)"
1057 [(set_attr "type" "test")
1058 (set_attr "length_immediate" "0")
1059 (set_attr "mode" "QI")])
1061 (define_expand "cmpqi_ext_3"
1062 [(set (reg:CC FLAGS_REG)
1066 (match_operand 0 "ext_register_operand" "")
1069 (match_operand:QI 1 "immediate_operand" "")))])
1071 (define_insn "*cmpqi_ext_3_insn"
1072 [(set (reg FLAGS_REG)
1076 (match_operand 0 "ext_register_operand" "Q")
1079 (match_operand:QI 1 "general_operand" "Qmn")))]
1080 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1081 "cmp{b}\t{%1, %h0|%h0, %1}"
1082 [(set_attr "type" "icmp")
1083 (set_attr "modrm" "1")
1084 (set_attr "mode" "QI")])
1086 (define_insn "*cmpqi_ext_3_insn_rex64"
1087 [(set (reg FLAGS_REG)
1091 (match_operand 0 "ext_register_operand" "Q")
1094 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1095 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1096 "cmp{b}\t{%1, %h0|%h0, %1}"
1097 [(set_attr "type" "icmp")
1098 (set_attr "modrm" "1")
1099 (set_attr "mode" "QI")])
1101 (define_insn "*cmpqi_ext_4"
1102 [(set (reg FLAGS_REG)
1106 (match_operand 0 "ext_register_operand" "Q")
1111 (match_operand 1 "ext_register_operand" "Q")
1113 (const_int 8)) 0)))]
1114 "ix86_match_ccmode (insn, CCmode)"
1115 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1116 [(set_attr "type" "icmp")
1117 (set_attr "mode" "QI")])
1119 ;; These implement float point compares.
1120 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1121 ;; which would allow mix and match FP modes on the compares. Which is what
1122 ;; the old patterns did, but with many more of them.
1124 (define_expand "cbranchxf4"
1125 [(set (reg:CC FLAGS_REG)
1126 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1127 (match_operand:XF 2 "nonmemory_operand" "")))
1128 (set (pc) (if_then_else
1129 (match_operator 0 "ix86_fp_comparison_operator"
1132 (label_ref (match_operand 3 "" ""))
1136 ix86_expand_branch (GET_CODE (operands[0]),
1137 operands[1], operands[2], operands[3]);
1141 (define_expand "cstorexf4"
1142 [(set (reg:CC FLAGS_REG)
1143 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1144 (match_operand:XF 3 "nonmemory_operand" "")))
1145 (set (match_operand:QI 0 "register_operand" "")
1146 (match_operator 1 "ix86_fp_comparison_operator"
1151 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1152 operands[2], operands[3]);
1156 (define_expand "cbranch<mode>4"
1157 [(set (reg:CC FLAGS_REG)
1158 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1159 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1160 (set (pc) (if_then_else
1161 (match_operator 0 "ix86_fp_comparison_operator"
1164 (label_ref (match_operand 3 "" ""))
1166 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1168 ix86_expand_branch (GET_CODE (operands[0]),
1169 operands[1], operands[2], operands[3]);
1173 (define_expand "cstore<mode>4"
1174 [(set (reg:CC FLAGS_REG)
1175 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1176 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1177 (set (match_operand:QI 0 "register_operand" "")
1178 (match_operator 1 "ix86_fp_comparison_operator"
1181 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1183 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1184 operands[2], operands[3]);
1188 (define_expand "cbranchcc4"
1189 [(set (pc) (if_then_else
1190 (match_operator 0 "comparison_operator"
1191 [(match_operand 1 "flags_reg_operand" "")
1192 (match_operand 2 "const0_operand" "")])
1193 (label_ref (match_operand 3 "" ""))
1197 ix86_expand_branch (GET_CODE (operands[0]),
1198 operands[1], operands[2], operands[3]);
1202 (define_expand "cstorecc4"
1203 [(set (match_operand:QI 0 "register_operand" "")
1204 (match_operator 1 "comparison_operator"
1205 [(match_operand 2 "flags_reg_operand" "")
1206 (match_operand 3 "const0_operand" "")]))]
1209 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1210 operands[2], operands[3]);
1215 ;; FP compares, step 1:
1216 ;; Set the FP condition codes.
1218 ;; CCFPmode compare with exceptions
1219 ;; CCFPUmode compare with no exceptions
1221 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1222 ;; used to manage the reg stack popping would not be preserved.
1224 (define_insn "*cmpfp_0"
1225 [(set (match_operand:HI 0 "register_operand" "=a")
1228 (match_operand 1 "register_operand" "f")
1229 (match_operand 2 "const0_operand" ""))]
1231 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1232 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1233 "* return output_fp_compare (insn, operands, 0, 0);"
1234 [(set_attr "type" "multi")
1235 (set_attr "unit" "i387")
1237 (cond [(match_operand:SF 1 "" "")
1239 (match_operand:DF 1 "" "")
1242 (const_string "XF")))])
1244 (define_insn_and_split "*cmpfp_0_cc"
1245 [(set (reg:CCFP FLAGS_REG)
1247 (match_operand 1 "register_operand" "f")
1248 (match_operand 2 "const0_operand" "")))
1249 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1250 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1251 && TARGET_SAHF && !TARGET_CMOVE
1252 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1254 "&& reload_completed"
1257 [(compare:CCFP (match_dup 1)(match_dup 2))]
1259 (set (reg:CC FLAGS_REG)
1260 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1262 [(set_attr "type" "multi")
1263 (set_attr "unit" "i387")
1265 (cond [(match_operand:SF 1 "" "")
1267 (match_operand:DF 1 "" "")
1270 (const_string "XF")))])
1272 (define_insn "*cmpfp_xf"
1273 [(set (match_operand:HI 0 "register_operand" "=a")
1276 (match_operand:XF 1 "register_operand" "f")
1277 (match_operand:XF 2 "register_operand" "f"))]
1280 "* return output_fp_compare (insn, operands, 0, 0);"
1281 [(set_attr "type" "multi")
1282 (set_attr "unit" "i387")
1283 (set_attr "mode" "XF")])
1285 (define_insn_and_split "*cmpfp_xf_cc"
1286 [(set (reg:CCFP FLAGS_REG)
1288 (match_operand:XF 1 "register_operand" "f")
1289 (match_operand:XF 2 "register_operand" "f")))
1290 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1292 && TARGET_SAHF && !TARGET_CMOVE"
1294 "&& reload_completed"
1297 [(compare:CCFP (match_dup 1)(match_dup 2))]
1299 (set (reg:CC FLAGS_REG)
1300 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1302 [(set_attr "type" "multi")
1303 (set_attr "unit" "i387")
1304 (set_attr "mode" "XF")])
1306 (define_insn "*cmpfp_<mode>"
1307 [(set (match_operand:HI 0 "register_operand" "=a")
1310 (match_operand:MODEF 1 "register_operand" "f")
1311 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1314 "* return output_fp_compare (insn, operands, 0, 0);"
1315 [(set_attr "type" "multi")
1316 (set_attr "unit" "i387")
1317 (set_attr "mode" "<MODE>")])
1319 (define_insn_and_split "*cmpfp_<mode>_cc"
1320 [(set (reg:CCFP FLAGS_REG)
1322 (match_operand:MODEF 1 "register_operand" "f")
1323 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1324 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1326 && TARGET_SAHF && !TARGET_CMOVE"
1328 "&& reload_completed"
1331 [(compare:CCFP (match_dup 1)(match_dup 2))]
1333 (set (reg:CC FLAGS_REG)
1334 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1336 [(set_attr "type" "multi")
1337 (set_attr "unit" "i387")
1338 (set_attr "mode" "<MODE>")])
1340 (define_insn "*cmpfp_u"
1341 [(set (match_operand:HI 0 "register_operand" "=a")
1344 (match_operand 1 "register_operand" "f")
1345 (match_operand 2 "register_operand" "f"))]
1347 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1348 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1349 "* return output_fp_compare (insn, operands, 0, 1);"
1350 [(set_attr "type" "multi")
1351 (set_attr "unit" "i387")
1353 (cond [(match_operand:SF 1 "" "")
1355 (match_operand:DF 1 "" "")
1358 (const_string "XF")))])
1360 (define_insn_and_split "*cmpfp_u_cc"
1361 [(set (reg:CCFPU FLAGS_REG)
1363 (match_operand 1 "register_operand" "f")
1364 (match_operand 2 "register_operand" "f")))
1365 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1366 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1367 && TARGET_SAHF && !TARGET_CMOVE
1368 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1370 "&& reload_completed"
1373 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1375 (set (reg:CC FLAGS_REG)
1376 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1378 [(set_attr "type" "multi")
1379 (set_attr "unit" "i387")
1381 (cond [(match_operand:SF 1 "" "")
1383 (match_operand:DF 1 "" "")
1386 (const_string "XF")))])
1388 (define_insn "*cmpfp_<mode>"
1389 [(set (match_operand:HI 0 "register_operand" "=a")
1392 (match_operand 1 "register_operand" "f")
1393 (match_operator 3 "float_operator"
1394 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1396 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1397 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1398 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1399 "* return output_fp_compare (insn, operands, 0, 0);"
1400 [(set_attr "type" "multi")
1401 (set_attr "unit" "i387")
1402 (set_attr "fp_int_src" "true")
1403 (set_attr "mode" "<MODE>")])
1405 (define_insn_and_split "*cmpfp_<mode>_cc"
1406 [(set (reg:CCFP FLAGS_REG)
1408 (match_operand 1 "register_operand" "f")
1409 (match_operator 3 "float_operator"
1410 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1411 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1412 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1413 && TARGET_SAHF && !TARGET_CMOVE
1414 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1415 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1417 "&& reload_completed"
1422 (match_op_dup 3 [(match_dup 2)]))]
1424 (set (reg:CC FLAGS_REG)
1425 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1427 [(set_attr "type" "multi")
1428 (set_attr "unit" "i387")
1429 (set_attr "fp_int_src" "true")
1430 (set_attr "mode" "<MODE>")])
1432 ;; FP compares, step 2
1433 ;; Move the fpsw to ax.
1435 (define_insn "x86_fnstsw_1"
1436 [(set (match_operand:HI 0 "register_operand" "=a")
1437 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1440 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1441 (set_attr "mode" "SI")
1442 (set_attr "unit" "i387")])
1444 ;; FP compares, step 3
1445 ;; Get ax into flags, general case.
1447 (define_insn "x86_sahf_1"
1448 [(set (reg:CC FLAGS_REG)
1449 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1453 #ifndef HAVE_AS_IX86_SAHF
1455 return ASM_BYTE "0x9e";
1460 [(set_attr "length" "1")
1461 (set_attr "athlon_decode" "vector")
1462 (set_attr "amdfam10_decode" "direct")
1463 (set_attr "bdver1_decode" "direct")
1464 (set_attr "mode" "SI")])
1466 ;; Pentium Pro can do steps 1 through 3 in one go.
1467 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1468 (define_insn "*cmpfp_i_mixed"
1469 [(set (reg:CCFP FLAGS_REG)
1470 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1471 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1472 "TARGET_MIX_SSE_I387
1473 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1474 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1475 "* return output_fp_compare (insn, operands, 1, 0);"
1476 [(set_attr "type" "fcmp,ssecomi")
1477 (set_attr "prefix" "orig,maybe_vex")
1479 (if_then_else (match_operand:SF 1 "" "")
1481 (const_string "DF")))
1482 (set (attr "prefix_rep")
1483 (if_then_else (eq_attr "type" "ssecomi")
1485 (const_string "*")))
1486 (set (attr "prefix_data16")
1487 (cond [(eq_attr "type" "fcmp")
1489 (eq_attr "mode" "DF")
1492 (const_string "0")))
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")
1495 (set_attr "bdver1_decode" "double")])
1497 (define_insn "*cmpfp_i_sse"
1498 [(set (reg:CCFP FLAGS_REG)
1499 (compare:CCFP (match_operand 0 "register_operand" "x")
1500 (match_operand 1 "nonimmediate_operand" "xm")))]
1502 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1503 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1504 "* return output_fp_compare (insn, operands, 1, 0);"
1505 [(set_attr "type" "ssecomi")
1506 (set_attr "prefix" "maybe_vex")
1508 (if_then_else (match_operand:SF 1 "" "")
1510 (const_string "DF")))
1511 (set_attr "prefix_rep" "0")
1512 (set (attr "prefix_data16")
1513 (if_then_else (eq_attr "mode" "DF")
1515 (const_string "0")))
1516 (set_attr "athlon_decode" "vector")
1517 (set_attr "amdfam10_decode" "direct")
1518 (set_attr "bdver1_decode" "double")])
1520 (define_insn "*cmpfp_i_i387"
1521 [(set (reg:CCFP FLAGS_REG)
1522 (compare:CCFP (match_operand 0 "register_operand" "f")
1523 (match_operand 1 "register_operand" "f")))]
1524 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1526 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1527 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1528 "* return output_fp_compare (insn, operands, 1, 0);"
1529 [(set_attr "type" "fcmp")
1531 (cond [(match_operand:SF 1 "" "")
1533 (match_operand:DF 1 "" "")
1536 (const_string "XF")))
1537 (set_attr "athlon_decode" "vector")
1538 (set_attr "amdfam10_decode" "direct")
1539 (set_attr "bdver1_decode" "double")])
1541 (define_insn "*cmpfp_iu_mixed"
1542 [(set (reg:CCFPU FLAGS_REG)
1543 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1544 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1545 "TARGET_MIX_SSE_I387
1546 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1547 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1548 "* return output_fp_compare (insn, operands, 1, 1);"
1549 [(set_attr "type" "fcmp,ssecomi")
1550 (set_attr "prefix" "orig,maybe_vex")
1552 (if_then_else (match_operand:SF 1 "" "")
1554 (const_string "DF")))
1555 (set (attr "prefix_rep")
1556 (if_then_else (eq_attr "type" "ssecomi")
1558 (const_string "*")))
1559 (set (attr "prefix_data16")
1560 (cond [(eq_attr "type" "fcmp")
1562 (eq_attr "mode" "DF")
1565 (const_string "0")))
1566 (set_attr "athlon_decode" "vector")
1567 (set_attr "amdfam10_decode" "direct")
1568 (set_attr "bdver1_decode" "double")])
1570 (define_insn "*cmpfp_iu_sse"
1571 [(set (reg:CCFPU FLAGS_REG)
1572 (compare:CCFPU (match_operand 0 "register_operand" "x")
1573 (match_operand 1 "nonimmediate_operand" "xm")))]
1575 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1576 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1577 "* return output_fp_compare (insn, operands, 1, 1);"
1578 [(set_attr "type" "ssecomi")
1579 (set_attr "prefix" "maybe_vex")
1581 (if_then_else (match_operand:SF 1 "" "")
1583 (const_string "DF")))
1584 (set_attr "prefix_rep" "0")
1585 (set (attr "prefix_data16")
1586 (if_then_else (eq_attr "mode" "DF")
1588 (const_string "0")))
1589 (set_attr "athlon_decode" "vector")
1590 (set_attr "amdfam10_decode" "direct")
1591 (set_attr "bdver1_decode" "double")])
1593 (define_insn "*cmpfp_iu_387"
1594 [(set (reg:CCFPU FLAGS_REG)
1595 (compare:CCFPU (match_operand 0 "register_operand" "f")
1596 (match_operand 1 "register_operand" "f")))]
1597 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1599 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1600 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1601 "* return output_fp_compare (insn, operands, 1, 1);"
1602 [(set_attr "type" "fcmp")
1604 (cond [(match_operand:SF 1 "" "")
1606 (match_operand:DF 1 "" "")
1609 (const_string "XF")))
1610 (set_attr "athlon_decode" "vector")
1611 (set_attr "amdfam10_decode" "direct")
1612 (set_attr "bdver1_decode" "direct")])
1614 ;; Push/pop instructions.
1616 (define_insn "*push<mode>2"
1617 [(set (match_operand:DWI 0 "push_operand" "=<")
1618 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1623 [(set (match_operand:TI 0 "push_operand" "")
1624 (match_operand:TI 1 "general_operand" ""))]
1625 "TARGET_64BIT && reload_completed
1626 && !SSE_REG_P (operands[1])"
1628 "ix86_split_long_move (operands); DONE;")
1630 (define_insn "*pushdi2_rex64"
1631 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1632 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1637 [(set_attr "type" "push,multi")
1638 (set_attr "mode" "DI")])
1640 ;; Convert impossible pushes of immediate to existing instructions.
1641 ;; First try to get scratch register and go through it. In case this
1642 ;; fails, push sign extended lower part first and then overwrite
1643 ;; upper part by 32bit move.
1645 [(match_scratch:DI 2 "r")
1646 (set (match_operand:DI 0 "push_operand" "")
1647 (match_operand:DI 1 "immediate_operand" ""))]
1648 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1649 && !x86_64_immediate_operand (operands[1], DImode)"
1650 [(set (match_dup 2) (match_dup 1))
1651 (set (match_dup 0) (match_dup 2))])
1653 ;; We need to define this as both peepholer and splitter for case
1654 ;; peephole2 pass is not run.
1655 ;; "&& 1" is needed to keep it from matching the previous pattern.
1657 [(set (match_operand:DI 0 "push_operand" "")
1658 (match_operand:DI 1 "immediate_operand" ""))]
1659 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1660 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1661 [(set (match_dup 0) (match_dup 1))
1662 (set (match_dup 2) (match_dup 3))]
1664 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1666 operands[1] = gen_lowpart (DImode, operands[2]);
1667 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1672 [(set (match_operand:DI 0 "push_operand" "")
1673 (match_operand:DI 1 "immediate_operand" ""))]
1674 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1675 ? epilogue_completed : reload_completed)
1676 && !symbolic_operand (operands[1], DImode)
1677 && !x86_64_immediate_operand (operands[1], DImode)"
1678 [(set (match_dup 0) (match_dup 1))
1679 (set (match_dup 2) (match_dup 3))]
1681 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1683 operands[1] = gen_lowpart (DImode, operands[2]);
1684 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1689 [(set (match_operand:DI 0 "push_operand" "")
1690 (match_operand:DI 1 "general_operand" ""))]
1691 "!TARGET_64BIT && reload_completed
1692 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1694 "ix86_split_long_move (operands); DONE;")
1696 (define_insn "*pushsi2"
1697 [(set (match_operand:SI 0 "push_operand" "=<")
1698 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1701 [(set_attr "type" "push")
1702 (set_attr "mode" "SI")])
1704 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1705 ;; "push a byte/word". But actually we use pushl, which has the effect
1706 ;; of rounding the amount pushed up to a word.
1708 ;; For TARGET_64BIT we always round up to 8 bytes.
1709 (define_insn "*push<mode>2_rex64"
1710 [(set (match_operand:SWI124 0 "push_operand" "=X")
1711 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1714 [(set_attr "type" "push")
1715 (set_attr "mode" "DI")])
1717 (define_insn "*push<mode>2"
1718 [(set (match_operand:SWI12 0 "push_operand" "=X")
1719 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1722 [(set_attr "type" "push")
1723 (set_attr "mode" "SI")])
1725 (define_insn "*push<mode>2_prologue"
1726 [(set (match_operand:P 0 "push_operand" "=<")
1727 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1728 (clobber (mem:BLK (scratch)))]
1730 "push{<imodesuffix>}\t%1"
1731 [(set_attr "type" "push")
1732 (set_attr "mode" "<MODE>")])
1734 (define_insn "*pop<mode>1"
1735 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1736 (match_operand:P 1 "pop_operand" ">"))]
1738 "pop{<imodesuffix>}\t%0"
1739 [(set_attr "type" "pop")
1740 (set_attr "mode" "<MODE>")])
1742 (define_insn "*pop<mode>1_epilogue"
1743 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1744 (match_operand:P 1 "pop_operand" ">"))
1745 (clobber (mem:BLK (scratch)))]
1747 "pop{<imodesuffix>}\t%0"
1748 [(set_attr "type" "pop")
1749 (set_attr "mode" "<MODE>")])
1751 ;; Move instructions.
1753 (define_expand "movoi"
1754 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1755 (match_operand:OI 1 "general_operand" ""))]
1757 "ix86_expand_move (OImode, operands); DONE;")
1759 (define_expand "movti"
1760 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1761 (match_operand:TI 1 "nonimmediate_operand" ""))]
1762 "TARGET_64BIT || TARGET_SSE"
1765 ix86_expand_move (TImode, operands);
1766 else if (push_operand (operands[0], TImode))
1767 ix86_expand_push (TImode, operands[1]);
1769 ix86_expand_vector_move (TImode, operands);
1773 ;; This expands to what emit_move_complex would generate if we didn't
1774 ;; have a movti pattern. Having this avoids problems with reload on
1775 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1776 ;; to have around all the time.
1777 (define_expand "movcdi"
1778 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1779 (match_operand:CDI 1 "general_operand" ""))]
1782 if (push_operand (operands[0], CDImode))
1783 emit_move_complex_push (CDImode, operands[0], operands[1]);
1785 emit_move_complex_parts (operands[0], operands[1]);
1789 (define_expand "mov<mode>"
1790 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1791 (match_operand:SWI1248x 1 "general_operand" ""))]
1793 "ix86_expand_move (<MODE>mode, operands); DONE;")
1795 (define_insn "*mov<mode>_xor"
1796 [(set (match_operand:SWI48 0 "register_operand" "=r")
1797 (match_operand:SWI48 1 "const0_operand" ""))
1798 (clobber (reg:CC FLAGS_REG))]
1801 [(set_attr "type" "alu1")
1802 (set_attr "mode" "SI")
1803 (set_attr "length_immediate" "0")])
1805 (define_insn "*mov<mode>_or"
1806 [(set (match_operand:SWI48 0 "register_operand" "=r")
1807 (match_operand:SWI48 1 "const_int_operand" ""))
1808 (clobber (reg:CC FLAGS_REG))]
1810 && operands[1] == constm1_rtx"
1811 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1812 [(set_attr "type" "alu1")
1813 (set_attr "mode" "<MODE>")
1814 (set_attr "length_immediate" "1")])
1816 (define_insn "*movoi_internal_avx"
1817 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1818 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1819 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1821 switch (which_alternative)
1824 return "vxorps\t%0, %0, %0";
1827 if (misaligned_operand (operands[0], OImode)
1828 || misaligned_operand (operands[1], OImode))
1829 return "vmovdqu\t{%1, %0|%0, %1}";
1831 return "vmovdqa\t{%1, %0|%0, %1}";
1836 [(set_attr "type" "sselog1,ssemov,ssemov")
1837 (set_attr "prefix" "vex")
1838 (set_attr "mode" "OI")])
1840 (define_insn "*movti_internal_rex64"
1841 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1842 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1843 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1845 switch (which_alternative)
1851 if (get_attr_mode (insn) == MODE_V4SF)
1852 return "%vxorps\t%0, %d0";
1854 return "%vpxor\t%0, %d0";
1857 /* TDmode values are passed as TImode on the stack. Moving them
1858 to stack may result in unaligned memory access. */
1859 if (misaligned_operand (operands[0], TImode)
1860 || misaligned_operand (operands[1], TImode))
1862 if (get_attr_mode (insn) == MODE_V4SF)
1863 return "%vmovups\t{%1, %0|%0, %1}";
1865 return "%vmovdqu\t{%1, %0|%0, %1}";
1869 if (get_attr_mode (insn) == MODE_V4SF)
1870 return "%vmovaps\t{%1, %0|%0, %1}";
1872 return "%vmovdqa\t{%1, %0|%0, %1}";
1878 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1879 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1881 (cond [(eq_attr "alternative" "2,3")
1883 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1885 (const_string "V4SF")
1886 (const_string "TI"))
1887 (eq_attr "alternative" "4")
1889 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1891 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1893 (const_string "V4SF")
1894 (const_string "TI"))]
1895 (const_string "DI")))])
1898 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1899 (match_operand:TI 1 "general_operand" ""))]
1901 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1903 "ix86_split_long_move (operands); DONE;")
1905 (define_insn "*movti_internal_sse"
1906 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1907 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1908 "TARGET_SSE && !TARGET_64BIT
1909 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1911 switch (which_alternative)
1914 if (get_attr_mode (insn) == MODE_V4SF)
1915 return "%vxorps\t%0, %d0";
1917 return "%vpxor\t%0, %d0";
1920 /* TDmode values are passed as TImode on the stack. Moving them
1921 to stack may result in unaligned memory access. */
1922 if (misaligned_operand (operands[0], TImode)
1923 || misaligned_operand (operands[1], TImode))
1925 if (get_attr_mode (insn) == MODE_V4SF)
1926 return "%vmovups\t{%1, %0|%0, %1}";
1928 return "%vmovdqu\t{%1, %0|%0, %1}";
1932 if (get_attr_mode (insn) == MODE_V4SF)
1933 return "%vmovaps\t{%1, %0|%0, %1}";
1935 return "%vmovdqa\t{%1, %0|%0, %1}";
1941 [(set_attr "type" "sselog1,ssemov,ssemov")
1942 (set_attr "prefix" "maybe_vex")
1944 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1945 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1947 (const_string "V4SF")
1948 (and (eq_attr "alternative" "2")
1949 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1951 (const_string "V4SF")]
1952 (const_string "TI")))])
1954 (define_insn "*movdi_internal_rex64"
1955 [(set (match_operand:DI 0 "nonimmediate_operand"
1956 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1957 (match_operand:DI 1 "general_operand"
1958 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1959 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1961 switch (get_attr_type (insn))
1964 if (SSE_REG_P (operands[0]))
1965 return "movq2dq\t{%1, %0|%0, %1}";
1967 return "movdq2q\t{%1, %0|%0, %1}";
1972 if (get_attr_mode (insn) == MODE_TI)
1973 return "vmovdqa\t{%1, %0|%0, %1}";
1975 return "vmovq\t{%1, %0|%0, %1}";
1978 if (get_attr_mode (insn) == MODE_TI)
1979 return "movdqa\t{%1, %0|%0, %1}";
1983 /* Moves from and into integer register is done using movd
1984 opcode with REX prefix. */
1985 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1986 return "movd\t{%1, %0|%0, %1}";
1987 return "movq\t{%1, %0|%0, %1}";
1990 return "%vpxor\t%0, %d0";
1993 return "pxor\t%0, %0";
1999 return "lea{q}\t{%a1, %0|%0, %a1}";
2002 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2003 if (get_attr_mode (insn) == MODE_SI)
2004 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2005 else if (which_alternative == 2)
2006 return "movabs{q}\t{%1, %0|%0, %1}";
2008 return "mov{q}\t{%1, %0|%0, %1}";
2012 (cond [(eq_attr "alternative" "5")
2013 (const_string "mmx")
2014 (eq_attr "alternative" "6,7,8,9,10")
2015 (const_string "mmxmov")
2016 (eq_attr "alternative" "11")
2017 (const_string "sselog1")
2018 (eq_attr "alternative" "12,13,14,15,16")
2019 (const_string "ssemov")
2020 (eq_attr "alternative" "17,18")
2021 (const_string "ssecvt")
2022 (eq_attr "alternative" "4")
2023 (const_string "multi")
2024 (match_operand:DI 1 "pic_32bit_operand" "")
2025 (const_string "lea")
2027 (const_string "imov")))
2030 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2032 (const_string "*")))
2033 (set (attr "length_immediate")
2035 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2037 (const_string "*")))
2038 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2039 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2040 (set (attr "prefix")
2041 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2042 (const_string "maybe_vex")
2043 (const_string "orig")))
2044 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2046 ;; Convert impossible stores of immediate to existing instructions.
2047 ;; First try to get scratch register and go through it. In case this
2048 ;; fails, move by 32bit parts.
2050 [(match_scratch:DI 2 "r")
2051 (set (match_operand:DI 0 "memory_operand" "")
2052 (match_operand:DI 1 "immediate_operand" ""))]
2053 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2054 && !x86_64_immediate_operand (operands[1], DImode)"
2055 [(set (match_dup 2) (match_dup 1))
2056 (set (match_dup 0) (match_dup 2))])
2058 ;; We need to define this as both peepholer and splitter for case
2059 ;; peephole2 pass is not run.
2060 ;; "&& 1" is needed to keep it from matching the previous pattern.
2062 [(set (match_operand:DI 0 "memory_operand" "")
2063 (match_operand:DI 1 "immediate_operand" ""))]
2064 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2065 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2066 [(set (match_dup 2) (match_dup 3))
2067 (set (match_dup 4) (match_dup 5))]
2068 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2071 [(set (match_operand:DI 0 "memory_operand" "")
2072 (match_operand:DI 1 "immediate_operand" ""))]
2073 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2074 ? epilogue_completed : reload_completed)
2075 && !symbolic_operand (operands[1], DImode)
2076 && !x86_64_immediate_operand (operands[1], DImode)"
2077 [(set (match_dup 2) (match_dup 3))
2078 (set (match_dup 4) (match_dup 5))]
2079 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2081 (define_insn "*movdi_internal"
2082 [(set (match_operand:DI 0 "nonimmediate_operand"
2083 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2084 (match_operand:DI 1 "general_operand"
2085 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2086 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2091 movq\t{%1, %0|%0, %1}
2092 movq\t{%1, %0|%0, %1}
2094 %vmovq\t{%1, %0|%0, %1}
2095 %vmovdqa\t{%1, %0|%0, %1}
2096 %vmovq\t{%1, %0|%0, %1}
2098 movlps\t{%1, %0|%0, %1}
2099 movaps\t{%1, %0|%0, %1}
2100 movlps\t{%1, %0|%0, %1}"
2101 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2102 (set (attr "prefix")
2103 (if_then_else (eq_attr "alternative" "5,6,7,8")
2104 (const_string "vex")
2105 (const_string "orig")))
2106 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2109 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2110 (match_operand:DI 1 "general_operand" ""))]
2111 "!TARGET_64BIT && reload_completed
2112 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2113 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2115 "ix86_split_long_move (operands); DONE;")
2117 (define_insn "*movsi_internal"
2118 [(set (match_operand:SI 0 "nonimmediate_operand"
2119 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2120 (match_operand:SI 1 "general_operand"
2121 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2122 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2124 switch (get_attr_type (insn))
2127 if (get_attr_mode (insn) == MODE_TI)
2128 return "%vpxor\t%0, %d0";
2129 return "%vxorps\t%0, %d0";
2132 switch (get_attr_mode (insn))
2135 return "%vmovdqa\t{%1, %0|%0, %1}";
2137 return "%vmovaps\t{%1, %0|%0, %1}";
2139 return "%vmovd\t{%1, %0|%0, %1}";
2141 return "%vmovss\t{%1, %0|%0, %1}";
2147 return "pxor\t%0, %0";
2150 if (get_attr_mode (insn) == MODE_DI)
2151 return "movq\t{%1, %0|%0, %1}";
2152 return "movd\t{%1, %0|%0, %1}";
2155 return "lea{l}\t{%a1, %0|%0, %a1}";
2158 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2159 return "mov{l}\t{%1, %0|%0, %1}";
2163 (cond [(eq_attr "alternative" "2")
2164 (const_string "mmx")
2165 (eq_attr "alternative" "3,4,5")
2166 (const_string "mmxmov")
2167 (eq_attr "alternative" "6")
2168 (const_string "sselog1")
2169 (eq_attr "alternative" "7,8,9,10,11")
2170 (const_string "ssemov")
2171 (match_operand:DI 1 "pic_32bit_operand" "")
2172 (const_string "lea")
2174 (const_string "imov")))
2175 (set (attr "prefix")
2176 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2177 (const_string "orig")
2178 (const_string "maybe_vex")))
2179 (set (attr "prefix_data16")
2180 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2182 (const_string "*")))
2184 (cond [(eq_attr "alternative" "2,3")
2186 (eq_attr "alternative" "6,7")
2188 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2189 (const_string "V4SF")
2190 (const_string "TI"))
2191 (and (eq_attr "alternative" "8,9,10,11")
2192 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2195 (const_string "SI")))])
2197 (define_insn "*movhi_internal"
2198 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2199 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2200 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2202 switch (get_attr_type (insn))
2205 /* movzwl is faster than movw on p2 due to partial word stalls,
2206 though not as fast as an aligned movl. */
2207 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2209 if (get_attr_mode (insn) == MODE_SI)
2210 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2212 return "mov{w}\t{%1, %0|%0, %1}";
2216 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2218 (const_string "imov")
2219 (and (eq_attr "alternative" "0")
2220 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2222 (eq (symbol_ref "TARGET_HIMODE_MATH")
2224 (const_string "imov")
2225 (and (eq_attr "alternative" "1,2")
2226 (match_operand:HI 1 "aligned_operand" ""))
2227 (const_string "imov")
2228 (and (ne (symbol_ref "TARGET_MOVX")
2230 (eq_attr "alternative" "0,2"))
2231 (const_string "imovx")
2233 (const_string "imov")))
2235 (cond [(eq_attr "type" "imovx")
2237 (and (eq_attr "alternative" "1,2")
2238 (match_operand:HI 1 "aligned_operand" ""))
2240 (and (eq_attr "alternative" "0")
2241 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2243 (eq (symbol_ref "TARGET_HIMODE_MATH")
2247 (const_string "HI")))])
2249 ;; Situation is quite tricky about when to choose full sized (SImode) move
2250 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2251 ;; partial register dependency machines (such as AMD Athlon), where QImode
2252 ;; moves issue extra dependency and for partial register stalls machines
2253 ;; that don't use QImode patterns (and QImode move cause stall on the next
2256 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2257 ;; register stall machines with, where we use QImode instructions, since
2258 ;; partial register stall can be caused there. Then we use movzx.
2259 (define_insn "*movqi_internal"
2260 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2261 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2262 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2264 switch (get_attr_type (insn))
2267 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2268 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2270 if (get_attr_mode (insn) == MODE_SI)
2271 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2273 return "mov{b}\t{%1, %0|%0, %1}";
2277 (cond [(and (eq_attr "alternative" "5")
2278 (not (match_operand:QI 1 "aligned_operand" "")))
2279 (const_string "imovx")
2280 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2282 (const_string "imov")
2283 (and (eq_attr "alternative" "3")
2284 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2286 (eq (symbol_ref "TARGET_QIMODE_MATH")
2288 (const_string "imov")
2289 (eq_attr "alternative" "3,5")
2290 (const_string "imovx")
2291 (and (ne (symbol_ref "TARGET_MOVX")
2293 (eq_attr "alternative" "2"))
2294 (const_string "imovx")
2296 (const_string "imov")))
2298 (cond [(eq_attr "alternative" "3,4,5")
2300 (eq_attr "alternative" "6")
2302 (eq_attr "type" "imovx")
2304 (and (eq_attr "type" "imov")
2305 (and (eq_attr "alternative" "0,1")
2306 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2308 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2310 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2313 ;; Avoid partial register stalls when not using QImode arithmetic
2314 (and (eq_attr "type" "imov")
2315 (and (eq_attr "alternative" "0,1")
2316 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2318 (eq (symbol_ref "TARGET_QIMODE_MATH")
2322 (const_string "QI")))])
2324 ;; Stores and loads of ax to arbitrary constant address.
2325 ;; We fake an second form of instruction to force reload to load address
2326 ;; into register when rax is not available
2327 (define_insn "*movabs<mode>_1"
2328 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2329 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2330 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2332 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2333 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2334 [(set_attr "type" "imov")
2335 (set_attr "modrm" "0,*")
2336 (set_attr "length_address" "8,0")
2337 (set_attr "length_immediate" "0,*")
2338 (set_attr "memory" "store")
2339 (set_attr "mode" "<MODE>")])
2341 (define_insn "*movabs<mode>_2"
2342 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2343 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2344 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2346 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2347 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2348 [(set_attr "type" "imov")
2349 (set_attr "modrm" "0,*")
2350 (set_attr "length_address" "8,0")
2351 (set_attr "length_immediate" "0")
2352 (set_attr "memory" "load")
2353 (set_attr "mode" "<MODE>")])
2355 (define_insn "*swap<mode>"
2356 [(set (match_operand:SWI48 0 "register_operand" "+r")
2357 (match_operand:SWI48 1 "register_operand" "+r"))
2361 "xchg{<imodesuffix>}\t%1, %0"
2362 [(set_attr "type" "imov")
2363 (set_attr "mode" "<MODE>")
2364 (set_attr "pent_pair" "np")
2365 (set_attr "athlon_decode" "vector")
2366 (set_attr "amdfam10_decode" "double")
2367 (set_attr "bdver1_decode" "double")])
2369 (define_insn "*swap<mode>_1"
2370 [(set (match_operand:SWI12 0 "register_operand" "+r")
2371 (match_operand:SWI12 1 "register_operand" "+r"))
2374 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2376 [(set_attr "type" "imov")
2377 (set_attr "mode" "SI")
2378 (set_attr "pent_pair" "np")
2379 (set_attr "athlon_decode" "vector")
2380 (set_attr "amdfam10_decode" "double")
2381 (set_attr "bdver1_decode" "double")])
2383 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2384 ;; is disabled for AMDFAM10
2385 (define_insn "*swap<mode>_2"
2386 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2387 (match_operand:SWI12 1 "register_operand" "+<r>"))
2390 "TARGET_PARTIAL_REG_STALL"
2391 "xchg{<imodesuffix>}\t%1, %0"
2392 [(set_attr "type" "imov")
2393 (set_attr "mode" "<MODE>")
2394 (set_attr "pent_pair" "np")
2395 (set_attr "athlon_decode" "vector")])
2397 (define_expand "movstrict<mode>"
2398 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2399 (match_operand:SWI12 1 "general_operand" ""))]
2402 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2404 /* Don't generate memory->memory moves, go through a register */
2405 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2406 operands[1] = force_reg (<MODE>mode, operands[1]);
2409 (define_insn "*movstrict<mode>_1"
2410 [(set (strict_low_part
2411 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2412 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2413 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2414 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2415 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2416 [(set_attr "type" "imov")
2417 (set_attr "mode" "<MODE>")])
2419 (define_insn "*movstrict<mode>_xor"
2420 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2421 (match_operand:SWI12 1 "const0_operand" ""))
2422 (clobber (reg:CC FLAGS_REG))]
2424 "xor{<imodesuffix>}\t%0, %0"
2425 [(set_attr "type" "alu1")
2426 (set_attr "mode" "<MODE>")
2427 (set_attr "length_immediate" "0")])
2429 (define_insn "*mov<mode>_extv_1"
2430 [(set (match_operand:SWI24 0 "register_operand" "=R")
2431 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2435 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2436 [(set_attr "type" "imovx")
2437 (set_attr "mode" "SI")])
2439 (define_insn "*movqi_extv_1_rex64"
2440 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2441 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2446 switch (get_attr_type (insn))
2449 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2451 return "mov{b}\t{%h1, %0|%0, %h1}";
2455 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2456 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2457 (ne (symbol_ref "TARGET_MOVX")
2459 (const_string "imovx")
2460 (const_string "imov")))
2462 (if_then_else (eq_attr "type" "imovx")
2464 (const_string "QI")))])
2466 (define_insn "*movqi_extv_1"
2467 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2468 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2473 switch (get_attr_type (insn))
2476 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2478 return "mov{b}\t{%h1, %0|%0, %h1}";
2482 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2483 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2484 (ne (symbol_ref "TARGET_MOVX")
2486 (const_string "imovx")
2487 (const_string "imov")))
2489 (if_then_else (eq_attr "type" "imovx")
2491 (const_string "QI")))])
2493 (define_insn "*mov<mode>_extzv_1"
2494 [(set (match_operand:SWI48 0 "register_operand" "=R")
2495 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2499 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2500 [(set_attr "type" "imovx")
2501 (set_attr "mode" "SI")])
2503 (define_insn "*movqi_extzv_2_rex64"
2504 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2506 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2511 switch (get_attr_type (insn))
2514 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2516 return "mov{b}\t{%h1, %0|%0, %h1}";
2520 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2521 (ne (symbol_ref "TARGET_MOVX")
2523 (const_string "imovx")
2524 (const_string "imov")))
2526 (if_then_else (eq_attr "type" "imovx")
2528 (const_string "QI")))])
2530 (define_insn "*movqi_extzv_2"
2531 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2533 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2538 switch (get_attr_type (insn))
2541 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2543 return "mov{b}\t{%h1, %0|%0, %h1}";
2547 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2548 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2549 (ne (symbol_ref "TARGET_MOVX")
2551 (const_string "imovx")
2552 (const_string "imov")))
2554 (if_then_else (eq_attr "type" "imovx")
2556 (const_string "QI")))])
2558 (define_expand "mov<mode>_insv_1"
2559 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2562 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2564 (define_insn "*mov<mode>_insv_1_rex64"
2565 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2568 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2570 "mov{b}\t{%b1, %h0|%h0, %b1}"
2571 [(set_attr "type" "imov")
2572 (set_attr "mode" "QI")])
2574 (define_insn "*movsi_insv_1"
2575 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2578 (match_operand:SI 1 "general_operand" "Qmn"))]
2580 "mov{b}\t{%b1, %h0|%h0, %b1}"
2581 [(set_attr "type" "imov")
2582 (set_attr "mode" "QI")])
2584 (define_insn "*movqi_insv_2"
2585 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2588 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2591 "mov{b}\t{%h1, %h0|%h0, %h1}"
2592 [(set_attr "type" "imov")
2593 (set_attr "mode" "QI")])
2595 ;; Floating point push instructions.
2597 (define_insn "*pushtf"
2598 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2599 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2602 /* This insn should be already split before reg-stack. */
2605 [(set_attr "type" "multi")
2606 (set_attr "unit" "sse,*,*")
2607 (set_attr "mode" "TF,SI,SI")])
2610 [(set (match_operand:TF 0 "push_operand" "")
2611 (match_operand:TF 1 "sse_reg_operand" ""))]
2612 "TARGET_SSE2 && reload_completed"
2613 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2614 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2617 [(set (match_operand:TF 0 "push_operand" "")
2618 (match_operand:TF 1 "general_operand" ""))]
2619 "TARGET_SSE2 && reload_completed
2620 && !SSE_REG_P (operands[1])"
2622 "ix86_split_long_move (operands); DONE;")
2624 (define_insn "*pushxf"
2625 [(set (match_operand:XF 0 "push_operand" "=<,<")
2626 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2627 "optimize_function_for_speed_p (cfun)"
2629 /* This insn should be already split before reg-stack. */
2632 [(set_attr "type" "multi")
2633 (set_attr "unit" "i387,*")
2634 (set_attr "mode" "XF,SI")])
2636 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2637 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2638 ;; Pushing using integer instructions is longer except for constants
2639 ;; and direct memory references (assuming that any given constant is pushed
2640 ;; only once, but this ought to be handled elsewhere).
2642 (define_insn "*pushxf_nointeger"
2643 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2644 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2645 "optimize_function_for_size_p (cfun)"
2647 /* This insn should be already split before reg-stack. */
2650 [(set_attr "type" "multi")
2651 (set_attr "unit" "i387,*,*")
2652 (set_attr "mode" "XF,SI,SI")])
2655 [(set (match_operand:XF 0 "push_operand" "")
2656 (match_operand:XF 1 "fp_register_operand" ""))]
2658 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2659 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2660 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2663 [(set (match_operand:XF 0 "push_operand" "")
2664 (match_operand:XF 1 "general_operand" ""))]
2666 && !FP_REG_P (operands[1])"
2668 "ix86_split_long_move (operands); DONE;")
2670 (define_insn "*pushdf"
2671 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2672 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2673 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2675 /* This insn should be already split before reg-stack. */
2678 [(set_attr "type" "multi")
2679 (set_attr "unit" "i387,*,*")
2680 (set_attr "mode" "DF,SI,DF")])
2682 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2683 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2684 ;; On the average, pushdf using integers can be still shorter. Allow this
2685 ;; pattern for optimize_size too.
2687 (define_insn "*pushdf_nointeger"
2688 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2689 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2690 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2692 /* This insn should be already split before reg-stack. */
2695 [(set_attr "type" "multi")
2696 (set_attr "unit" "i387,*,*,*")
2697 (set_attr "mode" "DF,SI,SI,DF")])
2699 ;; %%% Kill this when call knows how to work this out.
2701 [(set (match_operand:DF 0 "push_operand" "")
2702 (match_operand:DF 1 "any_fp_register_operand" ""))]
2704 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2705 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2708 [(set (match_operand:DF 0 "push_operand" "")
2709 (match_operand:DF 1 "general_operand" ""))]
2711 && !ANY_FP_REG_P (operands[1])"
2713 "ix86_split_long_move (operands); DONE;")
2715 (define_insn "*pushsf_rex64"
2716 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2717 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2720 /* Anything else should be already split before reg-stack. */
2721 gcc_assert (which_alternative == 1);
2722 return "push{q}\t%q1";
2724 [(set_attr "type" "multi,push,multi")
2725 (set_attr "unit" "i387,*,*")
2726 (set_attr "mode" "SF,DI,SF")])
2728 (define_insn "*pushsf"
2729 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2730 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2733 /* Anything else should be already split before reg-stack. */
2734 gcc_assert (which_alternative == 1);
2735 return "push{l}\t%1";
2737 [(set_attr "type" "multi,push,multi")
2738 (set_attr "unit" "i387,*,*")
2739 (set_attr "mode" "SF,SI,SF")])
2742 [(set (match_operand:SF 0 "push_operand" "")
2743 (match_operand:SF 1 "memory_operand" ""))]
2745 && MEM_P (operands[1])
2746 && (operands[2] = find_constant_src (insn))"
2750 ;; %%% Kill this when call knows how to work this out.
2752 [(set (match_operand:SF 0 "push_operand" "")
2753 (match_operand:SF 1 "any_fp_register_operand" ""))]
2755 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2756 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2757 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2759 ;; Floating point move instructions.
2761 (define_expand "movtf"
2762 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2763 (match_operand:TF 1 "nonimmediate_operand" ""))]
2766 ix86_expand_move (TFmode, operands);
2770 (define_expand "mov<mode>"
2771 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2772 (match_operand:X87MODEF 1 "general_operand" ""))]
2774 "ix86_expand_move (<MODE>mode, operands); DONE;")
2776 (define_insn "*movtf_internal"
2777 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2778 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2780 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2782 switch (which_alternative)
2786 if (get_attr_mode (insn) == MODE_V4SF)
2787 return "%vmovaps\t{%1, %0|%0, %1}";
2789 return "%vmovdqa\t{%1, %0|%0, %1}";
2791 if (get_attr_mode (insn) == MODE_V4SF)
2792 return "%vxorps\t%0, %d0";
2794 return "%vpxor\t%0, %d0";
2802 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2803 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2805 (cond [(eq_attr "alternative" "0,2")
2807 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2809 (const_string "V4SF")
2810 (const_string "TI"))
2811 (eq_attr "alternative" "1")
2813 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2815 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2817 (const_string "V4SF")
2818 (const_string "TI"))]
2819 (const_string "DI")))])
2822 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2823 (match_operand:TF 1 "general_operand" ""))]
2825 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2827 "ix86_split_long_move (operands); DONE;")
2829 (define_insn "*movxf_internal"
2830 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2831 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2832 "optimize_function_for_speed_p (cfun)
2833 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2834 && (reload_in_progress || reload_completed
2835 || GET_CODE (operands[1]) != CONST_DOUBLE
2836 || memory_operand (operands[0], XFmode))"
2838 switch (which_alternative)
2842 return output_387_reg_move (insn, operands);
2845 return standard_80387_constant_opcode (operands[1]);
2854 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2855 (set_attr "mode" "XF,XF,XF,SI,SI")])
2857 ;; Do not use integer registers when optimizing for size
2858 (define_insn "*movxf_internal_nointeger"
2859 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2860 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2861 "optimize_function_for_size_p (cfun)
2862 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2863 && (reload_in_progress || reload_completed
2864 || standard_80387_constant_p (operands[1])
2865 || GET_CODE (operands[1]) != CONST_DOUBLE
2866 || memory_operand (operands[0], XFmode))"
2868 switch (which_alternative)
2872 return output_387_reg_move (insn, operands);
2875 return standard_80387_constant_opcode (operands[1]);
2883 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2884 (set_attr "mode" "XF,XF,XF,SI,SI")])
2887 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2888 (match_operand:XF 1 "general_operand" ""))]
2890 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2891 && ! (FP_REG_P (operands[0]) ||
2892 (GET_CODE (operands[0]) == SUBREG
2893 && FP_REG_P (SUBREG_REG (operands[0]))))
2894 && ! (FP_REG_P (operands[1]) ||
2895 (GET_CODE (operands[1]) == SUBREG
2896 && FP_REG_P (SUBREG_REG (operands[1]))))"
2898 "ix86_split_long_move (operands); DONE;")
2900 (define_insn "*movdf_internal_rex64"
2901 [(set (match_operand:DF 0 "nonimmediate_operand"
2902 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2903 (match_operand:DF 1 "general_operand"
2904 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2905 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2906 && (reload_in_progress || reload_completed
2907 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2908 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2909 && optimize_function_for_size_p (cfun)
2910 && standard_80387_constant_p (operands[1]))
2911 || GET_CODE (operands[1]) != CONST_DOUBLE
2912 || memory_operand (operands[0], DFmode))"
2914 switch (which_alternative)
2918 return output_387_reg_move (insn, operands);
2921 return standard_80387_constant_opcode (operands[1]);
2928 switch (get_attr_mode (insn))
2931 return "%vxorps\t%0, %d0";
2933 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2934 return "%vxorps\t%0, %d0";
2936 return "%vxorpd\t%0, %d0";
2938 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2939 return "%vxorps\t%0, %d0";
2941 return "%vpxor\t%0, %d0";
2948 switch (get_attr_mode (insn))
2951 return "%vmovaps\t{%1, %0|%0, %1}";
2953 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2954 return "%vmovaps\t{%1, %0|%0, %1}";
2956 return "%vmovapd\t{%1, %0|%0, %1}";
2958 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2959 return "%vmovaps\t{%1, %0|%0, %1}";
2961 return "%vmovdqa\t{%1, %0|%0, %1}";
2963 return "%vmovq\t{%1, %0|%0, %1}";
2967 if (REG_P (operands[0]) && REG_P (operands[1]))
2968 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2970 return "vmovsd\t{%1, %0|%0, %1}";
2973 return "movsd\t{%1, %0|%0, %1}";
2975 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2977 return "%vmovlps\t{%1, %d0|%d0, %1}";
2984 return "%vmovd\t{%1, %0|%0, %1}";
2990 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2991 (set (attr "prefix")
2992 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2993 (const_string "orig")
2994 (const_string "maybe_vex")))
2995 (set (attr "prefix_data16")
2996 (if_then_else (eq_attr "mode" "V1DF")
2998 (const_string "*")))
3000 (cond [(eq_attr "alternative" "0,1,2")
3002 (eq_attr "alternative" "3,4,9,10")
3005 /* For SSE1, we have many fewer alternatives. */
3006 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3007 (cond [(eq_attr "alternative" "5,6")
3008 (const_string "V4SF")
3010 (const_string "V2SF"))
3012 /* xorps is one byte shorter. */
3013 (eq_attr "alternative" "5")
3014 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3016 (const_string "V4SF")
3017 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3021 (const_string "V2DF"))
3023 /* For architectures resolving dependencies on
3024 whole SSE registers use APD move to break dependency
3025 chains, otherwise use short move to avoid extra work.
3027 movaps encodes one byte shorter. */
3028 (eq_attr "alternative" "6")
3030 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3032 (const_string "V4SF")
3033 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3035 (const_string "V2DF")
3037 (const_string "DF"))
3038 /* For architectures resolving dependencies on register
3039 parts we may avoid extra work to zero out upper part
3041 (eq_attr "alternative" "7")
3043 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3045 (const_string "V1DF")
3046 (const_string "DF"))
3048 (const_string "DF")))])
3050 (define_insn "*movdf_internal"
3051 [(set (match_operand:DF 0 "nonimmediate_operand"
3052 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3053 (match_operand:DF 1 "general_operand"
3054 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3055 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3056 && optimize_function_for_speed_p (cfun)
3057 && TARGET_INTEGER_DFMODE_MOVES
3058 && (reload_in_progress || reload_completed
3059 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3061 && optimize_function_for_size_p (cfun)
3062 && standard_80387_constant_p (operands[1]))
3063 || GET_CODE (operands[1]) != CONST_DOUBLE
3064 || memory_operand (operands[0], DFmode))"
3066 switch (which_alternative)
3070 return output_387_reg_move (insn, operands);
3073 return standard_80387_constant_opcode (operands[1]);
3080 switch (get_attr_mode (insn))
3083 return "xorps\t%0, %0";
3085 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3086 return "xorps\t%0, %0";
3088 return "xorpd\t%0, %0";
3090 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3091 return "xorps\t%0, %0";
3093 return "pxor\t%0, %0";
3100 switch (get_attr_mode (insn))
3103 return "movaps\t{%1, %0|%0, %1}";
3105 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3106 return "movaps\t{%1, %0|%0, %1}";
3108 return "movapd\t{%1, %0|%0, %1}";
3110 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3111 return "movaps\t{%1, %0|%0, %1}";
3113 return "movdqa\t{%1, %0|%0, %1}";
3115 return "movq\t{%1, %0|%0, %1}";
3117 return "movsd\t{%1, %0|%0, %1}";
3119 return "movlpd\t{%1, %0|%0, %1}";
3121 return "movlps\t{%1, %0|%0, %1}";
3130 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3131 (set (attr "prefix_data16")
3132 (if_then_else (eq_attr "mode" "V1DF")
3134 (const_string "*")))
3136 (cond [(eq_attr "alternative" "0,1,2")
3138 (eq_attr "alternative" "3,4")
3141 /* For SSE1, we have many fewer alternatives. */
3142 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3143 (cond [(eq_attr "alternative" "5,6")
3144 (const_string "V4SF")
3146 (const_string "V2SF"))
3148 /* xorps is one byte shorter. */
3149 (eq_attr "alternative" "5")
3150 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3152 (const_string "V4SF")
3153 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3157 (const_string "V2DF"))
3159 /* For architectures resolving dependencies on
3160 whole SSE registers use APD move to break dependency
3161 chains, otherwise use short move to avoid extra work.
3163 movaps encodes one byte shorter. */
3164 (eq_attr "alternative" "6")
3166 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3168 (const_string "V4SF")
3169 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3171 (const_string "V2DF")
3173 (const_string "DF"))
3174 /* For architectures resolving dependencies on register
3175 parts we may avoid extra work to zero out upper part
3177 (eq_attr "alternative" "7")
3179 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3181 (const_string "V1DF")
3182 (const_string "DF"))
3184 (const_string "DF")))])
3186 ;; Moving is usually shorter when only FP registers are used. This separate
3187 ;; movdf pattern avoids the use of integer registers for FP operations
3188 ;; when optimizing for size.
3190 (define_insn "*movdf_internal_nointeger"
3191 [(set (match_operand:DF 0 "nonimmediate_operand"
3192 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3193 (match_operand:DF 1 "general_operand"
3194 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3195 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3196 && ((optimize_function_for_size_p (cfun)
3197 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3198 && (reload_in_progress || reload_completed
3199 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3200 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3201 && optimize_function_for_size_p (cfun)
3202 && !memory_operand (operands[0], DFmode)
3203 && standard_80387_constant_p (operands[1]))
3204 || GET_CODE (operands[1]) != CONST_DOUBLE
3205 || ((optimize_function_for_size_p (cfun)
3206 || !TARGET_MEMORY_MISMATCH_STALL
3207 || reload_in_progress || reload_completed)
3208 && memory_operand (operands[0], DFmode)))"
3210 switch (which_alternative)
3214 return output_387_reg_move (insn, operands);
3217 return standard_80387_constant_opcode (operands[1]);
3224 switch (get_attr_mode (insn))
3227 return "%vxorps\t%0, %d0";
3229 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3230 return "%vxorps\t%0, %d0";
3232 return "%vxorpd\t%0, %d0";
3234 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3235 return "%vxorps\t%0, %d0";
3237 return "%vpxor\t%0, %d0";
3244 switch (get_attr_mode (insn))
3247 return "%vmovaps\t{%1, %0|%0, %1}";
3249 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3250 return "%vmovaps\t{%1, %0|%0, %1}";
3252 return "%vmovapd\t{%1, %0|%0, %1}";
3254 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3255 return "%vmovaps\t{%1, %0|%0, %1}";
3257 return "%vmovdqa\t{%1, %0|%0, %1}";
3259 return "%vmovq\t{%1, %0|%0, %1}";
3263 if (REG_P (operands[0]) && REG_P (operands[1]))
3264 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3266 return "vmovsd\t{%1, %0|%0, %1}";
3269 return "movsd\t{%1, %0|%0, %1}";
3273 if (REG_P (operands[0]))
3274 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3276 return "vmovlpd\t{%1, %0|%0, %1}";
3279 return "movlpd\t{%1, %0|%0, %1}";
3283 if (REG_P (operands[0]))
3284 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3286 return "vmovlps\t{%1, %0|%0, %1}";
3289 return "movlps\t{%1, %0|%0, %1}";
3298 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3299 (set (attr "prefix")
3300 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3301 (const_string "orig")
3302 (const_string "maybe_vex")))
3303 (set (attr "prefix_data16")
3304 (if_then_else (eq_attr "mode" "V1DF")
3306 (const_string "*")))
3308 (cond [(eq_attr "alternative" "0,1,2")
3310 (eq_attr "alternative" "3,4")
3313 /* For SSE1, we have many fewer alternatives. */
3314 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3315 (cond [(eq_attr "alternative" "5,6")
3316 (const_string "V4SF")
3318 (const_string "V2SF"))
3320 /* xorps is one byte shorter. */
3321 (eq_attr "alternative" "5")
3322 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3324 (const_string "V4SF")
3325 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3329 (const_string "V2DF"))
3331 /* For architectures resolving dependencies on
3332 whole SSE registers use APD move to break dependency
3333 chains, otherwise use short move to avoid extra work.
3335 movaps encodes one byte shorter. */
3336 (eq_attr "alternative" "6")
3338 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3340 (const_string "V4SF")
3341 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3343 (const_string "V2DF")
3345 (const_string "DF"))
3346 /* For architectures resolving dependencies on register
3347 parts we may avoid extra work to zero out upper part
3349 (eq_attr "alternative" "7")
3351 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3353 (const_string "V1DF")
3354 (const_string "DF"))
3356 (const_string "DF")))])
3359 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3360 (match_operand:DF 1 "general_operand" ""))]
3362 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3363 && ! (ANY_FP_REG_P (operands[0]) ||
3364 (GET_CODE (operands[0]) == SUBREG
3365 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3366 && ! (ANY_FP_REG_P (operands[1]) ||
3367 (GET_CODE (operands[1]) == SUBREG
3368 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3370 "ix86_split_long_move (operands); DONE;")
3372 (define_insn "*movsf_internal"
3373 [(set (match_operand:SF 0 "nonimmediate_operand"
3374 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3375 (match_operand:SF 1 "general_operand"
3376 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3377 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3378 && (reload_in_progress || reload_completed
3379 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3380 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3381 && standard_80387_constant_p (operands[1]))
3382 || GET_CODE (operands[1]) != CONST_DOUBLE
3383 || memory_operand (operands[0], SFmode))"
3385 switch (which_alternative)
3389 return output_387_reg_move (insn, operands);
3392 return standard_80387_constant_opcode (operands[1]);
3396 return "mov{l}\t{%1, %0|%0, %1}";
3398 if (get_attr_mode (insn) == MODE_TI)
3399 return "%vpxor\t%0, %d0";
3401 return "%vxorps\t%0, %d0";
3403 if (get_attr_mode (insn) == MODE_V4SF)
3404 return "%vmovaps\t{%1, %0|%0, %1}";
3406 return "%vmovss\t{%1, %d0|%d0, %1}";
3409 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3410 : "vmovss\t{%1, %0|%0, %1}";
3412 return "movss\t{%1, %0|%0, %1}";
3414 return "%vmovss\t{%1, %0|%0, %1}";
3416 case 9: case 10: case 14: case 15:
3417 return "movd\t{%1, %0|%0, %1}";
3419 return "%vmovd\t{%1, %0|%0, %1}";
3422 return "movq\t{%1, %0|%0, %1}";
3428 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3429 (set (attr "prefix")
3430 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3431 (const_string "maybe_vex")
3432 (const_string "orig")))
3434 (cond [(eq_attr "alternative" "3,4,9,10")
3436 (eq_attr "alternative" "5")
3438 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3440 (ne (symbol_ref "TARGET_SSE2")
3442 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3445 (const_string "V4SF"))
3446 /* For architectures resolving dependencies on
3447 whole SSE registers use APS move to break dependency
3448 chains, otherwise use short move to avoid extra work.
3450 Do the same for architectures resolving dependencies on
3451 the parts. While in DF mode it is better to always handle
3452 just register parts, the SF mode is different due to lack
3453 of instructions to load just part of the register. It is
3454 better to maintain the whole registers in single format
3455 to avoid problems on using packed logical operations. */
3456 (eq_attr "alternative" "6")
3458 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3460 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3462 (const_string "V4SF")
3463 (const_string "SF"))
3464 (eq_attr "alternative" "11")
3465 (const_string "DI")]
3466 (const_string "SF")))])
3469 [(set (match_operand 0 "register_operand" "")
3470 (match_operand 1 "memory_operand" ""))]
3472 && MEM_P (operands[1])
3473 && (GET_MODE (operands[0]) == TFmode
3474 || GET_MODE (operands[0]) == XFmode
3475 || GET_MODE (operands[0]) == DFmode
3476 || GET_MODE (operands[0]) == SFmode)
3477 && (operands[2] = find_constant_src (insn))"
3478 [(set (match_dup 0) (match_dup 2))]
3480 rtx c = operands[2];
3481 rtx r = operands[0];
3483 if (GET_CODE (r) == SUBREG)
3488 if (!standard_sse_constant_p (c))
3491 else if (FP_REG_P (r))
3493 if (!standard_80387_constant_p (c))
3496 else if (MMX_REG_P (r))
3501 [(set (match_operand 0 "register_operand" "")
3502 (float_extend (match_operand 1 "memory_operand" "")))]
3504 && MEM_P (operands[1])
3505 && (GET_MODE (operands[0]) == TFmode
3506 || GET_MODE (operands[0]) == XFmode
3507 || GET_MODE (operands[0]) == DFmode
3508 || GET_MODE (operands[0]) == SFmode)
3509 && (operands[2] = find_constant_src (insn))"
3510 [(set (match_dup 0) (match_dup 2))]
3512 rtx c = operands[2];
3513 rtx r = operands[0];
3515 if (GET_CODE (r) == SUBREG)
3520 if (!standard_sse_constant_p (c))
3523 else if (FP_REG_P (r))
3525 if (!standard_80387_constant_p (c))
3528 else if (MMX_REG_P (r))
3532 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3534 [(set (match_operand:X87MODEF 0 "register_operand" "")
3535 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3536 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3537 && (standard_80387_constant_p (operands[1]) == 8
3538 || standard_80387_constant_p (operands[1]) == 9)"
3539 [(set (match_dup 0)(match_dup 1))
3541 (neg:X87MODEF (match_dup 0)))]
3545 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3546 if (real_isnegzero (&r))
3547 operands[1] = CONST0_RTX (<MODE>mode);
3549 operands[1] = CONST1_RTX (<MODE>mode);
3552 (define_insn "swapxf"
3553 [(set (match_operand:XF 0 "register_operand" "+f")
3554 (match_operand:XF 1 "register_operand" "+f"))
3559 if (STACK_TOP_P (operands[0]))
3564 [(set_attr "type" "fxch")
3565 (set_attr "mode" "XF")])
3567 (define_insn "*swap<mode>"
3568 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3569 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3572 "TARGET_80387 || reload_completed"
3574 if (STACK_TOP_P (operands[0]))
3579 [(set_attr "type" "fxch")
3580 (set_attr "mode" "<MODE>")])
3582 ;; Zero extension instructions
3584 (define_expand "zero_extendsidi2"
3585 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3586 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3591 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3596 (define_insn "*zero_extendsidi2_rex64"
3597 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3599 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3602 mov\t{%k1, %k0|%k0, %k1}
3604 movd\t{%1, %0|%0, %1}
3605 movd\t{%1, %0|%0, %1}
3606 %vmovd\t{%1, %0|%0, %1}
3607 %vmovd\t{%1, %0|%0, %1}"
3608 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3609 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3610 (set_attr "prefix_0f" "0,*,*,*,*,*")
3611 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3614 [(set (match_operand:DI 0 "memory_operand" "")
3615 (zero_extend:DI (match_dup 0)))]
3617 [(set (match_dup 4) (const_int 0))]
3618 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3620 ;; %%% Kill me once multi-word ops are sane.
3621 (define_insn "zero_extendsidi2_1"
3622 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3624 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3625 (clobber (reg:CC FLAGS_REG))]
3631 movd\t{%1, %0|%0, %1}
3632 movd\t{%1, %0|%0, %1}
3633 %vmovd\t{%1, %0|%0, %1}
3634 %vmovd\t{%1, %0|%0, %1}"
3635 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3636 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3637 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3640 [(set (match_operand:DI 0 "register_operand" "")
3641 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3642 (clobber (reg:CC FLAGS_REG))]
3643 "!TARGET_64BIT && reload_completed
3644 && true_regnum (operands[0]) == true_regnum (operands[1])"
3645 [(set (match_dup 4) (const_int 0))]
3646 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3649 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3650 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3651 (clobber (reg:CC FLAGS_REG))]
3652 "!TARGET_64BIT && reload_completed
3653 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3654 [(set (match_dup 3) (match_dup 1))
3655 (set (match_dup 4) (const_int 0))]
3656 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3658 (define_insn "zero_extend<mode>di2"
3659 [(set (match_operand:DI 0 "register_operand" "=r")
3661 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3663 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3664 [(set_attr "type" "imovx")
3665 (set_attr "mode" "SI")])
3667 (define_expand "zero_extendhisi2"
3668 [(set (match_operand:SI 0 "register_operand" "")
3669 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3672 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3674 operands[1] = force_reg (HImode, operands[1]);
3675 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3680 (define_insn_and_split "zero_extendhisi2_and"
3681 [(set (match_operand:SI 0 "register_operand" "=r")
3682 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3683 (clobber (reg:CC FLAGS_REG))]
3684 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3686 "&& reload_completed"
3687 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3688 (clobber (reg:CC FLAGS_REG))])]
3690 [(set_attr "type" "alu1")
3691 (set_attr "mode" "SI")])
3693 (define_insn "*zero_extendhisi2_movzwl"
3694 [(set (match_operand:SI 0 "register_operand" "=r")
3695 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3696 "!TARGET_ZERO_EXTEND_WITH_AND
3697 || optimize_function_for_size_p (cfun)"
3698 "movz{wl|x}\t{%1, %0|%0, %1}"
3699 [(set_attr "type" "imovx")
3700 (set_attr "mode" "SI")])
3702 (define_expand "zero_extendqi<mode>2"
3704 [(set (match_operand:SWI24 0 "register_operand" "")
3705 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3706 (clobber (reg:CC FLAGS_REG))])])
3708 (define_insn "*zero_extendqi<mode>2_and"
3709 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3710 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3711 (clobber (reg:CC FLAGS_REG))]
3712 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3714 [(set_attr "type" "alu1")
3715 (set_attr "mode" "<MODE>")])
3717 ;; When source and destination does not overlap, clear destination
3718 ;; first and then do the movb
3720 [(set (match_operand:SWI24 0 "register_operand" "")
3721 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3722 (clobber (reg:CC FLAGS_REG))]
3724 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3725 && ANY_QI_REG_P (operands[0])
3726 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3727 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3728 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3730 operands[2] = gen_lowpart (QImode, operands[0]);
3731 ix86_expand_clear (operands[0]);
3734 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3735 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3736 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3737 (clobber (reg:CC FLAGS_REG))]
3738 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3740 [(set_attr "type" "imovx,alu1")
3741 (set_attr "mode" "<MODE>")])
3743 ;; For the movzbl case strip only the clobber
3745 [(set (match_operand:SWI24 0 "register_operand" "")
3746 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3747 (clobber (reg:CC FLAGS_REG))]
3749 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3750 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3752 (zero_extend:SWI24 (match_dup 1)))])
3754 ; zero extend to SImode to avoid partial register stalls
3755 (define_insn "*zero_extendqi<mode>2_movzbl"
3756 [(set (match_operand:SWI24 0 "register_operand" "=r")
3757 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3759 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3760 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3761 [(set_attr "type" "imovx")
3762 (set_attr "mode" "SI")])
3764 ;; Rest is handled by single and.
3766 [(set (match_operand:SWI24 0 "register_operand" "")
3767 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3768 (clobber (reg:CC FLAGS_REG))]
3770 && true_regnum (operands[0]) == true_regnum (operands[1])"
3771 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3772 (clobber (reg:CC FLAGS_REG))])])
3774 ;; Sign extension instructions
3776 (define_expand "extendsidi2"
3777 [(set (match_operand:DI 0 "register_operand" "")
3778 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3783 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3788 (define_insn "*extendsidi2_rex64"
3789 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3790 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3794 movs{lq|x}\t{%1, %0|%0, %1}"
3795 [(set_attr "type" "imovx")
3796 (set_attr "mode" "DI")
3797 (set_attr "prefix_0f" "0")
3798 (set_attr "modrm" "0,1")])
3800 (define_insn "extendsidi2_1"
3801 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3802 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3803 (clobber (reg:CC FLAGS_REG))
3804 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3808 ;; Extend to memory case when source register does die.
3810 [(set (match_operand:DI 0 "memory_operand" "")
3811 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3812 (clobber (reg:CC FLAGS_REG))
3813 (clobber (match_operand:SI 2 "register_operand" ""))]
3815 && dead_or_set_p (insn, operands[1])
3816 && !reg_mentioned_p (operands[1], operands[0]))"
3817 [(set (match_dup 3) (match_dup 1))
3818 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3819 (clobber (reg:CC FLAGS_REG))])
3820 (set (match_dup 4) (match_dup 1))]
3821 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3823 ;; Extend to memory case when source register does not die.
3825 [(set (match_operand:DI 0 "memory_operand" "")
3826 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3827 (clobber (reg:CC FLAGS_REG))
3828 (clobber (match_operand:SI 2 "register_operand" ""))]
3832 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3834 emit_move_insn (operands[3], operands[1]);
3836 /* Generate a cltd if possible and doing so it profitable. */
3837 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3838 && true_regnum (operands[1]) == AX_REG
3839 && true_regnum (operands[2]) == DX_REG)
3841 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3845 emit_move_insn (operands[2], operands[1]);
3846 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3848 emit_move_insn (operands[4], operands[2]);
3852 ;; Extend to register case. Optimize case where source and destination
3853 ;; registers match and cases where we can use cltd.
3855 [(set (match_operand:DI 0 "register_operand" "")
3856 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3857 (clobber (reg:CC FLAGS_REG))
3858 (clobber (match_scratch:SI 2 ""))]
3862 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3864 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3865 emit_move_insn (operands[3], operands[1]);
3867 /* Generate a cltd if possible and doing so it profitable. */
3868 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3869 && true_regnum (operands[3]) == AX_REG
3870 && true_regnum (operands[4]) == DX_REG)
3872 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3876 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3877 emit_move_insn (operands[4], operands[1]);
3879 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3883 (define_insn "extend<mode>di2"
3884 [(set (match_operand:DI 0 "register_operand" "=r")
3886 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3888 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3889 [(set_attr "type" "imovx")
3890 (set_attr "mode" "DI")])
3892 (define_insn "extendhisi2"
3893 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3894 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3897 switch (get_attr_prefix_0f (insn))
3900 return "{cwtl|cwde}";
3902 return "movs{wl|x}\t{%1, %0|%0, %1}";
3905 [(set_attr "type" "imovx")
3906 (set_attr "mode" "SI")
3907 (set (attr "prefix_0f")
3908 ;; movsx is short decodable while cwtl is vector decoded.
3909 (if_then_else (and (eq_attr "cpu" "!k6")
3910 (eq_attr "alternative" "0"))
3912 (const_string "1")))
3914 (if_then_else (eq_attr "prefix_0f" "0")
3916 (const_string "1")))])
3918 (define_insn "*extendhisi2_zext"
3919 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3922 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3925 switch (get_attr_prefix_0f (insn))
3928 return "{cwtl|cwde}";
3930 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3933 [(set_attr "type" "imovx")
3934 (set_attr "mode" "SI")
3935 (set (attr "prefix_0f")
3936 ;; movsx is short decodable while cwtl is vector decoded.
3937 (if_then_else (and (eq_attr "cpu" "!k6")
3938 (eq_attr "alternative" "0"))
3940 (const_string "1")))
3942 (if_then_else (eq_attr "prefix_0f" "0")
3944 (const_string "1")))])
3946 (define_insn "extendqisi2"
3947 [(set (match_operand:SI 0 "register_operand" "=r")
3948 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3950 "movs{bl|x}\t{%1, %0|%0, %1}"
3951 [(set_attr "type" "imovx")
3952 (set_attr "mode" "SI")])
3954 (define_insn "*extendqisi2_zext"
3955 [(set (match_operand:DI 0 "register_operand" "=r")
3957 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3959 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3960 [(set_attr "type" "imovx")
3961 (set_attr "mode" "SI")])
3963 (define_insn "extendqihi2"
3964 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3965 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3968 switch (get_attr_prefix_0f (insn))
3971 return "{cbtw|cbw}";
3973 return "movs{bw|x}\t{%1, %0|%0, %1}";
3976 [(set_attr "type" "imovx")
3977 (set_attr "mode" "HI")
3978 (set (attr "prefix_0f")
3979 ;; movsx is short decodable while cwtl is vector decoded.
3980 (if_then_else (and (eq_attr "cpu" "!k6")
3981 (eq_attr "alternative" "0"))
3983 (const_string "1")))
3985 (if_then_else (eq_attr "prefix_0f" "0")
3987 (const_string "1")))])
3989 ;; Conversions between float and double.
3991 ;; These are all no-ops in the model used for the 80387.
3992 ;; So just emit moves.
3994 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3996 [(set (match_operand:DF 0 "push_operand" "")
3997 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3999 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4000 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4003 [(set (match_operand:XF 0 "push_operand" "")
4004 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4006 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4007 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4008 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4010 (define_expand "extendsfdf2"
4011 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4012 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4013 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4015 /* ??? Needed for compress_float_constant since all fp constants
4016 are LEGITIMATE_CONSTANT_P. */
4017 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4019 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4020 && standard_80387_constant_p (operands[1]) > 0)
4022 operands[1] = simplify_const_unary_operation
4023 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4024 emit_move_insn_1 (operands[0], operands[1]);
4027 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4031 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4033 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4035 We do the conversion post reload to avoid producing of 128bit spills
4036 that might lead to ICE on 32bit target. The sequence unlikely combine
4039 [(set (match_operand:DF 0 "register_operand" "")
4041 (match_operand:SF 1 "nonimmediate_operand" "")))]
4042 "TARGET_USE_VECTOR_FP_CONVERTS
4043 && optimize_insn_for_speed_p ()
4044 && reload_completed && SSE_REG_P (operands[0])"
4049 (parallel [(const_int 0) (const_int 1)]))))]
4051 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4052 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4053 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4054 Try to avoid move when unpacking can be done in source. */
4055 if (REG_P (operands[1]))
4057 /* If it is unsafe to overwrite upper half of source, we need
4058 to move to destination and unpack there. */
4059 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4060 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4061 && true_regnum (operands[0]) != true_regnum (operands[1]))
4063 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4064 emit_move_insn (tmp, operands[1]);
4067 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4068 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4072 emit_insn (gen_vec_setv4sf_0 (operands[3],
4073 CONST0_RTX (V4SFmode), operands[1]));
4076 (define_insn "*extendsfdf2_mixed"
4077 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4079 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4080 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4082 switch (which_alternative)
4086 return output_387_reg_move (insn, operands);
4089 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4095 [(set_attr "type" "fmov,fmov,ssecvt")
4096 (set_attr "prefix" "orig,orig,maybe_vex")
4097 (set_attr "mode" "SF,XF,DF")])
4099 (define_insn "*extendsfdf2_sse"
4100 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4101 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4102 "TARGET_SSE2 && TARGET_SSE_MATH"
4103 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4104 [(set_attr "type" "ssecvt")
4105 (set_attr "prefix" "maybe_vex")
4106 (set_attr "mode" "DF")])
4108 (define_insn "*extendsfdf2_i387"
4109 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4110 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4112 "* return output_387_reg_move (insn, operands);"
4113 [(set_attr "type" "fmov")
4114 (set_attr "mode" "SF,XF")])
4116 (define_expand "extend<mode>xf2"
4117 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4118 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4121 /* ??? Needed for compress_float_constant since all fp constants
4122 are LEGITIMATE_CONSTANT_P. */
4123 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4125 if (standard_80387_constant_p (operands[1]) > 0)
4127 operands[1] = simplify_const_unary_operation
4128 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4129 emit_move_insn_1 (operands[0], operands[1]);
4132 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4136 (define_insn "*extend<mode>xf2_i387"
4137 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4139 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4141 "* return output_387_reg_move (insn, operands);"
4142 [(set_attr "type" "fmov")
4143 (set_attr "mode" "<MODE>,XF")])
4145 ;; %%% This seems bad bad news.
4146 ;; This cannot output into an f-reg because there is no way to be sure
4147 ;; of truncating in that case. Otherwise this is just like a simple move
4148 ;; insn. So we pretend we can output to a reg in order to get better
4149 ;; register preferencing, but we really use a stack slot.
4151 ;; Conversion from DFmode to SFmode.
4153 (define_expand "truncdfsf2"
4154 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4156 (match_operand:DF 1 "nonimmediate_operand" "")))]
4157 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4159 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4161 else if (flag_unsafe_math_optimizations)
4165 enum ix86_stack_slot slot = (virtuals_instantiated
4168 rtx temp = assign_386_stack_local (SFmode, slot);
4169 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4174 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4176 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4178 We do the conversion post reload to avoid producing of 128bit spills
4179 that might lead to ICE on 32bit target. The sequence unlikely combine
4182 [(set (match_operand:SF 0 "register_operand" "")
4184 (match_operand:DF 1 "nonimmediate_operand" "")))]
4185 "TARGET_USE_VECTOR_FP_CONVERTS
4186 && optimize_insn_for_speed_p ()
4187 && reload_completed && SSE_REG_P (operands[0])"
4190 (float_truncate:V2SF
4194 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4195 operands[3] = CONST0_RTX (V2SFmode);
4196 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4197 /* Use movsd for loading from memory, unpcklpd for registers.
4198 Try to avoid move when unpacking can be done in source, or SSE3
4199 movddup is available. */
4200 if (REG_P (operands[1]))
4203 && true_regnum (operands[0]) != true_regnum (operands[1])
4204 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4205 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4207 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4208 emit_move_insn (tmp, operands[1]);
4211 else if (!TARGET_SSE3)
4212 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4213 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4216 emit_insn (gen_sse2_loadlpd (operands[4],
4217 CONST0_RTX (V2DFmode), operands[1]));
4220 (define_expand "truncdfsf2_with_temp"
4221 [(parallel [(set (match_operand:SF 0 "" "")
4222 (float_truncate:SF (match_operand:DF 1 "" "")))
4223 (clobber (match_operand:SF 2 "" ""))])])
4225 (define_insn "*truncdfsf_fast_mixed"
4226 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4228 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4229 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4231 switch (which_alternative)
4234 return output_387_reg_move (insn, operands);
4236 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4241 [(set_attr "type" "fmov,ssecvt")
4242 (set_attr "prefix" "orig,maybe_vex")
4243 (set_attr "mode" "SF")])
4245 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4246 ;; because nothing we do here is unsafe.
4247 (define_insn "*truncdfsf_fast_sse"
4248 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4250 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4251 "TARGET_SSE2 && TARGET_SSE_MATH"
4252 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4253 [(set_attr "type" "ssecvt")
4254 (set_attr "prefix" "maybe_vex")
4255 (set_attr "mode" "SF")])
4257 (define_insn "*truncdfsf_fast_i387"
4258 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4260 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4261 "TARGET_80387 && flag_unsafe_math_optimizations"
4262 "* return output_387_reg_move (insn, operands);"
4263 [(set_attr "type" "fmov")
4264 (set_attr "mode" "SF")])
4266 (define_insn "*truncdfsf_mixed"
4267 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4269 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4270 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4271 "TARGET_MIX_SSE_I387"
4273 switch (which_alternative)
4276 return output_387_reg_move (insn, operands);
4278 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4284 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4285 (set_attr "unit" "*,*,i387,i387,i387")
4286 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4287 (set_attr "mode" "SF")])
4289 (define_insn "*truncdfsf_i387"
4290 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4292 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4293 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4296 switch (which_alternative)
4299 return output_387_reg_move (insn, operands);
4305 [(set_attr "type" "fmov,multi,multi,multi")
4306 (set_attr "unit" "*,i387,i387,i387")
4307 (set_attr "mode" "SF")])
4309 (define_insn "*truncdfsf2_i387_1"
4310 [(set (match_operand:SF 0 "memory_operand" "=m")
4312 (match_operand:DF 1 "register_operand" "f")))]
4314 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4315 && !TARGET_MIX_SSE_I387"
4316 "* return output_387_reg_move (insn, operands);"
4317 [(set_attr "type" "fmov")
4318 (set_attr "mode" "SF")])
4321 [(set (match_operand:SF 0 "register_operand" "")
4323 (match_operand:DF 1 "fp_register_operand" "")))
4324 (clobber (match_operand 2 "" ""))]
4326 [(set (match_dup 2) (match_dup 1))
4327 (set (match_dup 0) (match_dup 2))]
4328 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4330 ;; Conversion from XFmode to {SF,DF}mode
4332 (define_expand "truncxf<mode>2"
4333 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4334 (float_truncate:MODEF
4335 (match_operand:XF 1 "register_operand" "")))
4336 (clobber (match_dup 2))])]
4339 if (flag_unsafe_math_optimizations)
4341 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4342 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4343 if (reg != operands[0])
4344 emit_move_insn (operands[0], reg);
4349 enum ix86_stack_slot slot = (virtuals_instantiated
4352 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4356 (define_insn "*truncxfsf2_mixed"
4357 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4359 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4360 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4363 gcc_assert (!which_alternative);
4364 return output_387_reg_move (insn, operands);
4366 [(set_attr "type" "fmov,multi,multi,multi")
4367 (set_attr "unit" "*,i387,i387,i387")
4368 (set_attr "mode" "SF")])
4370 (define_insn "*truncxfdf2_mixed"
4371 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4373 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4374 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4377 gcc_assert (!which_alternative);
4378 return output_387_reg_move (insn, operands);
4380 [(set_attr "type" "fmov,multi,multi,multi")
4381 (set_attr "unit" "*,i387,i387,i387")
4382 (set_attr "mode" "DF")])
4384 (define_insn "truncxf<mode>2_i387_noop"
4385 [(set (match_operand:MODEF 0 "register_operand" "=f")
4386 (float_truncate:MODEF
4387 (match_operand:XF 1 "register_operand" "f")))]
4388 "TARGET_80387 && flag_unsafe_math_optimizations"
4389 "* return output_387_reg_move (insn, operands);"
4390 [(set_attr "type" "fmov")
4391 (set_attr "mode" "<MODE>")])
4393 (define_insn "*truncxf<mode>2_i387"
4394 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4395 (float_truncate:MODEF
4396 (match_operand:XF 1 "register_operand" "f")))]
4398 "* return output_387_reg_move (insn, operands);"
4399 [(set_attr "type" "fmov")
4400 (set_attr "mode" "<MODE>")])
4403 [(set (match_operand:MODEF 0 "register_operand" "")
4404 (float_truncate:MODEF
4405 (match_operand:XF 1 "register_operand" "")))
4406 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4407 "TARGET_80387 && reload_completed"
4408 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4409 (set (match_dup 0) (match_dup 2))])
4412 [(set (match_operand:MODEF 0 "memory_operand" "")
4413 (float_truncate:MODEF
4414 (match_operand:XF 1 "register_operand" "")))
4415 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4417 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4419 ;; Signed conversion to DImode.
4421 (define_expand "fix_truncxfdi2"
4422 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4423 (fix:DI (match_operand:XF 1 "register_operand" "")))
4424 (clobber (reg:CC FLAGS_REG))])]
4429 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4434 (define_expand "fix_trunc<mode>di2"
4435 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4436 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4437 (clobber (reg:CC FLAGS_REG))])]
4438 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4441 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4443 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4446 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4448 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4449 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4450 if (out != operands[0])
4451 emit_move_insn (operands[0], out);
4456 ;; Signed conversion to SImode.
4458 (define_expand "fix_truncxfsi2"
4459 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4460 (fix:SI (match_operand:XF 1 "register_operand" "")))
4461 (clobber (reg:CC FLAGS_REG))])]
4466 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4471 (define_expand "fix_trunc<mode>si2"
4472 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4473 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4474 (clobber (reg:CC FLAGS_REG))])]
4475 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4478 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4480 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4483 if (SSE_FLOAT_MODE_P (<MODE>mode))
4485 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4486 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4487 if (out != operands[0])
4488 emit_move_insn (operands[0], out);
4493 ;; Signed conversion to HImode.
4495 (define_expand "fix_trunc<mode>hi2"
4496 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4497 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4498 (clobber (reg:CC FLAGS_REG))])]
4500 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4504 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4509 ;; Unsigned conversion to SImode.
4511 (define_expand "fixuns_trunc<mode>si2"
4513 [(set (match_operand:SI 0 "register_operand" "")
4515 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4517 (clobber (match_scratch:<ssevecmode> 3 ""))
4518 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4519 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4521 enum machine_mode mode = <MODE>mode;
4522 enum machine_mode vecmode = <ssevecmode>mode;
4523 REAL_VALUE_TYPE TWO31r;
4526 if (optimize_insn_for_size_p ())
4529 real_ldexp (&TWO31r, &dconst1, 31);
4530 two31 = const_double_from_real_value (TWO31r, mode);
4531 two31 = ix86_build_const_vector (vecmode, true, two31);
4532 operands[2] = force_reg (vecmode, two31);
4535 (define_insn_and_split "*fixuns_trunc<mode>_1"
4536 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4538 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4539 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4540 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4541 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4542 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4543 && optimize_function_for_speed_p (cfun)"
4545 "&& reload_completed"
4548 ix86_split_convert_uns_si_sse (operands);
4552 ;; Unsigned conversion to HImode.
4553 ;; Without these patterns, we'll try the unsigned SI conversion which
4554 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4556 (define_expand "fixuns_trunc<mode>hi2"
4558 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4559 (set (match_operand:HI 0 "nonimmediate_operand" "")
4560 (subreg:HI (match_dup 2) 0))]
4561 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4562 "operands[2] = gen_reg_rtx (SImode);")
4564 ;; When SSE is available, it is always faster to use it!
4565 (define_insn "fix_trunc<mode>di_sse"
4566 [(set (match_operand:DI 0 "register_operand" "=r,r")
4567 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4568 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4569 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4570 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4571 [(set_attr "type" "sseicvt")
4572 (set_attr "prefix" "maybe_vex")
4573 (set_attr "prefix_rex" "1")
4574 (set_attr "mode" "<MODE>")
4575 (set_attr "athlon_decode" "double,vector")
4576 (set_attr "amdfam10_decode" "double,double")
4577 (set_attr "bdver1_decode" "double,double")])
4579 (define_insn "fix_trunc<mode>si_sse"
4580 [(set (match_operand:SI 0 "register_operand" "=r,r")
4581 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4582 "SSE_FLOAT_MODE_P (<MODE>mode)
4583 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4584 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4585 [(set_attr "type" "sseicvt")
4586 (set_attr "prefix" "maybe_vex")
4587 (set_attr "mode" "<MODE>")
4588 (set_attr "athlon_decode" "double,vector")
4589 (set_attr "amdfam10_decode" "double,double")
4590 (set_attr "bdver1_decode" "double,double")])
4592 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4594 [(set (match_operand:MODEF 0 "register_operand" "")
4595 (match_operand:MODEF 1 "memory_operand" ""))
4596 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4597 (fix:SSEMODEI24 (match_dup 0)))]
4598 "TARGET_SHORTEN_X87_SSE
4599 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4600 && peep2_reg_dead_p (2, operands[0])"
4601 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4603 ;; Avoid vector decoded forms of the instruction.
4605 [(match_scratch:DF 2 "Y2")
4606 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4607 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4608 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4609 [(set (match_dup 2) (match_dup 1))
4610 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4613 [(match_scratch:SF 2 "x")
4614 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4615 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4616 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4617 [(set (match_dup 2) (match_dup 1))
4618 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4620 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4621 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4622 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4623 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4625 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4626 && (TARGET_64BIT || <MODE>mode != DImode))
4628 && can_create_pseudo_p ()"
4633 if (memory_operand (operands[0], VOIDmode))
4634 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4637 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4638 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4644 [(set_attr "type" "fisttp")
4645 (set_attr "mode" "<MODE>")])
4647 (define_insn "fix_trunc<mode>_i387_fisttp"
4648 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4649 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4650 (clobber (match_scratch:XF 2 "=&1f"))]
4651 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4653 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4654 && (TARGET_64BIT || <MODE>mode != DImode))
4655 && TARGET_SSE_MATH)"
4656 "* return output_fix_trunc (insn, operands, 1);"
4657 [(set_attr "type" "fisttp")
4658 (set_attr "mode" "<MODE>")])
4660 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4661 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4662 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4663 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4664 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4665 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4667 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4668 && (TARGET_64BIT || <MODE>mode != DImode))
4669 && TARGET_SSE_MATH)"
4671 [(set_attr "type" "fisttp")
4672 (set_attr "mode" "<MODE>")])
4675 [(set (match_operand:X87MODEI 0 "register_operand" "")
4676 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4677 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4678 (clobber (match_scratch 3 ""))]
4680 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4681 (clobber (match_dup 3))])
4682 (set (match_dup 0) (match_dup 2))])
4685 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4686 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4687 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4688 (clobber (match_scratch 3 ""))]
4690 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4691 (clobber (match_dup 3))])])
4693 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4694 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4695 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4696 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4697 ;; function in i386.c.
4698 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4699 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4700 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4701 (clobber (reg:CC FLAGS_REG))]
4702 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4704 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4705 && (TARGET_64BIT || <MODE>mode != DImode))
4706 && can_create_pseudo_p ()"
4711 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4713 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4714 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4715 if (memory_operand (operands[0], VOIDmode))
4716 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4717 operands[2], operands[3]));
4720 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4721 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4722 operands[2], operands[3],
4727 [(set_attr "type" "fistp")
4728 (set_attr "i387_cw" "trunc")
4729 (set_attr "mode" "<MODE>")])
4731 (define_insn "fix_truncdi_i387"
4732 [(set (match_operand:DI 0 "memory_operand" "=m")
4733 (fix:DI (match_operand 1 "register_operand" "f")))
4734 (use (match_operand:HI 2 "memory_operand" "m"))
4735 (use (match_operand:HI 3 "memory_operand" "m"))
4736 (clobber (match_scratch:XF 4 "=&1f"))]
4737 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4739 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4740 "* return output_fix_trunc (insn, operands, 0);"
4741 [(set_attr "type" "fistp")
4742 (set_attr "i387_cw" "trunc")
4743 (set_attr "mode" "DI")])
4745 (define_insn "fix_truncdi_i387_with_temp"
4746 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4747 (fix:DI (match_operand 1 "register_operand" "f,f")))
4748 (use (match_operand:HI 2 "memory_operand" "m,m"))
4749 (use (match_operand:HI 3 "memory_operand" "m,m"))
4750 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4751 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4752 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4754 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4756 [(set_attr "type" "fistp")
4757 (set_attr "i387_cw" "trunc")
4758 (set_attr "mode" "DI")])
4761 [(set (match_operand:DI 0 "register_operand" "")
4762 (fix:DI (match_operand 1 "register_operand" "")))
4763 (use (match_operand:HI 2 "memory_operand" ""))
4764 (use (match_operand:HI 3 "memory_operand" ""))
4765 (clobber (match_operand:DI 4 "memory_operand" ""))
4766 (clobber (match_scratch 5 ""))]
4768 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4771 (clobber (match_dup 5))])
4772 (set (match_dup 0) (match_dup 4))])
4775 [(set (match_operand:DI 0 "memory_operand" "")
4776 (fix:DI (match_operand 1 "register_operand" "")))
4777 (use (match_operand:HI 2 "memory_operand" ""))
4778 (use (match_operand:HI 3 "memory_operand" ""))
4779 (clobber (match_operand:DI 4 "memory_operand" ""))
4780 (clobber (match_scratch 5 ""))]
4782 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4785 (clobber (match_dup 5))])])
4787 (define_insn "fix_trunc<mode>_i387"
4788 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4789 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4790 (use (match_operand:HI 2 "memory_operand" "m"))
4791 (use (match_operand:HI 3 "memory_operand" "m"))]
4792 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4794 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4795 "* return output_fix_trunc (insn, operands, 0);"
4796 [(set_attr "type" "fistp")
4797 (set_attr "i387_cw" "trunc")
4798 (set_attr "mode" "<MODE>")])
4800 (define_insn "fix_trunc<mode>_i387_with_temp"
4801 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4802 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4803 (use (match_operand:HI 2 "memory_operand" "m,m"))
4804 (use (match_operand:HI 3 "memory_operand" "m,m"))
4805 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4806 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4808 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4810 [(set_attr "type" "fistp")
4811 (set_attr "i387_cw" "trunc")
4812 (set_attr "mode" "<MODE>")])
4815 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4816 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4817 (use (match_operand:HI 2 "memory_operand" ""))
4818 (use (match_operand:HI 3 "memory_operand" ""))
4819 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4821 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4823 (use (match_dup 3))])
4824 (set (match_dup 0) (match_dup 4))])
4827 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4828 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4829 (use (match_operand:HI 2 "memory_operand" ""))
4830 (use (match_operand:HI 3 "memory_operand" ""))
4831 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4833 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4835 (use (match_dup 3))])])
4837 (define_insn "x86_fnstcw_1"
4838 [(set (match_operand:HI 0 "memory_operand" "=m")
4839 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4842 [(set (attr "length")
4843 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4844 (set_attr "mode" "HI")
4845 (set_attr "unit" "i387")
4846 (set_attr "bdver1_decode" "vector")])
4848 (define_insn "x86_fldcw_1"
4849 [(set (reg:HI FPCR_REG)
4850 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4853 [(set (attr "length")
4854 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4855 (set_attr "mode" "HI")
4856 (set_attr "unit" "i387")
4857 (set_attr "athlon_decode" "vector")
4858 (set_attr "amdfam10_decode" "vector")
4859 (set_attr "bdver1_decode" "vector")])
4861 ;; Conversion between fixed point and floating point.
4863 ;; Even though we only accept memory inputs, the backend _really_
4864 ;; wants to be able to do this between registers.
4866 (define_expand "floathi<mode>2"
4867 [(set (match_operand:X87MODEF 0 "register_operand" "")
4868 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4871 || TARGET_MIX_SSE_I387)")
4873 ;; Pre-reload splitter to add memory clobber to the pattern.
4874 (define_insn_and_split "*floathi<mode>2_1"
4875 [(set (match_operand:X87MODEF 0 "register_operand" "")
4876 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4878 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4879 || TARGET_MIX_SSE_I387)
4880 && can_create_pseudo_p ()"
4883 [(parallel [(set (match_dup 0)
4884 (float:X87MODEF (match_dup 1)))
4885 (clobber (match_dup 2))])]
4886 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4888 (define_insn "*floathi<mode>2_i387_with_temp"
4889 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4890 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4891 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4894 || TARGET_MIX_SSE_I387)"
4896 [(set_attr "type" "fmov,multi")
4897 (set_attr "mode" "<MODE>")
4898 (set_attr "unit" "*,i387")
4899 (set_attr "fp_int_src" "true")])
4901 (define_insn "*floathi<mode>2_i387"
4902 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4903 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4906 || TARGET_MIX_SSE_I387)"
4908 [(set_attr "type" "fmov")
4909 (set_attr "mode" "<MODE>")
4910 (set_attr "fp_int_src" "true")])
4913 [(set (match_operand:X87MODEF 0 "register_operand" "")
4914 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4915 (clobber (match_operand:HI 2 "memory_operand" ""))]
4917 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4918 || TARGET_MIX_SSE_I387)
4919 && reload_completed"
4920 [(set (match_dup 2) (match_dup 1))
4921 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4924 [(set (match_operand:X87MODEF 0 "register_operand" "")
4925 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4926 (clobber (match_operand:HI 2 "memory_operand" ""))]
4928 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4929 || TARGET_MIX_SSE_I387)
4930 && reload_completed"
4931 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4933 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4934 [(set (match_operand:X87MODEF 0 "register_operand" "")
4936 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4938 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4939 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4941 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4942 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4943 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4945 rtx reg = gen_reg_rtx (XFmode);
4948 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4950 if (<X87MODEF:MODE>mode == SFmode)
4951 insn = gen_truncxfsf2 (operands[0], reg);
4952 else if (<X87MODEF:MODE>mode == DFmode)
4953 insn = gen_truncxfdf2 (operands[0], reg);
4962 ;; Pre-reload splitter to add memory clobber to the pattern.
4963 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4964 [(set (match_operand:X87MODEF 0 "register_operand" "")
4965 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4967 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4968 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4969 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4970 || TARGET_MIX_SSE_I387))
4971 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4972 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4973 && ((<SSEMODEI24:MODE>mode == SImode
4974 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4975 && optimize_function_for_speed_p (cfun)
4976 && flag_trapping_math)
4977 || !(TARGET_INTER_UNIT_CONVERSIONS
4978 || optimize_function_for_size_p (cfun)))))
4979 && can_create_pseudo_p ()"
4982 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4983 (clobber (match_dup 2))])]
4985 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4987 /* Avoid store forwarding (partial memory) stall penalty
4988 by passing DImode value through XMM registers. */
4989 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4990 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4991 && optimize_function_for_speed_p (cfun))
4993 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5000 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5001 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5003 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5004 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5005 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5006 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5008 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5009 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5010 (set_attr "unit" "*,i387,*,*,*")
5011 (set_attr "athlon_decode" "*,*,double,direct,double")
5012 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5013 (set_attr "bdver1_decode" "*,*,double,direct,double")
5014 (set_attr "fp_int_src" "true")])
5016 (define_insn "*floatsi<mode>2_vector_mixed"
5017 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5018 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5019 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5020 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5024 [(set_attr "type" "fmov,sseicvt")
5025 (set_attr "mode" "<MODE>,<ssevecmode>")
5026 (set_attr "unit" "i387,*")
5027 (set_attr "athlon_decode" "*,direct")
5028 (set_attr "amdfam10_decode" "*,double")
5029 (set_attr "bdver1_decode" "*,direct")
5030 (set_attr "fp_int_src" "true")])
5032 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5033 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5035 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5036 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5037 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5038 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5040 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5041 (set_attr "mode" "<MODEF:MODE>")
5042 (set_attr "unit" "*,i387,*,*")
5043 (set_attr "athlon_decode" "*,*,double,direct")
5044 (set_attr "amdfam10_decode" "*,*,vector,double")
5045 (set_attr "bdver1_decode" "*,*,double,direct")
5046 (set_attr "fp_int_src" "true")])
5049 [(set (match_operand:MODEF 0 "register_operand" "")
5050 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5051 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5052 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5053 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5054 && TARGET_INTER_UNIT_CONVERSIONS
5056 && (SSE_REG_P (operands[0])
5057 || (GET_CODE (operands[0]) == SUBREG
5058 && SSE_REG_P (operands[0])))"
5059 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5062 [(set (match_operand:MODEF 0 "register_operand" "")
5063 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5064 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5065 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5066 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5067 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5069 && (SSE_REG_P (operands[0])
5070 || (GET_CODE (operands[0]) == SUBREG
5071 && SSE_REG_P (operands[0])))"
5072 [(set (match_dup 2) (match_dup 1))
5073 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5075 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5076 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5078 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5079 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5080 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5081 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5084 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5085 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5086 [(set_attr "type" "fmov,sseicvt,sseicvt")
5087 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5088 (set_attr "mode" "<MODEF:MODE>")
5089 (set (attr "prefix_rex")
5091 (and (eq_attr "prefix" "maybe_vex")
5092 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5094 (const_string "*")))
5095 (set_attr "unit" "i387,*,*")
5096 (set_attr "athlon_decode" "*,double,direct")
5097 (set_attr "amdfam10_decode" "*,vector,double")
5098 (set_attr "bdver1_decode" "*,double,direct")
5099 (set_attr "fp_int_src" "true")])
5101 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5102 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5104 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5105 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5106 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5107 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5110 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5111 [(set_attr "type" "fmov,sseicvt")
5112 (set_attr "prefix" "orig,maybe_vex")
5113 (set_attr "mode" "<MODEF:MODE>")
5114 (set (attr "prefix_rex")
5116 (and (eq_attr "prefix" "maybe_vex")
5117 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5119 (const_string "*")))
5120 (set_attr "athlon_decode" "*,direct")
5121 (set_attr "amdfam10_decode" "*,double")
5122 (set_attr "bdver1_decode" "*,direct")
5123 (set_attr "fp_int_src" "true")])
5125 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5126 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5128 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5129 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5130 "TARGET_SSE2 && TARGET_SSE_MATH
5131 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5133 [(set_attr "type" "sseicvt")
5134 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5135 (set_attr "athlon_decode" "double,direct,double")
5136 (set_attr "amdfam10_decode" "vector,double,double")
5137 (set_attr "bdver1_decode" "double,direct,double")
5138 (set_attr "fp_int_src" "true")])
5140 (define_insn "*floatsi<mode>2_vector_sse"
5141 [(set (match_operand:MODEF 0 "register_operand" "=x")
5142 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5143 "TARGET_SSE2 && TARGET_SSE_MATH
5144 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5146 [(set_attr "type" "sseicvt")
5147 (set_attr "mode" "<MODE>")
5148 (set_attr "athlon_decode" "direct")
5149 (set_attr "amdfam10_decode" "double")
5150 (set_attr "bdver1_decode" "direct")
5151 (set_attr "fp_int_src" "true")])
5154 [(set (match_operand:MODEF 0 "register_operand" "")
5155 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5156 (clobber (match_operand:SI 2 "memory_operand" ""))]
5157 "TARGET_SSE2 && TARGET_SSE_MATH
5158 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5160 && (SSE_REG_P (operands[0])
5161 || (GET_CODE (operands[0]) == SUBREG
5162 && SSE_REG_P (operands[0])))"
5165 rtx op1 = operands[1];
5167 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5169 if (GET_CODE (op1) == SUBREG)
5170 op1 = SUBREG_REG (op1);
5172 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5174 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5175 emit_insn (gen_sse2_loadld (operands[4],
5176 CONST0_RTX (V4SImode), operands[1]));
5178 /* We can ignore possible trapping value in the
5179 high part of SSE register for non-trapping math. */
5180 else if (SSE_REG_P (op1) && !flag_trapping_math)
5181 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5184 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5185 emit_move_insn (operands[2], operands[1]);
5186 emit_insn (gen_sse2_loadld (operands[4],
5187 CONST0_RTX (V4SImode), operands[2]));
5190 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5195 [(set (match_operand:MODEF 0 "register_operand" "")
5196 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5197 (clobber (match_operand:SI 2 "memory_operand" ""))]
5198 "TARGET_SSE2 && TARGET_SSE_MATH
5199 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5201 && (SSE_REG_P (operands[0])
5202 || (GET_CODE (operands[0]) == SUBREG
5203 && SSE_REG_P (operands[0])))"
5206 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5208 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5210 emit_insn (gen_sse2_loadld (operands[4],
5211 CONST0_RTX (V4SImode), operands[1]));
5213 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5218 [(set (match_operand:MODEF 0 "register_operand" "")
5219 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5220 "TARGET_SSE2 && TARGET_SSE_MATH
5221 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5223 && (SSE_REG_P (operands[0])
5224 || (GET_CODE (operands[0]) == SUBREG
5225 && SSE_REG_P (operands[0])))"
5228 rtx op1 = operands[1];
5230 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5232 if (GET_CODE (op1) == SUBREG)
5233 op1 = SUBREG_REG (op1);
5235 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5237 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5238 emit_insn (gen_sse2_loadld (operands[4],
5239 CONST0_RTX (V4SImode), operands[1]));
5241 /* We can ignore possible trapping value in the
5242 high part of SSE register for non-trapping math. */
5243 else if (SSE_REG_P (op1) && !flag_trapping_math)
5244 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5248 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5253 [(set (match_operand:MODEF 0 "register_operand" "")
5254 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5255 "TARGET_SSE2 && TARGET_SSE_MATH
5256 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5258 && (SSE_REG_P (operands[0])
5259 || (GET_CODE (operands[0]) == SUBREG
5260 && SSE_REG_P (operands[0])))"
5263 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5265 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5267 emit_insn (gen_sse2_loadld (operands[4],
5268 CONST0_RTX (V4SImode), operands[1]));
5270 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5274 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5275 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5277 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5278 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5279 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5280 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5282 [(set_attr "type" "sseicvt")
5283 (set_attr "mode" "<MODEF:MODE>")
5284 (set_attr "athlon_decode" "double,direct")
5285 (set_attr "amdfam10_decode" "vector,double")
5286 (set_attr "bdver1_decode" "double,direct")
5287 (set_attr "fp_int_src" "true")])
5289 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5290 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5292 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5293 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5294 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5295 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5296 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5297 [(set_attr "type" "sseicvt")
5298 (set_attr "prefix" "maybe_vex")
5299 (set_attr "mode" "<MODEF:MODE>")
5300 (set (attr "prefix_rex")
5302 (and (eq_attr "prefix" "maybe_vex")
5303 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5305 (const_string "*")))
5306 (set_attr "athlon_decode" "double,direct")
5307 (set_attr "amdfam10_decode" "vector,double")
5308 (set_attr "bdver1_decode" "double,direct")
5309 (set_attr "fp_int_src" "true")])
5312 [(set (match_operand:MODEF 0 "register_operand" "")
5313 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5314 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5315 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5316 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5317 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5319 && (SSE_REG_P (operands[0])
5320 || (GET_CODE (operands[0]) == SUBREG
5321 && SSE_REG_P (operands[0])))"
5322 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5324 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5325 [(set (match_operand:MODEF 0 "register_operand" "=x")
5327 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5328 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5329 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5330 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5331 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5332 [(set_attr "type" "sseicvt")
5333 (set_attr "prefix" "maybe_vex")
5334 (set_attr "mode" "<MODEF:MODE>")
5335 (set (attr "prefix_rex")
5337 (and (eq_attr "prefix" "maybe_vex")
5338 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5340 (const_string "*")))
5341 (set_attr "athlon_decode" "direct")
5342 (set_attr "amdfam10_decode" "double")
5343 (set_attr "bdver1_decode" "direct")
5344 (set_attr "fp_int_src" "true")])
5347 [(set (match_operand:MODEF 0 "register_operand" "")
5348 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5349 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5350 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5351 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5352 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5354 && (SSE_REG_P (operands[0])
5355 || (GET_CODE (operands[0]) == SUBREG
5356 && SSE_REG_P (operands[0])))"
5357 [(set (match_dup 2) (match_dup 1))
5358 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5361 [(set (match_operand:MODEF 0 "register_operand" "")
5362 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5363 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5364 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5365 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5367 && (SSE_REG_P (operands[0])
5368 || (GET_CODE (operands[0]) == SUBREG
5369 && SSE_REG_P (operands[0])))"
5370 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5372 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5373 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5375 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5376 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5378 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5382 [(set_attr "type" "fmov,multi")
5383 (set_attr "mode" "<X87MODEF:MODE>")
5384 (set_attr "unit" "*,i387")
5385 (set_attr "fp_int_src" "true")])
5387 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5388 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5390 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5392 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5394 [(set_attr "type" "fmov")
5395 (set_attr "mode" "<X87MODEF:MODE>")
5396 (set_attr "fp_int_src" "true")])
5399 [(set (match_operand:X87MODEF 0 "register_operand" "")
5400 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5401 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5403 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5405 && FP_REG_P (operands[0])"
5406 [(set (match_dup 2) (match_dup 1))
5407 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5410 [(set (match_operand:X87MODEF 0 "register_operand" "")
5411 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5412 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5414 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5416 && FP_REG_P (operands[0])"
5417 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5419 ;; Avoid store forwarding (partial memory) stall penalty
5420 ;; by passing DImode value through XMM registers. */
5422 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5423 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5425 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5426 (clobber (match_scratch:V4SI 3 "=X,x"))
5427 (clobber (match_scratch:V4SI 4 "=X,x"))
5428 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5429 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5430 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5431 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5433 [(set_attr "type" "multi")
5434 (set_attr "mode" "<X87MODEF:MODE>")
5435 (set_attr "unit" "i387")
5436 (set_attr "fp_int_src" "true")])
5439 [(set (match_operand:X87MODEF 0 "register_operand" "")
5440 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5441 (clobber (match_scratch:V4SI 3 ""))
5442 (clobber (match_scratch:V4SI 4 ""))
5443 (clobber (match_operand:DI 2 "memory_operand" ""))]
5444 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5445 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5446 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5448 && FP_REG_P (operands[0])"
5449 [(set (match_dup 2) (match_dup 3))
5450 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5452 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5453 Assemble the 64-bit DImode value in an xmm register. */
5454 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5455 gen_rtx_SUBREG (SImode, operands[1], 0)));
5456 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5457 gen_rtx_SUBREG (SImode, operands[1], 4)));
5458 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5461 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5465 [(set (match_operand:X87MODEF 0 "register_operand" "")
5466 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5467 (clobber (match_scratch:V4SI 3 ""))
5468 (clobber (match_scratch:V4SI 4 ""))
5469 (clobber (match_operand:DI 2 "memory_operand" ""))]
5470 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5471 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5472 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5474 && FP_REG_P (operands[0])"
5475 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5477 ;; Avoid store forwarding (partial memory) stall penalty by extending
5478 ;; SImode value to DImode through XMM register instead of pushing two
5479 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5480 ;; targets benefit from this optimization. Also note that fild
5481 ;; loads from memory only.
5483 (define_insn "*floatunssi<mode>2_1"
5484 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5485 (unsigned_float:X87MODEF
5486 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5487 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5488 (clobber (match_scratch:SI 3 "=X,x"))]
5490 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5493 [(set_attr "type" "multi")
5494 (set_attr "mode" "<MODE>")])
5497 [(set (match_operand:X87MODEF 0 "register_operand" "")
5498 (unsigned_float:X87MODEF
5499 (match_operand:SI 1 "register_operand" "")))
5500 (clobber (match_operand:DI 2 "memory_operand" ""))
5501 (clobber (match_scratch:SI 3 ""))]
5503 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5505 && reload_completed"
5506 [(set (match_dup 2) (match_dup 1))
5508 (float:X87MODEF (match_dup 2)))]
5509 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5512 [(set (match_operand:X87MODEF 0 "register_operand" "")
5513 (unsigned_float:X87MODEF
5514 (match_operand:SI 1 "memory_operand" "")))
5515 (clobber (match_operand:DI 2 "memory_operand" ""))
5516 (clobber (match_scratch:SI 3 ""))]
5518 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5520 && reload_completed"
5521 [(set (match_dup 2) (match_dup 3))
5523 (float:X87MODEF (match_dup 2)))]
5525 emit_move_insn (operands[3], operands[1]);
5526 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5529 (define_expand "floatunssi<mode>2"
5531 [(set (match_operand:X87MODEF 0 "register_operand" "")
5532 (unsigned_float:X87MODEF
5533 (match_operand:SI 1 "nonimmediate_operand" "")))
5534 (clobber (match_dup 2))
5535 (clobber (match_scratch:SI 3 ""))])]
5537 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5539 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5541 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5543 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5548 enum ix86_stack_slot slot = (virtuals_instantiated
5551 operands[2] = assign_386_stack_local (DImode, slot);
5555 (define_expand "floatunsdisf2"
5556 [(use (match_operand:SF 0 "register_operand" ""))
5557 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5558 "TARGET_64BIT && TARGET_SSE_MATH"
5559 "x86_emit_floatuns (operands); DONE;")
5561 (define_expand "floatunsdidf2"
5562 [(use (match_operand:DF 0 "register_operand" ""))
5563 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5564 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5565 && TARGET_SSE2 && TARGET_SSE_MATH"
5568 x86_emit_floatuns (operands);
5570 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5576 (define_expand "add<mode>3"
5577 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5578 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5579 (match_operand:SDWIM 2 "<general_operand>" "")))]
5581 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5583 (define_insn_and_split "*add<dwi>3_doubleword"
5584 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5586 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5587 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5588 (clobber (reg:CC FLAGS_REG))]
5589 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5592 [(parallel [(set (reg:CC FLAGS_REG)
5593 (unspec:CC [(match_dup 1) (match_dup 2)]
5596 (plus:DWIH (match_dup 1) (match_dup 2)))])
5597 (parallel [(set (match_dup 3)
5601 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5603 (clobber (reg:CC FLAGS_REG))])]
5604 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5606 (define_insn "*add<mode>3_cc"
5607 [(set (reg:CC FLAGS_REG)
5609 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5610 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5612 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5613 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5614 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5615 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5616 [(set_attr "type" "alu")
5617 (set_attr "mode" "<MODE>")])
5619 (define_insn "addqi3_cc"
5620 [(set (reg:CC FLAGS_REG)
5622 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5623 (match_operand:QI 2 "general_operand" "qn,qm")]
5625 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5626 (plus:QI (match_dup 1) (match_dup 2)))]
5627 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5628 "add{b}\t{%2, %0|%0, %2}"
5629 [(set_attr "type" "alu")
5630 (set_attr "mode" "QI")])
5632 (define_insn "*lea_1"
5633 [(set (match_operand:P 0 "register_operand" "=r")
5634 (match_operand:P 1 "no_seg_address_operand" "p"))]
5636 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5637 [(set_attr "type" "lea")
5638 (set_attr "mode" "<MODE>")])
5640 (define_insn "*lea_2"
5641 [(set (match_operand:SI 0 "register_operand" "=r")
5642 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5644 "lea{l}\t{%a1, %0|%0, %a1}"
5645 [(set_attr "type" "lea")
5646 (set_attr "mode" "SI")])
5648 (define_insn "*lea_2_zext"
5649 [(set (match_operand:DI 0 "register_operand" "=r")
5651 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5653 "lea{l}\t{%a1, %k0|%k0, %a1}"
5654 [(set_attr "type" "lea")
5655 (set_attr "mode" "SI")])
5657 (define_insn "*add<mode>_1"
5658 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5660 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5661 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5662 (clobber (reg:CC FLAGS_REG))]
5663 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5665 switch (get_attr_type (insn))
5671 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5672 if (operands[2] == const1_rtx)
5673 return "inc{<imodesuffix>}\t%0";
5676 gcc_assert (operands[2] == constm1_rtx);
5677 return "dec{<imodesuffix>}\t%0";
5681 /* For most processors, ADD is faster than LEA. This alternative
5682 was added to use ADD as much as possible. */
5683 if (which_alternative == 2)
5686 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5689 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5690 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5691 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5693 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5697 (cond [(eq_attr "alternative" "3")
5698 (const_string "lea")
5699 (match_operand:SWI48 2 "incdec_operand" "")
5700 (const_string "incdec")
5702 (const_string "alu")))
5703 (set (attr "length_immediate")
5705 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5707 (const_string "*")))
5708 (set_attr "mode" "<MODE>")])
5710 ;; It may seem that nonimmediate operand is proper one for operand 1.
5711 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5712 ;; we take care in ix86_binary_operator_ok to not allow two memory
5713 ;; operands so proper swapping will be done in reload. This allow
5714 ;; patterns constructed from addsi_1 to match.
5716 (define_insn "*addsi_1_zext"
5717 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5719 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5720 (match_operand:SI 2 "general_operand" "g,0,li"))))
5721 (clobber (reg:CC FLAGS_REG))]
5722 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5724 switch (get_attr_type (insn))
5730 if (operands[2] == const1_rtx)
5731 return "inc{l}\t%k0";
5734 gcc_assert (operands[2] == constm1_rtx);
5735 return "dec{l}\t%k0";
5739 /* For most processors, ADD is faster than LEA. This alternative
5740 was added to use ADD as much as possible. */
5741 if (which_alternative == 1)
5744 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5747 if (x86_maybe_negate_const_int (&operands[2], SImode))
5748 return "sub{l}\t{%2, %k0|%k0, %2}";
5750 return "add{l}\t{%2, %k0|%k0, %2}";
5754 (cond [(eq_attr "alternative" "2")
5755 (const_string "lea")
5756 (match_operand:SI 2 "incdec_operand" "")
5757 (const_string "incdec")
5759 (const_string "alu")))
5760 (set (attr "length_immediate")
5762 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5764 (const_string "*")))
5765 (set_attr "mode" "SI")])
5767 (define_insn "*addhi_1"
5768 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5769 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5770 (match_operand:HI 2 "general_operand" "rn,rm")))
5771 (clobber (reg:CC FLAGS_REG))]
5772 "TARGET_PARTIAL_REG_STALL
5773 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5775 switch (get_attr_type (insn))
5778 if (operands[2] == const1_rtx)
5779 return "inc{w}\t%0";
5782 gcc_assert (operands[2] == constm1_rtx);
5783 return "dec{w}\t%0";
5787 if (x86_maybe_negate_const_int (&operands[2], HImode))
5788 return "sub{w}\t{%2, %0|%0, %2}";
5790 return "add{w}\t{%2, %0|%0, %2}";
5794 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5795 (const_string "incdec")
5796 (const_string "alu")))
5797 (set (attr "length_immediate")
5799 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5801 (const_string "*")))
5802 (set_attr "mode" "HI")])
5804 (define_insn "*addhi_1_lea"
5805 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5806 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5807 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5808 (clobber (reg:CC FLAGS_REG))]
5809 "!TARGET_PARTIAL_REG_STALL
5810 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5812 switch (get_attr_type (insn))
5818 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5819 if (operands[2] == const1_rtx)
5820 return "inc{w}\t%0";
5823 gcc_assert (operands[2] == constm1_rtx);
5824 return "dec{w}\t%0";
5828 /* For most processors, ADD is faster than LEA. This alternative
5829 was added to use ADD as much as possible. */
5830 if (which_alternative == 2)
5833 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5836 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5837 if (x86_maybe_negate_const_int (&operands[2], HImode))
5838 return "sub{w}\t{%2, %0|%0, %2}";
5840 return "add{w}\t{%2, %0|%0, %2}";
5844 (cond [(eq_attr "alternative" "3")
5845 (const_string "lea")
5846 (match_operand:HI 2 "incdec_operand" "")
5847 (const_string "incdec")
5849 (const_string "alu")))
5850 (set (attr "length_immediate")
5852 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5854 (const_string "*")))
5855 (set_attr "mode" "HI,HI,HI,SI")])
5857 ;; %%% Potential partial reg stall on alternative 2. What to do?
5858 (define_insn "*addqi_1"
5859 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5860 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5861 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5862 (clobber (reg:CC FLAGS_REG))]
5863 "TARGET_PARTIAL_REG_STALL
5864 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5866 int widen = (which_alternative == 2);
5867 switch (get_attr_type (insn))
5870 if (operands[2] == const1_rtx)
5871 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5874 gcc_assert (operands[2] == constm1_rtx);
5875 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5879 if (x86_maybe_negate_const_int (&operands[2], QImode))
5882 return "sub{l}\t{%2, %k0|%k0, %2}";
5884 return "sub{b}\t{%2, %0|%0, %2}";
5887 return "add{l}\t{%k2, %k0|%k0, %k2}";
5889 return "add{b}\t{%2, %0|%0, %2}";
5893 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5894 (const_string "incdec")
5895 (const_string "alu")))
5896 (set (attr "length_immediate")
5898 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5900 (const_string "*")))
5901 (set_attr "mode" "QI,QI,SI")])
5903 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5904 (define_insn "*addqi_1_lea"
5905 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5906 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5907 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5908 (clobber (reg:CC FLAGS_REG))]
5909 "!TARGET_PARTIAL_REG_STALL
5910 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5912 int widen = (which_alternative == 3 || which_alternative == 4);
5914 switch (get_attr_type (insn))
5920 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5921 if (operands[2] == const1_rtx)
5922 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5925 gcc_assert (operands[2] == constm1_rtx);
5926 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5930 /* For most processors, ADD is faster than LEA. These alternatives
5931 were added to use ADD as much as possible. */
5932 if (which_alternative == 2 || which_alternative == 4)
5935 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5938 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5939 if (x86_maybe_negate_const_int (&operands[2], QImode))
5942 return "sub{l}\t{%2, %k0|%k0, %2}";
5944 return "sub{b}\t{%2, %0|%0, %2}";
5947 return "add{l}\t{%k2, %k0|%k0, %k2}";
5949 return "add{b}\t{%2, %0|%0, %2}";
5953 (cond [(eq_attr "alternative" "5")
5954 (const_string "lea")
5955 (match_operand:QI 2 "incdec_operand" "")
5956 (const_string "incdec")
5958 (const_string "alu")))
5959 (set (attr "length_immediate")
5961 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5963 (const_string "*")))
5964 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5966 (define_insn "*addqi_1_slp"
5967 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5968 (plus:QI (match_dup 0)
5969 (match_operand:QI 1 "general_operand" "qn,qnm")))
5970 (clobber (reg:CC FLAGS_REG))]
5971 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5972 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5974 switch (get_attr_type (insn))
5977 if (operands[1] == const1_rtx)
5978 return "inc{b}\t%0";
5981 gcc_assert (operands[1] == constm1_rtx);
5982 return "dec{b}\t%0";
5986 if (x86_maybe_negate_const_int (&operands[1], QImode))
5987 return "sub{b}\t{%1, %0|%0, %1}";
5989 return "add{b}\t{%1, %0|%0, %1}";
5993 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5994 (const_string "incdec")
5995 (const_string "alu1")))
5996 (set (attr "memory")
5997 (if_then_else (match_operand 1 "memory_operand" "")
5998 (const_string "load")
5999 (const_string "none")))
6000 (set_attr "mode" "QI")])
6002 ;; Convert lea to the lea pattern to avoid flags dependency.
6004 [(set (match_operand 0 "register_operand" "")
6005 (plus (match_operand 1 "register_operand" "")
6006 (match_operand 2 "nonmemory_operand" "")))
6007 (clobber (reg:CC FLAGS_REG))]
6008 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6012 enum machine_mode mode = GET_MODE (operands[0]);
6014 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6015 may confuse gen_lowpart. */
6018 operands[1] = gen_lowpart (Pmode, operands[1]);
6019 operands[2] = gen_lowpart (Pmode, operands[2]);
6022 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6024 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6025 operands[0] = gen_lowpart (SImode, operands[0]);
6027 if (TARGET_64BIT && mode != Pmode)
6028 pat = gen_rtx_SUBREG (SImode, pat, 0);
6030 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6034 ;; Convert lea to the lea pattern to avoid flags dependency.
6035 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6036 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6038 [(set (match_operand:DI 0 "register_operand" "")
6039 (plus:DI (match_operand:DI 1 "register_operand" "")
6040 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6041 (clobber (reg:CC FLAGS_REG))]
6042 "TARGET_64BIT && reload_completed
6043 && true_regnum (operands[0]) != true_regnum (operands[1])"
6045 (plus:DI (match_dup 1) (match_dup 2)))])
6047 ;; Convert lea to the lea pattern to avoid flags dependency.
6049 [(set (match_operand:DI 0 "register_operand" "")
6051 (plus:SI (match_operand:SI 1 "register_operand" "")
6052 (match_operand:SI 2 "nonmemory_operand" ""))))
6053 (clobber (reg:CC FLAGS_REG))]
6054 "TARGET_64BIT && reload_completed
6055 && ix86_lea_for_add_ok (insn, operands)"
6057 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6059 operands[1] = gen_lowpart (DImode, operands[1]);
6060 operands[2] = gen_lowpart (DImode, operands[2]);
6063 (define_insn "*add<mode>_2"
6064 [(set (reg FLAGS_REG)
6067 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6068 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6070 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6071 (plus:SWI (match_dup 1) (match_dup 2)))]
6072 "ix86_match_ccmode (insn, CCGOCmode)
6073 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6075 switch (get_attr_type (insn))
6078 if (operands[2] == const1_rtx)
6079 return "inc{<imodesuffix>}\t%0";
6082 gcc_assert (operands[2] == constm1_rtx);
6083 return "dec{<imodesuffix>}\t%0";
6087 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6088 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6090 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6094 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6095 (const_string "incdec")
6096 (const_string "alu")))
6097 (set (attr "length_immediate")
6099 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6101 (const_string "*")))
6102 (set_attr "mode" "<MODE>")])
6104 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6105 (define_insn "*addsi_2_zext"
6106 [(set (reg FLAGS_REG)
6108 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6109 (match_operand:SI 2 "general_operand" "g"))
6111 (set (match_operand:DI 0 "register_operand" "=r")
6112 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6113 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6114 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6116 switch (get_attr_type (insn))
6119 if (operands[2] == const1_rtx)
6120 return "inc{l}\t%k0";
6123 gcc_assert (operands[2] == constm1_rtx);
6124 return "dec{l}\t%k0";
6128 if (x86_maybe_negate_const_int (&operands[2], SImode))
6129 return "sub{l}\t{%2, %k0|%k0, %2}";
6131 return "add{l}\t{%2, %k0|%k0, %2}";
6135 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6136 (const_string "incdec")
6137 (const_string "alu")))
6138 (set (attr "length_immediate")
6140 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6142 (const_string "*")))
6143 (set_attr "mode" "SI")])
6145 (define_insn "*add<mode>_3"
6146 [(set (reg FLAGS_REG)
6148 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6149 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6150 (clobber (match_scratch:SWI 0 "=<r>"))]
6151 "ix86_match_ccmode (insn, CCZmode)
6152 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6154 switch (get_attr_type (insn))
6157 if (operands[2] == const1_rtx)
6158 return "inc{<imodesuffix>}\t%0";
6161 gcc_assert (operands[2] == constm1_rtx);
6162 return "dec{<imodesuffix>}\t%0";
6166 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6167 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6169 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6173 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6174 (const_string "incdec")
6175 (const_string "alu")))
6176 (set (attr "length_immediate")
6178 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6180 (const_string "*")))
6181 (set_attr "mode" "<MODE>")])
6183 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6184 (define_insn "*addsi_3_zext"
6185 [(set (reg FLAGS_REG)
6187 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6188 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6189 (set (match_operand:DI 0 "register_operand" "=r")
6190 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6191 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6192 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6194 switch (get_attr_type (insn))
6197 if (operands[2] == const1_rtx)
6198 return "inc{l}\t%k0";
6201 gcc_assert (operands[2] == constm1_rtx);
6202 return "dec{l}\t%k0";
6206 if (x86_maybe_negate_const_int (&operands[2], SImode))
6207 return "sub{l}\t{%2, %k0|%k0, %2}";
6209 return "add{l}\t{%2, %k0|%k0, %2}";
6213 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6214 (const_string "incdec")
6215 (const_string "alu")))
6216 (set (attr "length_immediate")
6218 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6220 (const_string "*")))
6221 (set_attr "mode" "SI")])
6223 ; For comparisons against 1, -1 and 128, we may generate better code
6224 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6225 ; is matched then. We can't accept general immediate, because for
6226 ; case of overflows, the result is messed up.
6227 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6228 ; only for comparisons not depending on it.
6230 (define_insn "*adddi_4"
6231 [(set (reg FLAGS_REG)
6233 (match_operand:DI 1 "nonimmediate_operand" "0")
6234 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6235 (clobber (match_scratch:DI 0 "=rm"))]
6237 && ix86_match_ccmode (insn, CCGCmode)"
6239 switch (get_attr_type (insn))
6242 if (operands[2] == constm1_rtx)
6243 return "inc{q}\t%0";
6246 gcc_assert (operands[2] == const1_rtx);
6247 return "dec{q}\t%0";
6251 if (x86_maybe_negate_const_int (&operands[2], DImode))
6252 return "add{q}\t{%2, %0|%0, %2}";
6254 return "sub{q}\t{%2, %0|%0, %2}";
6258 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6259 (const_string "incdec")
6260 (const_string "alu")))
6261 (set (attr "length_immediate")
6263 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6265 (const_string "*")))
6266 (set_attr "mode" "DI")])
6268 ; For comparisons against 1, -1 and 128, we may generate better code
6269 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6270 ; is matched then. We can't accept general immediate, because for
6271 ; case of overflows, the result is messed up.
6272 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6273 ; only for comparisons not depending on it.
6275 (define_insn "*add<mode>_4"
6276 [(set (reg FLAGS_REG)
6278 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6279 (match_operand:SWI124 2 "const_int_operand" "n")))
6280 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6281 "ix86_match_ccmode (insn, CCGCmode)"
6283 switch (get_attr_type (insn))
6286 if (operands[2] == constm1_rtx)
6287 return "inc{<imodesuffix>}\t%0";
6290 gcc_assert (operands[2] == const1_rtx);
6291 return "dec{<imodesuffix>}\t%0";
6295 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6296 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6298 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6302 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6303 (const_string "incdec")
6304 (const_string "alu")))
6305 (set (attr "length_immediate")
6307 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6309 (const_string "*")))
6310 (set_attr "mode" "<MODE>")])
6312 (define_insn "*add<mode>_5"
6313 [(set (reg FLAGS_REG)
6316 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6317 (match_operand:SWI 2 "<general_operand>" "<g>"))
6319 (clobber (match_scratch:SWI 0 "=<r>"))]
6320 "ix86_match_ccmode (insn, CCGOCmode)
6321 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6323 switch (get_attr_type (insn))
6326 if (operands[2] == const1_rtx)
6327 return "inc{<imodesuffix>}\t%0";
6330 gcc_assert (operands[2] == constm1_rtx);
6331 return "dec{<imodesuffix>}\t%0";
6335 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6336 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6338 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6342 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6343 (const_string "incdec")
6344 (const_string "alu")))
6345 (set (attr "length_immediate")
6347 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6349 (const_string "*")))
6350 (set_attr "mode" "<MODE>")])
6352 (define_insn "*addqi_ext_1_rex64"
6353 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6358 (match_operand 1 "ext_register_operand" "0")
6361 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6362 (clobber (reg:CC FLAGS_REG))]
6365 switch (get_attr_type (insn))
6368 if (operands[2] == const1_rtx)
6369 return "inc{b}\t%h0";
6372 gcc_assert (operands[2] == constm1_rtx);
6373 return "dec{b}\t%h0";
6377 return "add{b}\t{%2, %h0|%h0, %2}";
6381 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6382 (const_string "incdec")
6383 (const_string "alu")))
6384 (set_attr "modrm" "1")
6385 (set_attr "mode" "QI")])
6387 (define_insn "addqi_ext_1"
6388 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6393 (match_operand 1 "ext_register_operand" "0")
6396 (match_operand:QI 2 "general_operand" "Qmn")))
6397 (clobber (reg:CC FLAGS_REG))]
6400 switch (get_attr_type (insn))
6403 if (operands[2] == const1_rtx)
6404 return "inc{b}\t%h0";
6407 gcc_assert (operands[2] == constm1_rtx);
6408 return "dec{b}\t%h0";
6412 return "add{b}\t{%2, %h0|%h0, %2}";
6416 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6417 (const_string "incdec")
6418 (const_string "alu")))
6419 (set_attr "modrm" "1")
6420 (set_attr "mode" "QI")])
6422 (define_insn "*addqi_ext_2"
6423 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6428 (match_operand 1 "ext_register_operand" "%0")
6432 (match_operand 2 "ext_register_operand" "Q")
6435 (clobber (reg:CC FLAGS_REG))]
6437 "add{b}\t{%h2, %h0|%h0, %h2}"
6438 [(set_attr "type" "alu")
6439 (set_attr "mode" "QI")])
6441 ;; The lea patterns for non-Pmodes needs to be matched by
6442 ;; several insns converted to real lea by splitters.
6444 (define_insn_and_split "*lea_general_1"
6445 [(set (match_operand 0 "register_operand" "=r")
6446 (plus (plus (match_operand 1 "index_register_operand" "l")
6447 (match_operand 2 "register_operand" "r"))
6448 (match_operand 3 "immediate_operand" "i")))]
6449 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6450 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6451 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6452 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6453 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6454 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6455 || GET_MODE (operands[3]) == VOIDmode)"
6457 "&& reload_completed"
6461 operands[0] = gen_lowpart (SImode, operands[0]);
6462 operands[1] = gen_lowpart (Pmode, operands[1]);
6463 operands[2] = gen_lowpart (Pmode, operands[2]);
6464 operands[3] = gen_lowpart (Pmode, operands[3]);
6465 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6467 if (Pmode != SImode)
6468 pat = gen_rtx_SUBREG (SImode, pat, 0);
6469 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6472 [(set_attr "type" "lea")
6473 (set_attr "mode" "SI")])
6475 (define_insn_and_split "*lea_general_1_zext"
6476 [(set (match_operand:DI 0 "register_operand" "=r")
6479 (match_operand:SI 1 "index_register_operand" "l")
6480 (match_operand:SI 2 "register_operand" "r"))
6481 (match_operand:SI 3 "immediate_operand" "i"))))]
6484 "&& reload_completed"
6486 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6488 (match_dup 3)) 0)))]
6490 operands[1] = gen_lowpart (Pmode, operands[1]);
6491 operands[2] = gen_lowpart (Pmode, operands[2]);
6492 operands[3] = gen_lowpart (Pmode, operands[3]);
6494 [(set_attr "type" "lea")
6495 (set_attr "mode" "SI")])
6497 (define_insn_and_split "*lea_general_2"
6498 [(set (match_operand 0 "register_operand" "=r")
6499 (plus (mult (match_operand 1 "index_register_operand" "l")
6500 (match_operand 2 "const248_operand" "i"))
6501 (match_operand 3 "nonmemory_operand" "ri")))]
6502 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6503 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6504 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6505 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6506 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6507 || GET_MODE (operands[3]) == VOIDmode)"
6509 "&& reload_completed"
6513 operands[0] = gen_lowpart (SImode, operands[0]);
6514 operands[1] = gen_lowpart (Pmode, operands[1]);
6515 operands[3] = gen_lowpart (Pmode, operands[3]);
6516 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6518 if (Pmode != SImode)
6519 pat = gen_rtx_SUBREG (SImode, pat, 0);
6520 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6523 [(set_attr "type" "lea")
6524 (set_attr "mode" "SI")])
6526 (define_insn_and_split "*lea_general_2_zext"
6527 [(set (match_operand:DI 0 "register_operand" "=r")
6530 (match_operand:SI 1 "index_register_operand" "l")
6531 (match_operand:SI 2 "const248_operand" "n"))
6532 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6535 "&& reload_completed"
6537 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6539 (match_dup 3)) 0)))]
6541 operands[1] = gen_lowpart (Pmode, operands[1]);
6542 operands[3] = gen_lowpart (Pmode, operands[3]);
6544 [(set_attr "type" "lea")
6545 (set_attr "mode" "SI")])
6547 (define_insn_and_split "*lea_general_3"
6548 [(set (match_operand 0 "register_operand" "=r")
6549 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6550 (match_operand 2 "const248_operand" "i"))
6551 (match_operand 3 "register_operand" "r"))
6552 (match_operand 4 "immediate_operand" "i")))]
6553 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6554 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6555 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6556 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6557 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6559 "&& reload_completed"
6563 operands[0] = gen_lowpart (SImode, operands[0]);
6564 operands[1] = gen_lowpart (Pmode, operands[1]);
6565 operands[3] = gen_lowpart (Pmode, operands[3]);
6566 operands[4] = gen_lowpart (Pmode, operands[4]);
6567 pat = gen_rtx_PLUS (Pmode,
6568 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6572 if (Pmode != SImode)
6573 pat = gen_rtx_SUBREG (SImode, pat, 0);
6574 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6577 [(set_attr "type" "lea")
6578 (set_attr "mode" "SI")])
6580 (define_insn_and_split "*lea_general_3_zext"
6581 [(set (match_operand:DI 0 "register_operand" "=r")
6585 (match_operand:SI 1 "index_register_operand" "l")
6586 (match_operand:SI 2 "const248_operand" "n"))
6587 (match_operand:SI 3 "register_operand" "r"))
6588 (match_operand:SI 4 "immediate_operand" "i"))))]
6591 "&& reload_completed"
6593 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6596 (match_dup 4)) 0)))]
6598 operands[1] = gen_lowpart (Pmode, operands[1]);
6599 operands[3] = gen_lowpart (Pmode, operands[3]);
6600 operands[4] = gen_lowpart (Pmode, operands[4]);
6602 [(set_attr "type" "lea")
6603 (set_attr "mode" "SI")])
6605 ;; Subtract instructions
6607 (define_expand "sub<mode>3"
6608 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6609 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6610 (match_operand:SDWIM 2 "<general_operand>" "")))]
6612 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6614 (define_insn_and_split "*sub<dwi>3_doubleword"
6615 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6617 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6618 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6619 (clobber (reg:CC FLAGS_REG))]
6620 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6623 [(parallel [(set (reg:CC FLAGS_REG)
6624 (compare:CC (match_dup 1) (match_dup 2)))
6626 (minus:DWIH (match_dup 1) (match_dup 2)))])
6627 (parallel [(set (match_dup 3)
6631 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6633 (clobber (reg:CC FLAGS_REG))])]
6634 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6636 (define_insn "*sub<mode>_1"
6637 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6639 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6640 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6641 (clobber (reg:CC FLAGS_REG))]
6642 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6643 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6644 [(set_attr "type" "alu")
6645 (set_attr "mode" "<MODE>")])
6647 (define_insn "*subsi_1_zext"
6648 [(set (match_operand:DI 0 "register_operand" "=r")
6650 (minus:SI (match_operand:SI 1 "register_operand" "0")
6651 (match_operand:SI 2 "general_operand" "g"))))
6652 (clobber (reg:CC FLAGS_REG))]
6653 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6654 "sub{l}\t{%2, %k0|%k0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "mode" "SI")])
6658 (define_insn "*subqi_1_slp"
6659 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6660 (minus:QI (match_dup 0)
6661 (match_operand:QI 1 "general_operand" "qn,qm")))
6662 (clobber (reg:CC FLAGS_REG))]
6663 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6664 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6665 "sub{b}\t{%1, %0|%0, %1}"
6666 [(set_attr "type" "alu1")
6667 (set_attr "mode" "QI")])
6669 (define_insn "*sub<mode>_2"
6670 [(set (reg FLAGS_REG)
6673 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6674 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6676 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6677 (minus:SWI (match_dup 1) (match_dup 2)))]
6678 "ix86_match_ccmode (insn, CCGOCmode)
6679 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6680 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6681 [(set_attr "type" "alu")
6682 (set_attr "mode" "<MODE>")])
6684 (define_insn "*subsi_2_zext"
6685 [(set (reg FLAGS_REG)
6687 (minus:SI (match_operand:SI 1 "register_operand" "0")
6688 (match_operand:SI 2 "general_operand" "g"))
6690 (set (match_operand:DI 0 "register_operand" "=r")
6692 (minus:SI (match_dup 1)
6694 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6695 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6696 "sub{l}\t{%2, %k0|%k0, %2}"
6697 [(set_attr "type" "alu")
6698 (set_attr "mode" "SI")])
6700 (define_insn "*sub<mode>_3"
6701 [(set (reg FLAGS_REG)
6702 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6703 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6704 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6705 (minus:SWI (match_dup 1) (match_dup 2)))]
6706 "ix86_match_ccmode (insn, CCmode)
6707 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6708 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6709 [(set_attr "type" "alu")
6710 (set_attr "mode" "<MODE>")])
6712 (define_insn "*subsi_3_zext"
6713 [(set (reg FLAGS_REG)
6714 (compare (match_operand:SI 1 "register_operand" "0")
6715 (match_operand:SI 2 "general_operand" "g")))
6716 (set (match_operand:DI 0 "register_operand" "=r")
6718 (minus:SI (match_dup 1)
6720 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6721 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6722 "sub{l}\t{%2, %1|%1, %2}"
6723 [(set_attr "type" "alu")
6724 (set_attr "mode" "SI")])
6726 ;; Add with carry and subtract with borrow
6728 (define_expand "<plusminus_insn><mode>3_carry"
6730 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6732 (match_operand:SWI 1 "nonimmediate_operand" "")
6733 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6734 [(match_operand 3 "flags_reg_operand" "")
6736 (match_operand:SWI 2 "<general_operand>" ""))))
6737 (clobber (reg:CC FLAGS_REG))])]
6738 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6740 (define_insn "*<plusminus_insn><mode>3_carry"
6741 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6743 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6745 (match_operator 3 "ix86_carry_flag_operator"
6746 [(reg FLAGS_REG) (const_int 0)])
6747 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6748 (clobber (reg:CC FLAGS_REG))]
6749 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6750 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6751 [(set_attr "type" "alu")
6752 (set_attr "use_carry" "1")
6753 (set_attr "pent_pair" "pu")
6754 (set_attr "mode" "<MODE>")])
6756 (define_insn "*addsi3_carry_zext"
6757 [(set (match_operand:DI 0 "register_operand" "=r")
6759 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6760 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6761 [(reg FLAGS_REG) (const_int 0)])
6762 (match_operand:SI 2 "general_operand" "g")))))
6763 (clobber (reg:CC FLAGS_REG))]
6764 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6765 "adc{l}\t{%2, %k0|%k0, %2}"
6766 [(set_attr "type" "alu")
6767 (set_attr "use_carry" "1")
6768 (set_attr "pent_pair" "pu")
6769 (set_attr "mode" "SI")])
6771 (define_insn "*subsi3_carry_zext"
6772 [(set (match_operand:DI 0 "register_operand" "=r")
6774 (minus:SI (match_operand:SI 1 "register_operand" "0")
6775 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6776 [(reg FLAGS_REG) (const_int 0)])
6777 (match_operand:SI 2 "general_operand" "g")))))
6778 (clobber (reg:CC FLAGS_REG))]
6779 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6780 "sbb{l}\t{%2, %k0|%k0, %2}"
6781 [(set_attr "type" "alu")
6782 (set_attr "pent_pair" "pu")
6783 (set_attr "mode" "SI")])
6785 ;; Overflow setting add and subtract instructions
6787 (define_insn "*add<mode>3_cconly_overflow"
6788 [(set (reg:CCC FLAGS_REG)
6791 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6792 (match_operand:SWI 2 "<general_operand>" "<g>"))
6794 (clobber (match_scratch:SWI 0 "=<r>"))]
6795 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6797 [(set_attr "type" "alu")
6798 (set_attr "mode" "<MODE>")])
6800 (define_insn "*sub<mode>3_cconly_overflow"
6801 [(set (reg:CCC FLAGS_REG)
6804 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6805 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6808 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6809 [(set_attr "type" "icmp")
6810 (set_attr "mode" "<MODE>")])
6812 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6813 [(set (reg:CCC FLAGS_REG)
6816 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6817 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6819 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6820 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6821 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6822 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6823 [(set_attr "type" "alu")
6824 (set_attr "mode" "<MODE>")])
6826 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6827 [(set (reg:CCC FLAGS_REG)
6830 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6831 (match_operand:SI 2 "general_operand" "g"))
6833 (set (match_operand:DI 0 "register_operand" "=r")
6834 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6835 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6836 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6837 [(set_attr "type" "alu")
6838 (set_attr "mode" "SI")])
6840 ;; The patterns that match these are at the end of this file.
6842 (define_expand "<plusminus_insn>xf3"
6843 [(set (match_operand:XF 0 "register_operand" "")
6845 (match_operand:XF 1 "register_operand" "")
6846 (match_operand:XF 2 "register_operand" "")))]
6849 (define_expand "<plusminus_insn><mode>3"
6850 [(set (match_operand:MODEF 0 "register_operand" "")
6852 (match_operand:MODEF 1 "register_operand" "")
6853 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6854 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6855 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6857 ;; Multiply instructions
6859 (define_expand "mul<mode>3"
6860 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6862 (match_operand:SWIM248 1 "register_operand" "")
6863 (match_operand:SWIM248 2 "<general_operand>" "")))
6864 (clobber (reg:CC FLAGS_REG))])])
6866 (define_expand "mulqi3"
6867 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6869 (match_operand:QI 1 "register_operand" "")
6870 (match_operand:QI 2 "nonimmediate_operand" "")))
6871 (clobber (reg:CC FLAGS_REG))])]
6872 "TARGET_QIMODE_MATH")
6875 ;; IMUL reg32/64, reg32/64, imm8 Direct
6876 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6877 ;; IMUL reg32/64, reg32/64, imm32 Direct
6878 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6879 ;; IMUL reg32/64, reg32/64 Direct
6880 ;; IMUL reg32/64, mem32/64 Direct
6882 ;; On BDVER1, all above IMULs use DirectPath
6884 (define_insn "*mul<mode>3_1"
6885 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6887 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6888 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6889 (clobber (reg:CC FLAGS_REG))]
6890 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6892 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6893 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6894 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6895 [(set_attr "type" "imul")
6896 (set_attr "prefix_0f" "0,0,1")
6897 (set (attr "athlon_decode")
6898 (cond [(eq_attr "cpu" "athlon")
6899 (const_string "vector")
6900 (eq_attr "alternative" "1")
6901 (const_string "vector")
6902 (and (eq_attr "alternative" "2")
6903 (match_operand 1 "memory_operand" ""))
6904 (const_string "vector")]
6905 (const_string "direct")))
6906 (set (attr "amdfam10_decode")
6907 (cond [(and (eq_attr "alternative" "0,1")
6908 (match_operand 1 "memory_operand" ""))
6909 (const_string "vector")]
6910 (const_string "direct")))
6911 (set_attr "bdver1_decode" "direct")
6912 (set_attr "mode" "<MODE>")])
6914 (define_insn "*mulsi3_1_zext"
6915 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6917 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6918 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6919 (clobber (reg:CC FLAGS_REG))]
6921 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6923 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6924 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6925 imul{l}\t{%2, %k0|%k0, %2}"
6926 [(set_attr "type" "imul")
6927 (set_attr "prefix_0f" "0,0,1")
6928 (set (attr "athlon_decode")
6929 (cond [(eq_attr "cpu" "athlon")
6930 (const_string "vector")
6931 (eq_attr "alternative" "1")
6932 (const_string "vector")
6933 (and (eq_attr "alternative" "2")
6934 (match_operand 1 "memory_operand" ""))
6935 (const_string "vector")]
6936 (const_string "direct")))
6937 (set (attr "amdfam10_decode")
6938 (cond [(and (eq_attr "alternative" "0,1")
6939 (match_operand 1 "memory_operand" ""))
6940 (const_string "vector")]
6941 (const_string "direct")))
6942 (set_attr "bdver1_decode" "direct")
6943 (set_attr "mode" "SI")])
6946 ;; IMUL reg16, reg16, imm8 VectorPath
6947 ;; IMUL reg16, mem16, imm8 VectorPath
6948 ;; IMUL reg16, reg16, imm16 VectorPath
6949 ;; IMUL reg16, mem16, imm16 VectorPath
6950 ;; IMUL reg16, reg16 Direct
6951 ;; IMUL reg16, mem16 Direct
6953 ;; On BDVER1, all HI MULs use DoublePath
6955 (define_insn "*mulhi3_1"
6956 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6957 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6958 (match_operand:HI 2 "general_operand" "K,n,mr")))
6959 (clobber (reg:CC FLAGS_REG))]
6961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6963 imul{w}\t{%2, %1, %0|%0, %1, %2}
6964 imul{w}\t{%2, %1, %0|%0, %1, %2}
6965 imul{w}\t{%2, %0|%0, %2}"
6966 [(set_attr "type" "imul")
6967 (set_attr "prefix_0f" "0,0,1")
6968 (set (attr "athlon_decode")
6969 (cond [(eq_attr "cpu" "athlon")
6970 (const_string "vector")
6971 (eq_attr "alternative" "1,2")
6972 (const_string "vector")]
6973 (const_string "direct")))
6974 (set (attr "amdfam10_decode")
6975 (cond [(eq_attr "alternative" "0,1")
6976 (const_string "vector")]
6977 (const_string "direct")))
6978 (set_attr "bdver1_decode" "double")
6979 (set_attr "mode" "HI")])
6981 ;;On AMDFAM10 and BDVER1
6985 (define_insn "*mulqi3_1"
6986 [(set (match_operand:QI 0 "register_operand" "=a")
6987 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6988 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6989 (clobber (reg:CC FLAGS_REG))]
6991 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6993 [(set_attr "type" "imul")
6994 (set_attr "length_immediate" "0")
6995 (set (attr "athlon_decode")
6996 (if_then_else (eq_attr "cpu" "athlon")
6997 (const_string "vector")
6998 (const_string "direct")))
6999 (set_attr "amdfam10_decode" "direct")
7000 (set_attr "bdver1_decode" "direct")
7001 (set_attr "mode" "QI")])
7003 (define_expand "<u>mul<mode><dwi>3"
7004 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7007 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7009 (match_operand:DWIH 2 "register_operand" ""))))
7010 (clobber (reg:CC FLAGS_REG))])])
7012 (define_expand "<u>mulqihi3"
7013 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7016 (match_operand:QI 1 "nonimmediate_operand" ""))
7018 (match_operand:QI 2 "register_operand" ""))))
7019 (clobber (reg:CC FLAGS_REG))])]
7020 "TARGET_QIMODE_MATH")
7022 (define_insn "*<u>mul<mode><dwi>3_1"
7023 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7026 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7028 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7029 (clobber (reg:CC FLAGS_REG))]
7030 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7031 "<sgnprefix>mul{<imodesuffix>}\t%2"
7032 [(set_attr "type" "imul")
7033 (set_attr "length_immediate" "0")
7034 (set (attr "athlon_decode")
7035 (if_then_else (eq_attr "cpu" "athlon")
7036 (const_string "vector")
7037 (const_string "double")))
7038 (set_attr "amdfam10_decode" "double")
7039 (set_attr "bdver1_decode" "direct")
7040 (set_attr "mode" "<MODE>")])
7042 (define_insn "*<u>mulqihi3_1"
7043 [(set (match_operand:HI 0 "register_operand" "=a")
7046 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7048 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7049 (clobber (reg:CC FLAGS_REG))]
7051 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7052 "<sgnprefix>mul{b}\t%2"
7053 [(set_attr "type" "imul")
7054 (set_attr "length_immediate" "0")
7055 (set (attr "athlon_decode")
7056 (if_then_else (eq_attr "cpu" "athlon")
7057 (const_string "vector")
7058 (const_string "direct")))
7059 (set_attr "amdfam10_decode" "direct")
7060 (set_attr "bdver1_decode" "direct")
7061 (set_attr "mode" "QI")])
7063 (define_expand "<s>mul<mode>3_highpart"
7064 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7069 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7071 (match_operand:SWI48 2 "register_operand" "")))
7073 (clobber (match_scratch:SWI48 3 ""))
7074 (clobber (reg:CC FLAGS_REG))])]
7076 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7078 (define_insn "*<s>muldi3_highpart_1"
7079 [(set (match_operand:DI 0 "register_operand" "=d")
7084 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7086 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7088 (clobber (match_scratch:DI 3 "=1"))
7089 (clobber (reg:CC FLAGS_REG))]
7091 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7092 "<sgnprefix>mul{q}\t%2"
7093 [(set_attr "type" "imul")
7094 (set_attr "length_immediate" "0")
7095 (set (attr "athlon_decode")
7096 (if_then_else (eq_attr "cpu" "athlon")
7097 (const_string "vector")
7098 (const_string "double")))
7099 (set_attr "amdfam10_decode" "double")
7100 (set_attr "bdver1_decode" "direct")
7101 (set_attr "mode" "DI")])
7103 (define_insn "*<s>mulsi3_highpart_1"
7104 [(set (match_operand:SI 0 "register_operand" "=d")
7109 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7111 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7113 (clobber (match_scratch:SI 3 "=1"))
7114 (clobber (reg:CC FLAGS_REG))]
7115 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7116 "<sgnprefix>mul{l}\t%2"
7117 [(set_attr "type" "imul")
7118 (set_attr "length_immediate" "0")
7119 (set (attr "athlon_decode")
7120 (if_then_else (eq_attr "cpu" "athlon")
7121 (const_string "vector")
7122 (const_string "double")))
7123 (set_attr "amdfam10_decode" "double")
7124 (set_attr "bdver1_decode" "direct")
7125 (set_attr "mode" "SI")])
7127 (define_insn "*<s>mulsi3_highpart_zext"
7128 [(set (match_operand:DI 0 "register_operand" "=d")
7129 (zero_extend:DI (truncate:SI
7131 (mult:DI (any_extend:DI
7132 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7134 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7136 (clobber (match_scratch:SI 3 "=1"))
7137 (clobber (reg:CC FLAGS_REG))]
7139 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7140 "<sgnprefix>mul{l}\t%2"
7141 [(set_attr "type" "imul")
7142 (set_attr "length_immediate" "0")
7143 (set (attr "athlon_decode")
7144 (if_then_else (eq_attr "cpu" "athlon")
7145 (const_string "vector")
7146 (const_string "double")))
7147 (set_attr "amdfam10_decode" "double")
7148 (set_attr "bdver1_decode" "direct")
7149 (set_attr "mode" "SI")])
7151 ;; The patterns that match these are at the end of this file.
7153 (define_expand "mulxf3"
7154 [(set (match_operand:XF 0 "register_operand" "")
7155 (mult:XF (match_operand:XF 1 "register_operand" "")
7156 (match_operand:XF 2 "register_operand" "")))]
7159 (define_expand "mul<mode>3"
7160 [(set (match_operand:MODEF 0 "register_operand" "")
7161 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7162 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7163 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7164 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7166 ;; Divide instructions
7168 ;; The patterns that match these are at the end of this file.
7170 (define_expand "divxf3"
7171 [(set (match_operand:XF 0 "register_operand" "")
7172 (div:XF (match_operand:XF 1 "register_operand" "")
7173 (match_operand:XF 2 "register_operand" "")))]
7176 (define_expand "divdf3"
7177 [(set (match_operand:DF 0 "register_operand" "")
7178 (div:DF (match_operand:DF 1 "register_operand" "")
7179 (match_operand:DF 2 "nonimmediate_operand" "")))]
7180 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7181 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7183 (define_expand "divsf3"
7184 [(set (match_operand:SF 0 "register_operand" "")
7185 (div:SF (match_operand:SF 1 "register_operand" "")
7186 (match_operand:SF 2 "nonimmediate_operand" "")))]
7187 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7190 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7191 && flag_finite_math_only && !flag_trapping_math
7192 && flag_unsafe_math_optimizations)
7194 ix86_emit_swdivsf (operands[0], operands[1],
7195 operands[2], SFmode);
7200 ;; Divmod instructions.
7202 (define_expand "divmod<mode>4"
7203 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7205 (match_operand:SWIM248 1 "register_operand" "")
7206 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7207 (set (match_operand:SWIM248 3 "register_operand" "")
7208 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7209 (clobber (reg:CC FLAGS_REG))])])
7211 ;; Split with 8bit unsigned divide:
7212 ;; if (dividend an divisor are in [0-255])
7213 ;; use 8bit unsigned integer divide
7215 ;; use original integer divide
7217 [(set (match_operand:SWI48 0 "register_operand" "")
7218 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7219 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7220 (set (match_operand:SWI48 1 "register_operand" "")
7221 (mod:SWI48 (match_dup 2) (match_dup 3)))
7222 (clobber (reg:CC FLAGS_REG))]
7223 "TARGET_USE_8BIT_IDIV
7224 && TARGET_QIMODE_MATH
7225 && can_create_pseudo_p ()
7226 && !optimize_insn_for_size_p ()"
7228 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7230 (define_insn_and_split "divmod<mode>4_1"
7231 [(set (match_operand:SWI48 0 "register_operand" "=a")
7232 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7233 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7234 (set (match_operand:SWI48 1 "register_operand" "=&d")
7235 (mod:SWI48 (match_dup 2) (match_dup 3)))
7236 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7237 (clobber (reg:CC FLAGS_REG))]
7241 [(parallel [(set (match_dup 1)
7242 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7243 (clobber (reg:CC FLAGS_REG))])
7244 (parallel [(set (match_dup 0)
7245 (div:SWI48 (match_dup 2) (match_dup 3)))
7247 (mod:SWI48 (match_dup 2) (match_dup 3)))
7249 (clobber (reg:CC FLAGS_REG))])]
7251 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7253 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7254 operands[4] = operands[2];
7257 /* Avoid use of cltd in favor of a mov+shift. */
7258 emit_move_insn (operands[1], operands[2]);
7259 operands[4] = operands[1];
7262 [(set_attr "type" "multi")
7263 (set_attr "mode" "<MODE>")])
7265 (define_insn_and_split "*divmod<mode>4"
7266 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7267 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7268 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7269 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7270 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7271 (clobber (reg:CC FLAGS_REG))]
7275 [(parallel [(set (match_dup 1)
7276 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7277 (clobber (reg:CC FLAGS_REG))])
7278 (parallel [(set (match_dup 0)
7279 (div:SWIM248 (match_dup 2) (match_dup 3)))
7281 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7283 (clobber (reg:CC FLAGS_REG))])]
7285 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7287 if (<MODE>mode != HImode
7288 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7289 operands[4] = operands[2];
7292 /* Avoid use of cltd in favor of a mov+shift. */
7293 emit_move_insn (operands[1], operands[2]);
7294 operands[4] = operands[1];
7297 [(set_attr "type" "multi")
7298 (set_attr "mode" "<MODE>")])
7300 (define_insn "*divmod<mode>4_noext"
7301 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7302 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7303 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7304 (set (match_operand:SWIM248 1 "register_operand" "=d")
7305 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7306 (use (match_operand:SWIM248 4 "register_operand" "1"))
7307 (clobber (reg:CC FLAGS_REG))]
7309 "idiv{<imodesuffix>}\t%3"
7310 [(set_attr "type" "idiv")
7311 (set_attr "mode" "<MODE>")])
7313 (define_expand "divmodqi4"
7314 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7316 (match_operand:QI 1 "register_operand" "")
7317 (match_operand:QI 2 "nonimmediate_operand" "")))
7318 (set (match_operand:QI 3 "register_operand" "")
7319 (mod:QI (match_dup 1) (match_dup 2)))
7320 (clobber (reg:CC FLAGS_REG))])]
7321 "TARGET_QIMODE_MATH"
7326 tmp0 = gen_reg_rtx (HImode);
7327 tmp1 = gen_reg_rtx (HImode);
7329 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7331 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7332 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7334 /* Extract remainder from AH. */
7335 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7336 insn = emit_move_insn (operands[3], tmp1);
7338 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7339 set_unique_reg_note (insn, REG_EQUAL, mod);
7341 /* Extract quotient from AL. */
7342 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7344 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7345 set_unique_reg_note (insn, REG_EQUAL, div);
7350 ;; Divide AX by r/m8, with result stored in
7353 ;; Change div/mod to HImode and extend the second argument to HImode
7354 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7355 ;; combine may fail.
7356 (define_insn "divmodhiqi3"
7357 [(set (match_operand:HI 0 "register_operand" "=a")
7362 (mod:HI (match_operand:HI 1 "register_operand" "0")
7364 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7368 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7369 (clobber (reg:CC FLAGS_REG))]
7370 "TARGET_QIMODE_MATH"
7372 [(set_attr "type" "idiv")
7373 (set_attr "mode" "QI")])
7375 (define_expand "udivmod<mode>4"
7376 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7378 (match_operand:SWIM248 1 "register_operand" "")
7379 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7380 (set (match_operand:SWIM248 3 "register_operand" "")
7381 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7382 (clobber (reg:CC FLAGS_REG))])])
7384 ;; Split with 8bit unsigned divide:
7385 ;; if (dividend an divisor are in [0-255])
7386 ;; use 8bit unsigned integer divide
7388 ;; use original integer divide
7390 [(set (match_operand:SWI48 0 "register_operand" "")
7391 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7392 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7393 (set (match_operand:SWI48 1 "register_operand" "")
7394 (umod:SWI48 (match_dup 2) (match_dup 3)))
7395 (clobber (reg:CC FLAGS_REG))]
7396 "TARGET_USE_8BIT_IDIV
7397 && TARGET_QIMODE_MATH
7398 && can_create_pseudo_p ()
7399 && !optimize_insn_for_size_p ()"
7401 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7403 (define_insn_and_split "udivmod<mode>4_1"
7404 [(set (match_operand:SWI48 0 "register_operand" "=a")
7405 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7406 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7407 (set (match_operand:SWI48 1 "register_operand" "=&d")
7408 (umod:SWI48 (match_dup 2) (match_dup 3)))
7409 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7410 (clobber (reg:CC FLAGS_REG))]
7414 [(set (match_dup 1) (const_int 0))
7415 (parallel [(set (match_dup 0)
7416 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7418 (umod:SWI48 (match_dup 2) (match_dup 3)))
7420 (clobber (reg:CC FLAGS_REG))])]
7422 [(set_attr "type" "multi")
7423 (set_attr "mode" "<MODE>")])
7425 (define_insn_and_split "*udivmod<mode>4"
7426 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7427 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7428 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7429 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7430 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7431 (clobber (reg:CC FLAGS_REG))]
7435 [(set (match_dup 1) (const_int 0))
7436 (parallel [(set (match_dup 0)
7437 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7439 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7441 (clobber (reg:CC FLAGS_REG))])]
7443 [(set_attr "type" "multi")
7444 (set_attr "mode" "<MODE>")])
7446 (define_insn "*udivmod<mode>4_noext"
7447 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7448 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7449 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7450 (set (match_operand:SWIM248 1 "register_operand" "=d")
7451 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7452 (use (match_operand:SWIM248 4 "register_operand" "1"))
7453 (clobber (reg:CC FLAGS_REG))]
7455 "div{<imodesuffix>}\t%3"
7456 [(set_attr "type" "idiv")
7457 (set_attr "mode" "<MODE>")])
7459 (define_expand "udivmodqi4"
7460 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7462 (match_operand:QI 1 "register_operand" "")
7463 (match_operand:QI 2 "nonimmediate_operand" "")))
7464 (set (match_operand:QI 3 "register_operand" "")
7465 (umod:QI (match_dup 1) (match_dup 2)))
7466 (clobber (reg:CC FLAGS_REG))])]
7467 "TARGET_QIMODE_MATH"
7472 tmp0 = gen_reg_rtx (HImode);
7473 tmp1 = gen_reg_rtx (HImode);
7475 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7477 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7478 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7480 /* Extract remainder from AH. */
7481 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7482 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7483 insn = emit_move_insn (operands[3], tmp1);
7485 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7486 set_unique_reg_note (insn, REG_EQUAL, mod);
7488 /* Extract quotient from AL. */
7489 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7491 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7492 set_unique_reg_note (insn, REG_EQUAL, div);
7497 (define_insn "udivmodhiqi3"
7498 [(set (match_operand:HI 0 "register_operand" "=a")
7503 (mod:HI (match_operand:HI 1 "register_operand" "0")
7505 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7509 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7510 (clobber (reg:CC FLAGS_REG))]
7511 "TARGET_QIMODE_MATH"
7513 [(set_attr "type" "idiv")
7514 (set_attr "mode" "QI")])
7516 ;; We cannot use div/idiv for double division, because it causes
7517 ;; "division by zero" on the overflow and that's not what we expect
7518 ;; from truncate. Because true (non truncating) double division is
7519 ;; never generated, we can't create this insn anyway.
7522 ; [(set (match_operand:SI 0 "register_operand" "=a")
7524 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7526 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7527 ; (set (match_operand:SI 3 "register_operand" "=d")
7529 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7530 ; (clobber (reg:CC FLAGS_REG))]
7532 ; "div{l}\t{%2, %0|%0, %2}"
7533 ; [(set_attr "type" "idiv")])
7535 ;;- Logical AND instructions
7537 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7538 ;; Note that this excludes ah.
7540 (define_expand "testsi_ccno_1"
7541 [(set (reg:CCNO FLAGS_REG)
7543 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7544 (match_operand:SI 1 "nonmemory_operand" ""))
7547 (define_expand "testqi_ccz_1"
7548 [(set (reg:CCZ FLAGS_REG)
7549 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7550 (match_operand:QI 1 "nonmemory_operand" ""))
7553 (define_expand "testdi_ccno_1"
7554 [(set (reg:CCNO FLAGS_REG)
7556 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7557 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7559 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7561 (define_insn "*testdi_1"
7562 [(set (reg FLAGS_REG)
7565 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7566 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7568 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7569 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7571 test{l}\t{%k1, %k0|%k0, %k1}
7572 test{l}\t{%k1, %k0|%k0, %k1}
7573 test{q}\t{%1, %0|%0, %1}
7574 test{q}\t{%1, %0|%0, %1}
7575 test{q}\t{%1, %0|%0, %1}"
7576 [(set_attr "type" "test")
7577 (set_attr "modrm" "0,1,0,1,1")
7578 (set_attr "mode" "SI,SI,DI,DI,DI")])
7580 (define_insn "*testqi_1_maybe_si"
7581 [(set (reg FLAGS_REG)
7584 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7585 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7587 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7588 && ix86_match_ccmode (insn,
7589 CONST_INT_P (operands[1])
7590 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7592 if (which_alternative == 3)
7594 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7595 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7596 return "test{l}\t{%1, %k0|%k0, %1}";
7598 return "test{b}\t{%1, %0|%0, %1}";
7600 [(set_attr "type" "test")
7601 (set_attr "modrm" "0,1,1,1")
7602 (set_attr "mode" "QI,QI,QI,SI")
7603 (set_attr "pent_pair" "uv,np,uv,np")])
7605 (define_insn "*test<mode>_1"
7606 [(set (reg FLAGS_REG)
7609 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7610 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7612 "ix86_match_ccmode (insn, CCNOmode)
7613 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7614 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7615 [(set_attr "type" "test")
7616 (set_attr "modrm" "0,1,1")
7617 (set_attr "mode" "<MODE>")
7618 (set_attr "pent_pair" "uv,np,uv")])
7620 (define_expand "testqi_ext_ccno_0"
7621 [(set (reg:CCNO FLAGS_REG)
7625 (match_operand 0 "ext_register_operand" "")
7628 (match_operand 1 "const_int_operand" ""))
7631 (define_insn "*testqi_ext_0"
7632 [(set (reg FLAGS_REG)
7636 (match_operand 0 "ext_register_operand" "Q")
7639 (match_operand 1 "const_int_operand" "n"))
7641 "ix86_match_ccmode (insn, CCNOmode)"
7642 "test{b}\t{%1, %h0|%h0, %1}"
7643 [(set_attr "type" "test")
7644 (set_attr "mode" "QI")
7645 (set_attr "length_immediate" "1")
7646 (set_attr "modrm" "1")
7647 (set_attr "pent_pair" "np")])
7649 (define_insn "*testqi_ext_1_rex64"
7650 [(set (reg FLAGS_REG)
7654 (match_operand 0 "ext_register_operand" "Q")
7658 (match_operand:QI 1 "register_operand" "Q")))
7660 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7661 "test{b}\t{%1, %h0|%h0, %1}"
7662 [(set_attr "type" "test")
7663 (set_attr "mode" "QI")])
7665 (define_insn "*testqi_ext_1"
7666 [(set (reg FLAGS_REG)
7670 (match_operand 0 "ext_register_operand" "Q")
7674 (match_operand:QI 1 "general_operand" "Qm")))
7676 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7677 "test{b}\t{%1, %h0|%h0, %1}"
7678 [(set_attr "type" "test")
7679 (set_attr "mode" "QI")])
7681 (define_insn "*testqi_ext_2"
7682 [(set (reg FLAGS_REG)
7686 (match_operand 0 "ext_register_operand" "Q")
7690 (match_operand 1 "ext_register_operand" "Q")
7694 "ix86_match_ccmode (insn, CCNOmode)"
7695 "test{b}\t{%h1, %h0|%h0, %h1}"
7696 [(set_attr "type" "test")
7697 (set_attr "mode" "QI")])
7699 (define_insn "*testqi_ext_3_rex64"
7700 [(set (reg FLAGS_REG)
7701 (compare (zero_extract:DI
7702 (match_operand 0 "nonimmediate_operand" "rm")
7703 (match_operand:DI 1 "const_int_operand" "")
7704 (match_operand:DI 2 "const_int_operand" ""))
7707 && ix86_match_ccmode (insn, CCNOmode)
7708 && INTVAL (operands[1]) > 0
7709 && INTVAL (operands[2]) >= 0
7710 /* Ensure that resulting mask is zero or sign extended operand. */
7711 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7712 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7713 && INTVAL (operands[1]) > 32))
7714 && (GET_MODE (operands[0]) == SImode
7715 || GET_MODE (operands[0]) == DImode
7716 || GET_MODE (operands[0]) == HImode
7717 || GET_MODE (operands[0]) == QImode)"
7720 ;; Combine likes to form bit extractions for some tests. Humor it.
7721 (define_insn "*testqi_ext_3"
7722 [(set (reg FLAGS_REG)
7723 (compare (zero_extract:SI
7724 (match_operand 0 "nonimmediate_operand" "rm")
7725 (match_operand:SI 1 "const_int_operand" "")
7726 (match_operand:SI 2 "const_int_operand" ""))
7728 "ix86_match_ccmode (insn, CCNOmode)
7729 && INTVAL (operands[1]) > 0
7730 && INTVAL (operands[2]) >= 0
7731 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7732 && (GET_MODE (operands[0]) == SImode
7733 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7734 || GET_MODE (operands[0]) == HImode
7735 || GET_MODE (operands[0]) == QImode)"
7739 [(set (match_operand 0 "flags_reg_operand" "")
7740 (match_operator 1 "compare_operator"
7742 (match_operand 2 "nonimmediate_operand" "")
7743 (match_operand 3 "const_int_operand" "")
7744 (match_operand 4 "const_int_operand" ""))
7746 "ix86_match_ccmode (insn, CCNOmode)"
7747 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7749 rtx val = operands[2];
7750 HOST_WIDE_INT len = INTVAL (operands[3]);
7751 HOST_WIDE_INT pos = INTVAL (operands[4]);
7753 enum machine_mode mode, submode;
7755 mode = GET_MODE (val);
7758 /* ??? Combine likes to put non-volatile mem extractions in QImode
7759 no matter the size of the test. So find a mode that works. */
7760 if (! MEM_VOLATILE_P (val))
7762 mode = smallest_mode_for_size (pos + len, MODE_INT);
7763 val = adjust_address (val, mode, 0);
7766 else if (GET_CODE (val) == SUBREG
7767 && (submode = GET_MODE (SUBREG_REG (val)),
7768 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7769 && pos + len <= GET_MODE_BITSIZE (submode)
7770 && GET_MODE_CLASS (submode) == MODE_INT)
7772 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7774 val = SUBREG_REG (val);
7776 else if (mode == HImode && pos + len <= 8)
7778 /* Small HImode tests can be converted to QImode. */
7780 val = gen_lowpart (QImode, val);
7783 if (len == HOST_BITS_PER_WIDE_INT)
7786 mask = ((HOST_WIDE_INT)1 << len) - 1;
7789 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7792 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7793 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7794 ;; this is relatively important trick.
7795 ;; Do the conversion only post-reload to avoid limiting of the register class
7798 [(set (match_operand 0 "flags_reg_operand" "")
7799 (match_operator 1 "compare_operator"
7800 [(and (match_operand 2 "register_operand" "")
7801 (match_operand 3 "const_int_operand" ""))
7804 && QI_REG_P (operands[2])
7805 && GET_MODE (operands[2]) != QImode
7806 && ((ix86_match_ccmode (insn, CCZmode)
7807 && !(INTVAL (operands[3]) & ~(255 << 8)))
7808 || (ix86_match_ccmode (insn, CCNOmode)
7809 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7812 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7815 "operands[2] = gen_lowpart (SImode, operands[2]);
7816 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7819 [(set (match_operand 0 "flags_reg_operand" "")
7820 (match_operator 1 "compare_operator"
7821 [(and (match_operand 2 "nonimmediate_operand" "")
7822 (match_operand 3 "const_int_operand" ""))
7825 && GET_MODE (operands[2]) != QImode
7826 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7827 && ((ix86_match_ccmode (insn, CCZmode)
7828 && !(INTVAL (operands[3]) & ~255))
7829 || (ix86_match_ccmode (insn, CCNOmode)
7830 && !(INTVAL (operands[3]) & ~127)))"
7832 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7834 "operands[2] = gen_lowpart (QImode, operands[2]);
7835 operands[3] = gen_lowpart (QImode, operands[3]);")
7837 ;; %%% This used to optimize known byte-wide and operations to memory,
7838 ;; and sometimes to QImode registers. If this is considered useful,
7839 ;; it should be done with splitters.
7841 (define_expand "and<mode>3"
7842 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7843 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7844 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7846 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7848 (define_insn "*anddi_1"
7849 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7851 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7852 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7853 (clobber (reg:CC FLAGS_REG))]
7854 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7856 switch (get_attr_type (insn))
7860 enum machine_mode mode;
7862 gcc_assert (CONST_INT_P (operands[2]));
7863 if (INTVAL (operands[2]) == 0xff)
7867 gcc_assert (INTVAL (operands[2]) == 0xffff);
7871 operands[1] = gen_lowpart (mode, operands[1]);
7873 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7875 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7879 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7880 if (get_attr_mode (insn) == MODE_SI)
7881 return "and{l}\t{%k2, %k0|%k0, %k2}";
7883 return "and{q}\t{%2, %0|%0, %2}";
7886 [(set_attr "type" "alu,alu,alu,imovx")
7887 (set_attr "length_immediate" "*,*,*,0")
7888 (set (attr "prefix_rex")
7890 (and (eq_attr "type" "imovx")
7891 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7892 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7894 (const_string "*")))
7895 (set_attr "mode" "SI,DI,DI,SI")])
7897 (define_insn "*andsi_1"
7898 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7899 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7900 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7901 (clobber (reg:CC FLAGS_REG))]
7902 "ix86_binary_operator_ok (AND, SImode, operands)"
7904 switch (get_attr_type (insn))
7908 enum machine_mode mode;
7910 gcc_assert (CONST_INT_P (operands[2]));
7911 if (INTVAL (operands[2]) == 0xff)
7915 gcc_assert (INTVAL (operands[2]) == 0xffff);
7919 operands[1] = gen_lowpart (mode, operands[1]);
7921 return "movz{bl|x}\t{%1, %0|%0, %1}";
7923 return "movz{wl|x}\t{%1, %0|%0, %1}";
7927 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7928 return "and{l}\t{%2, %0|%0, %2}";
7931 [(set_attr "type" "alu,alu,imovx")
7932 (set (attr "prefix_rex")
7934 (and (eq_attr "type" "imovx")
7935 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7936 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7938 (const_string "*")))
7939 (set_attr "length_immediate" "*,*,0")
7940 (set_attr "mode" "SI")])
7942 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7943 (define_insn "*andsi_1_zext"
7944 [(set (match_operand:DI 0 "register_operand" "=r")
7946 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7947 (match_operand:SI 2 "general_operand" "g"))))
7948 (clobber (reg:CC FLAGS_REG))]
7949 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7950 "and{l}\t{%2, %k0|%k0, %2}"
7951 [(set_attr "type" "alu")
7952 (set_attr "mode" "SI")])
7954 (define_insn "*andhi_1"
7955 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7956 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7957 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7958 (clobber (reg:CC FLAGS_REG))]
7959 "ix86_binary_operator_ok (AND, HImode, operands)"
7961 switch (get_attr_type (insn))
7964 gcc_assert (CONST_INT_P (operands[2]));
7965 gcc_assert (INTVAL (operands[2]) == 0xff);
7966 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7969 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7971 return "and{w}\t{%2, %0|%0, %2}";
7974 [(set_attr "type" "alu,alu,imovx")
7975 (set_attr "length_immediate" "*,*,0")
7976 (set (attr "prefix_rex")
7978 (and (eq_attr "type" "imovx")
7979 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7981 (const_string "*")))
7982 (set_attr "mode" "HI,HI,SI")])
7984 ;; %%% Potential partial reg stall on alternative 2. What to do?
7985 (define_insn "*andqi_1"
7986 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7987 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7988 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7989 (clobber (reg:CC FLAGS_REG))]
7990 "ix86_binary_operator_ok (AND, QImode, operands)"
7992 and{b}\t{%2, %0|%0, %2}
7993 and{b}\t{%2, %0|%0, %2}
7994 and{l}\t{%k2, %k0|%k0, %k2}"
7995 [(set_attr "type" "alu")
7996 (set_attr "mode" "QI,QI,SI")])
7998 (define_insn "*andqi_1_slp"
7999 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8000 (and:QI (match_dup 0)
8001 (match_operand:QI 1 "general_operand" "qn,qmn")))
8002 (clobber (reg:CC FLAGS_REG))]
8003 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8004 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8005 "and{b}\t{%1, %0|%0, %1}"
8006 [(set_attr "type" "alu1")
8007 (set_attr "mode" "QI")])
8010 [(set (match_operand 0 "register_operand" "")
8012 (const_int -65536)))
8013 (clobber (reg:CC FLAGS_REG))]
8014 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8015 || optimize_function_for_size_p (cfun)"
8016 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8017 "operands[1] = gen_lowpart (HImode, operands[0]);")
8020 [(set (match_operand 0 "ext_register_operand" "")
8023 (clobber (reg:CC FLAGS_REG))]
8024 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8025 && reload_completed"
8026 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8027 "operands[1] = gen_lowpart (QImode, operands[0]);")
8030 [(set (match_operand 0 "ext_register_operand" "")
8032 (const_int -65281)))
8033 (clobber (reg:CC FLAGS_REG))]
8034 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8035 && reload_completed"
8036 [(parallel [(set (zero_extract:SI (match_dup 0)
8040 (zero_extract:SI (match_dup 0)
8043 (zero_extract:SI (match_dup 0)
8046 (clobber (reg:CC FLAGS_REG))])]
8047 "operands[0] = gen_lowpart (SImode, operands[0]);")
8049 (define_insn "*anddi_2"
8050 [(set (reg FLAGS_REG)
8053 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8054 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8056 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8057 (and:DI (match_dup 1) (match_dup 2)))]
8058 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8059 && ix86_binary_operator_ok (AND, DImode, operands)"
8061 and{l}\t{%k2, %k0|%k0, %k2}
8062 and{q}\t{%2, %0|%0, %2}
8063 and{q}\t{%2, %0|%0, %2}"
8064 [(set_attr "type" "alu")
8065 (set_attr "mode" "SI,DI,DI")])
8067 (define_insn "*andqi_2_maybe_si"
8068 [(set (reg FLAGS_REG)
8070 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8071 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8073 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8074 (and:QI (match_dup 1) (match_dup 2)))]
8075 "ix86_binary_operator_ok (AND, QImode, operands)
8076 && ix86_match_ccmode (insn,
8077 CONST_INT_P (operands[2])
8078 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8080 if (which_alternative == 2)
8082 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8083 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8084 return "and{l}\t{%2, %k0|%k0, %2}";
8086 return "and{b}\t{%2, %0|%0, %2}";
8088 [(set_attr "type" "alu")
8089 (set_attr "mode" "QI,QI,SI")])
8091 (define_insn "*and<mode>_2"
8092 [(set (reg FLAGS_REG)
8093 (compare (and:SWI124
8094 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8095 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8097 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8098 (and:SWI124 (match_dup 1) (match_dup 2)))]
8099 "ix86_match_ccmode (insn, CCNOmode)
8100 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8101 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8102 [(set_attr "type" "alu")
8103 (set_attr "mode" "<MODE>")])
8105 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8106 (define_insn "*andsi_2_zext"
8107 [(set (reg FLAGS_REG)
8109 (match_operand:SI 1 "nonimmediate_operand" "%0")
8110 (match_operand:SI 2 "general_operand" "g"))
8112 (set (match_operand:DI 0 "register_operand" "=r")
8113 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8114 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8115 && ix86_binary_operator_ok (AND, SImode, operands)"
8116 "and{l}\t{%2, %k0|%k0, %2}"
8117 [(set_attr "type" "alu")
8118 (set_attr "mode" "SI")])
8120 (define_insn "*andqi_2_slp"
8121 [(set (reg FLAGS_REG)
8123 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8124 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8126 (set (strict_low_part (match_dup 0))
8127 (and:QI (match_dup 0) (match_dup 1)))]
8128 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8129 && ix86_match_ccmode (insn, CCNOmode)
8130 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8131 "and{b}\t{%1, %0|%0, %1}"
8132 [(set_attr "type" "alu1")
8133 (set_attr "mode" "QI")])
8135 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8136 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8137 ;; for a QImode operand, which of course failed.
8138 (define_insn "andqi_ext_0"
8139 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8144 (match_operand 1 "ext_register_operand" "0")
8147 (match_operand 2 "const_int_operand" "n")))
8148 (clobber (reg:CC FLAGS_REG))]
8150 "and{b}\t{%2, %h0|%h0, %2}"
8151 [(set_attr "type" "alu")
8152 (set_attr "length_immediate" "1")
8153 (set_attr "modrm" "1")
8154 (set_attr "mode" "QI")])
8156 ;; Generated by peephole translating test to and. This shows up
8157 ;; often in fp comparisons.
8158 (define_insn "*andqi_ext_0_cc"
8159 [(set (reg FLAGS_REG)
8163 (match_operand 1 "ext_register_operand" "0")
8166 (match_operand 2 "const_int_operand" "n"))
8168 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8177 "ix86_match_ccmode (insn, CCNOmode)"
8178 "and{b}\t{%2, %h0|%h0, %2}"
8179 [(set_attr "type" "alu")
8180 (set_attr "length_immediate" "1")
8181 (set_attr "modrm" "1")
8182 (set_attr "mode" "QI")])
8184 (define_insn "*andqi_ext_1_rex64"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8190 (match_operand 1 "ext_register_operand" "0")
8194 (match_operand 2 "ext_register_operand" "Q"))))
8195 (clobber (reg:CC FLAGS_REG))]
8197 "and{b}\t{%2, %h0|%h0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "length_immediate" "0")
8200 (set_attr "mode" "QI")])
8202 (define_insn "*andqi_ext_1"
8203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8208 (match_operand 1 "ext_register_operand" "0")
8212 (match_operand:QI 2 "general_operand" "Qm"))))
8213 (clobber (reg:CC FLAGS_REG))]
8215 "and{b}\t{%2, %h0|%h0, %2}"
8216 [(set_attr "type" "alu")
8217 (set_attr "length_immediate" "0")
8218 (set_attr "mode" "QI")])
8220 (define_insn "*andqi_ext_2"
8221 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8226 (match_operand 1 "ext_register_operand" "%0")
8230 (match_operand 2 "ext_register_operand" "Q")
8233 (clobber (reg:CC FLAGS_REG))]
8235 "and{b}\t{%h2, %h0|%h0, %h2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "length_immediate" "0")
8238 (set_attr "mode" "QI")])
8240 ;; Convert wide AND instructions with immediate operand to shorter QImode
8241 ;; equivalents when possible.
8242 ;; Don't do the splitting with memory operands, since it introduces risk
8243 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8244 ;; for size, but that can (should?) be handled by generic code instead.
8246 [(set (match_operand 0 "register_operand" "")
8247 (and (match_operand 1 "register_operand" "")
8248 (match_operand 2 "const_int_operand" "")))
8249 (clobber (reg:CC FLAGS_REG))]
8251 && QI_REG_P (operands[0])
8252 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8253 && !(~INTVAL (operands[2]) & ~(255 << 8))
8254 && GET_MODE (operands[0]) != QImode"
8255 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8256 (and:SI (zero_extract:SI (match_dup 1)
8257 (const_int 8) (const_int 8))
8259 (clobber (reg:CC FLAGS_REG))])]
8260 "operands[0] = gen_lowpart (SImode, operands[0]);
8261 operands[1] = gen_lowpart (SImode, operands[1]);
8262 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8264 ;; Since AND can be encoded with sign extended immediate, this is only
8265 ;; profitable when 7th bit is not set.
8267 [(set (match_operand 0 "register_operand" "")
8268 (and (match_operand 1 "general_operand" "")
8269 (match_operand 2 "const_int_operand" "")))
8270 (clobber (reg:CC FLAGS_REG))]
8272 && ANY_QI_REG_P (operands[0])
8273 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8274 && !(~INTVAL (operands[2]) & ~255)
8275 && !(INTVAL (operands[2]) & 128)
8276 && GET_MODE (operands[0]) != QImode"
8277 [(parallel [(set (strict_low_part (match_dup 0))
8278 (and:QI (match_dup 1)
8280 (clobber (reg:CC FLAGS_REG))])]
8281 "operands[0] = gen_lowpart (QImode, operands[0]);
8282 operands[1] = gen_lowpart (QImode, operands[1]);
8283 operands[2] = gen_lowpart (QImode, operands[2]);")
8285 ;; Logical inclusive and exclusive OR instructions
8287 ;; %%% This used to optimize known byte-wide and operations to memory.
8288 ;; If this is considered useful, it should be done with splitters.
8290 (define_expand "<code><mode>3"
8291 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8292 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8293 (match_operand:SWIM 2 "<general_operand>" "")))]
8295 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8297 (define_insn "*<code><mode>_1"
8298 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8300 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8301 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8302 (clobber (reg:CC FLAGS_REG))]
8303 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8304 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "<MODE>")])
8308 ;; %%% Potential partial reg stall on alternative 2. What to do?
8309 (define_insn "*<code>qi_1"
8310 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8311 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8312 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8316 <logic>{b}\t{%2, %0|%0, %2}
8317 <logic>{b}\t{%2, %0|%0, %2}
8318 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "mode" "QI,QI,SI")])
8322 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8323 (define_insn "*<code>si_1_zext"
8324 [(set (match_operand:DI 0 "register_operand" "=r")
8326 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8327 (match_operand:SI 2 "general_operand" "g"))))
8328 (clobber (reg:CC FLAGS_REG))]
8329 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8330 "<logic>{l}\t{%2, %k0|%k0, %2}"
8331 [(set_attr "type" "alu")
8332 (set_attr "mode" "SI")])
8334 (define_insn "*<code>si_1_zext_imm"
8335 [(set (match_operand:DI 0 "register_operand" "=r")
8337 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8338 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8339 (clobber (reg:CC FLAGS_REG))]
8340 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8341 "<logic>{l}\t{%2, %k0|%k0, %2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "mode" "SI")])
8345 (define_insn "*<code>qi_1_slp"
8346 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8347 (any_or:QI (match_dup 0)
8348 (match_operand:QI 1 "general_operand" "qmn,qn")))
8349 (clobber (reg:CC FLAGS_REG))]
8350 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8351 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8352 "<logic>{b}\t{%1, %0|%0, %1}"
8353 [(set_attr "type" "alu1")
8354 (set_attr "mode" "QI")])
8356 (define_insn "*<code><mode>_2"
8357 [(set (reg FLAGS_REG)
8358 (compare (any_or:SWI
8359 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8360 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8362 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8363 (any_or:SWI (match_dup 1) (match_dup 2)))]
8364 "ix86_match_ccmode (insn, CCNOmode)
8365 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8366 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8367 [(set_attr "type" "alu")
8368 (set_attr "mode" "<MODE>")])
8370 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8371 ;; ??? Special case for immediate operand is missing - it is tricky.
8372 (define_insn "*<code>si_2_zext"
8373 [(set (reg FLAGS_REG)
8374 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8375 (match_operand:SI 2 "general_operand" "g"))
8377 (set (match_operand:DI 0 "register_operand" "=r")
8378 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8379 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8380 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8381 "<logic>{l}\t{%2, %k0|%k0, %2}"
8382 [(set_attr "type" "alu")
8383 (set_attr "mode" "SI")])
8385 (define_insn "*<code>si_2_zext_imm"
8386 [(set (reg FLAGS_REG)
8388 (match_operand:SI 1 "nonimmediate_operand" "%0")
8389 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8391 (set (match_operand:DI 0 "register_operand" "=r")
8392 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8393 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8394 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8395 "<logic>{l}\t{%2, %k0|%k0, %2}"
8396 [(set_attr "type" "alu")
8397 (set_attr "mode" "SI")])
8399 (define_insn "*<code>qi_2_slp"
8400 [(set (reg FLAGS_REG)
8401 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8402 (match_operand:QI 1 "general_operand" "qmn,qn"))
8404 (set (strict_low_part (match_dup 0))
8405 (any_or:QI (match_dup 0) (match_dup 1)))]
8406 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8407 && ix86_match_ccmode (insn, CCNOmode)
8408 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8409 "<logic>{b}\t{%1, %0|%0, %1}"
8410 [(set_attr "type" "alu1")
8411 (set_attr "mode" "QI")])
8413 (define_insn "*<code><mode>_3"
8414 [(set (reg FLAGS_REG)
8415 (compare (any_or:SWI
8416 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8417 (match_operand:SWI 2 "<general_operand>" "<g>"))
8419 (clobber (match_scratch:SWI 0 "=<r>"))]
8420 "ix86_match_ccmode (insn, CCNOmode)
8421 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8422 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8423 [(set_attr "type" "alu")
8424 (set_attr "mode" "<MODE>")])
8426 (define_insn "*<code>qi_ext_0"
8427 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8432 (match_operand 1 "ext_register_operand" "0")
8435 (match_operand 2 "const_int_operand" "n")))
8436 (clobber (reg:CC FLAGS_REG))]
8437 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8438 "<logic>{b}\t{%2, %h0|%h0, %2}"
8439 [(set_attr "type" "alu")
8440 (set_attr "length_immediate" "1")
8441 (set_attr "modrm" "1")
8442 (set_attr "mode" "QI")])
8444 (define_insn "*<code>qi_ext_1_rex64"
8445 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8450 (match_operand 1 "ext_register_operand" "0")
8454 (match_operand 2 "ext_register_operand" "Q"))))
8455 (clobber (reg:CC FLAGS_REG))]
8457 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8458 "<logic>{b}\t{%2, %h0|%h0, %2}"
8459 [(set_attr "type" "alu")
8460 (set_attr "length_immediate" "0")
8461 (set_attr "mode" "QI")])
8463 (define_insn "*<code>qi_ext_1"
8464 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8469 (match_operand 1 "ext_register_operand" "0")
8473 (match_operand:QI 2 "general_operand" "Qm"))))
8474 (clobber (reg:CC FLAGS_REG))]
8476 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8477 "<logic>{b}\t{%2, %h0|%h0, %2}"
8478 [(set_attr "type" "alu")
8479 (set_attr "length_immediate" "0")
8480 (set_attr "mode" "QI")])
8482 (define_insn "*<code>qi_ext_2"
8483 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8487 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8490 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8493 (clobber (reg:CC FLAGS_REG))]
8494 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8495 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8496 [(set_attr "type" "alu")
8497 (set_attr "length_immediate" "0")
8498 (set_attr "mode" "QI")])
8501 [(set (match_operand 0 "register_operand" "")
8502 (any_or (match_operand 1 "register_operand" "")
8503 (match_operand 2 "const_int_operand" "")))
8504 (clobber (reg:CC FLAGS_REG))]
8506 && QI_REG_P (operands[0])
8507 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8508 && !(INTVAL (operands[2]) & ~(255 << 8))
8509 && GET_MODE (operands[0]) != QImode"
8510 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8511 (any_or:SI (zero_extract:SI (match_dup 1)
8512 (const_int 8) (const_int 8))
8514 (clobber (reg:CC FLAGS_REG))])]
8515 "operands[0] = gen_lowpart (SImode, operands[0]);
8516 operands[1] = gen_lowpart (SImode, operands[1]);
8517 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8519 ;; Since OR can be encoded with sign extended immediate, this is only
8520 ;; profitable when 7th bit is set.
8522 [(set (match_operand 0 "register_operand" "")
8523 (any_or (match_operand 1 "general_operand" "")
8524 (match_operand 2 "const_int_operand" "")))
8525 (clobber (reg:CC FLAGS_REG))]
8527 && ANY_QI_REG_P (operands[0])
8528 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8529 && !(INTVAL (operands[2]) & ~255)
8530 && (INTVAL (operands[2]) & 128)
8531 && GET_MODE (operands[0]) != QImode"
8532 [(parallel [(set (strict_low_part (match_dup 0))
8533 (any_or:QI (match_dup 1)
8535 (clobber (reg:CC FLAGS_REG))])]
8536 "operands[0] = gen_lowpart (QImode, operands[0]);
8537 operands[1] = gen_lowpart (QImode, operands[1]);
8538 operands[2] = gen_lowpart (QImode, operands[2]);")
8540 (define_expand "xorqi_cc_ext_1"
8542 (set (reg:CCNO FLAGS_REG)
8546 (match_operand 1 "ext_register_operand" "")
8549 (match_operand:QI 2 "general_operand" ""))
8551 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8561 (define_insn "*xorqi_cc_ext_1_rex64"
8562 [(set (reg FLAGS_REG)
8566 (match_operand 1 "ext_register_operand" "0")
8569 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8571 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8580 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8581 "xor{b}\t{%2, %h0|%h0, %2}"
8582 [(set_attr "type" "alu")
8583 (set_attr "modrm" "1")
8584 (set_attr "mode" "QI")])
8586 (define_insn "*xorqi_cc_ext_1"
8587 [(set (reg FLAGS_REG)
8591 (match_operand 1 "ext_register_operand" "0")
8594 (match_operand:QI 2 "general_operand" "qmn"))
8596 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8605 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8606 "xor{b}\t{%2, %h0|%h0, %2}"
8607 [(set_attr "type" "alu")
8608 (set_attr "modrm" "1")
8609 (set_attr "mode" "QI")])
8611 ;; Negation instructions
8613 (define_expand "neg<mode>2"
8614 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8615 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8617 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8619 (define_insn_and_split "*neg<dwi>2_doubleword"
8620 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8621 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8622 (clobber (reg:CC FLAGS_REG))]
8623 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8627 [(set (reg:CCZ FLAGS_REG)
8628 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8629 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8632 (plus:DWIH (match_dup 3)
8633 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8635 (clobber (reg:CC FLAGS_REG))])
8638 (neg:DWIH (match_dup 2)))
8639 (clobber (reg:CC FLAGS_REG))])]
8640 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8642 (define_insn "*neg<mode>2_1"
8643 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8644 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8645 (clobber (reg:CC FLAGS_REG))]
8646 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8647 "neg{<imodesuffix>}\t%0"
8648 [(set_attr "type" "negnot")
8649 (set_attr "mode" "<MODE>")])
8651 ;; Combine is quite creative about this pattern.
8652 (define_insn "*negsi2_1_zext"
8653 [(set (match_operand:DI 0 "register_operand" "=r")
8655 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8658 (clobber (reg:CC FLAGS_REG))]
8659 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8661 [(set_attr "type" "negnot")
8662 (set_attr "mode" "SI")])
8664 ;; The problem with neg is that it does not perform (compare x 0),
8665 ;; it really performs (compare 0 x), which leaves us with the zero
8666 ;; flag being the only useful item.
8668 (define_insn "*neg<mode>2_cmpz"
8669 [(set (reg:CCZ FLAGS_REG)
8671 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8673 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8674 (neg:SWI (match_dup 1)))]
8675 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8676 "neg{<imodesuffix>}\t%0"
8677 [(set_attr "type" "negnot")
8678 (set_attr "mode" "<MODE>")])
8680 (define_insn "*negsi2_cmpz_zext"
8681 [(set (reg:CCZ FLAGS_REG)
8685 (match_operand:DI 1 "register_operand" "0")
8689 (set (match_operand:DI 0 "register_operand" "=r")
8690 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8693 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8695 [(set_attr "type" "negnot")
8696 (set_attr "mode" "SI")])
8698 ;; Changing of sign for FP values is doable using integer unit too.
8700 (define_expand "<code><mode>2"
8701 [(set (match_operand:X87MODEF 0 "register_operand" "")
8702 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8703 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8704 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8706 (define_insn "*absneg<mode>2_mixed"
8707 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8708 (match_operator:MODEF 3 "absneg_operator"
8709 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8710 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8711 (clobber (reg:CC FLAGS_REG))]
8712 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8715 (define_insn "*absneg<mode>2_sse"
8716 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8717 (match_operator:MODEF 3 "absneg_operator"
8718 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8719 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8720 (clobber (reg:CC FLAGS_REG))]
8721 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8724 (define_insn "*absneg<mode>2_i387"
8725 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8726 (match_operator:X87MODEF 3 "absneg_operator"
8727 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8728 (use (match_operand 2 "" ""))
8729 (clobber (reg:CC FLAGS_REG))]
8730 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8733 (define_expand "<code>tf2"
8734 [(set (match_operand:TF 0 "register_operand" "")
8735 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8737 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8739 (define_insn "*absnegtf2_sse"
8740 [(set (match_operand:TF 0 "register_operand" "=x,x")
8741 (match_operator:TF 3 "absneg_operator"
8742 [(match_operand:TF 1 "register_operand" "0,x")]))
8743 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8744 (clobber (reg:CC FLAGS_REG))]
8748 ;; Splitters for fp abs and neg.
8751 [(set (match_operand 0 "fp_register_operand" "")
8752 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8753 (use (match_operand 2 "" ""))
8754 (clobber (reg:CC FLAGS_REG))]
8756 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8759 [(set (match_operand 0 "register_operand" "")
8760 (match_operator 3 "absneg_operator"
8761 [(match_operand 1 "register_operand" "")]))
8762 (use (match_operand 2 "nonimmediate_operand" ""))
8763 (clobber (reg:CC FLAGS_REG))]
8764 "reload_completed && SSE_REG_P (operands[0])"
8765 [(set (match_dup 0) (match_dup 3))]
8767 enum machine_mode mode = GET_MODE (operands[0]);
8768 enum machine_mode vmode = GET_MODE (operands[2]);
8771 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8772 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8773 if (operands_match_p (operands[0], operands[2]))
8776 operands[1] = operands[2];
8779 if (GET_CODE (operands[3]) == ABS)
8780 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8782 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8787 [(set (match_operand:SF 0 "register_operand" "")
8788 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8789 (use (match_operand:V4SF 2 "" ""))
8790 (clobber (reg:CC FLAGS_REG))]
8792 [(parallel [(set (match_dup 0) (match_dup 1))
8793 (clobber (reg:CC FLAGS_REG))])]
8796 operands[0] = gen_lowpart (SImode, operands[0]);
8797 if (GET_CODE (operands[1]) == ABS)
8799 tmp = gen_int_mode (0x7fffffff, SImode);
8800 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8804 tmp = gen_int_mode (0x80000000, SImode);
8805 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8811 [(set (match_operand:DF 0 "register_operand" "")
8812 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8813 (use (match_operand 2 "" ""))
8814 (clobber (reg:CC FLAGS_REG))]
8816 [(parallel [(set (match_dup 0) (match_dup 1))
8817 (clobber (reg:CC FLAGS_REG))])]
8822 tmp = gen_lowpart (DImode, operands[0]);
8823 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8826 if (GET_CODE (operands[1]) == ABS)
8829 tmp = gen_rtx_NOT (DImode, tmp);
8833 operands[0] = gen_highpart (SImode, operands[0]);
8834 if (GET_CODE (operands[1]) == ABS)
8836 tmp = gen_int_mode (0x7fffffff, SImode);
8837 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8841 tmp = gen_int_mode (0x80000000, SImode);
8842 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8849 [(set (match_operand:XF 0 "register_operand" "")
8850 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8851 (use (match_operand 2 "" ""))
8852 (clobber (reg:CC FLAGS_REG))]
8854 [(parallel [(set (match_dup 0) (match_dup 1))
8855 (clobber (reg:CC FLAGS_REG))])]
8858 operands[0] = gen_rtx_REG (SImode,
8859 true_regnum (operands[0])
8860 + (TARGET_64BIT ? 1 : 2));
8861 if (GET_CODE (operands[1]) == ABS)
8863 tmp = GEN_INT (0x7fff);
8864 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8868 tmp = GEN_INT (0x8000);
8869 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8874 ;; Conditionalize these after reload. If they match before reload, we
8875 ;; lose the clobber and ability to use integer instructions.
8877 (define_insn "*<code><mode>2_1"
8878 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8879 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8881 && (reload_completed
8882 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8883 "f<absneg_mnemonic>"
8884 [(set_attr "type" "fsgn")
8885 (set_attr "mode" "<MODE>")])
8887 (define_insn "*<code>extendsfdf2"
8888 [(set (match_operand:DF 0 "register_operand" "=f")
8889 (absneg:DF (float_extend:DF
8890 (match_operand:SF 1 "register_operand" "0"))))]
8891 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8892 "f<absneg_mnemonic>"
8893 [(set_attr "type" "fsgn")
8894 (set_attr "mode" "DF")])
8896 (define_insn "*<code>extendsfxf2"
8897 [(set (match_operand:XF 0 "register_operand" "=f")
8898 (absneg:XF (float_extend:XF
8899 (match_operand:SF 1 "register_operand" "0"))))]
8901 "f<absneg_mnemonic>"
8902 [(set_attr "type" "fsgn")
8903 (set_attr "mode" "XF")])
8905 (define_insn "*<code>extenddfxf2"
8906 [(set (match_operand:XF 0 "register_operand" "=f")
8907 (absneg:XF (float_extend:XF
8908 (match_operand:DF 1 "register_operand" "0"))))]
8910 "f<absneg_mnemonic>"
8911 [(set_attr "type" "fsgn")
8912 (set_attr "mode" "XF")])
8914 ;; Copysign instructions
8916 (define_mode_iterator CSGNMODE [SF DF TF])
8917 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8919 (define_expand "copysign<mode>3"
8920 [(match_operand:CSGNMODE 0 "register_operand" "")
8921 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8922 (match_operand:CSGNMODE 2 "register_operand" "")]
8923 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8924 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8925 "ix86_expand_copysign (operands); DONE;")
8927 (define_insn_and_split "copysign<mode>3_const"
8928 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8930 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8931 (match_operand:CSGNMODE 2 "register_operand" "0")
8932 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8934 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8935 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8937 "&& reload_completed"
8939 "ix86_split_copysign_const (operands); DONE;")
8941 (define_insn "copysign<mode>3_var"
8942 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8944 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8945 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8946 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8947 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8949 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8950 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8951 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8955 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8957 [(match_operand:CSGNMODE 2 "register_operand" "")
8958 (match_operand:CSGNMODE 3 "register_operand" "")
8959 (match_operand:<CSGNVMODE> 4 "" "")
8960 (match_operand:<CSGNVMODE> 5 "" "")]
8962 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8963 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8964 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8965 && reload_completed"
8967 "ix86_split_copysign_var (operands); DONE;")
8969 ;; One complement instructions
8971 (define_expand "one_cmpl<mode>2"
8972 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8973 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8975 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8977 (define_insn "*one_cmpl<mode>2_1"
8978 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8979 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8980 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8981 "not{<imodesuffix>}\t%0"
8982 [(set_attr "type" "negnot")
8983 (set_attr "mode" "<MODE>")])
8985 ;; %%% Potential partial reg stall on alternative 1. What to do?
8986 (define_insn "*one_cmplqi2_1"
8987 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8988 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8989 "ix86_unary_operator_ok (NOT, QImode, operands)"
8993 [(set_attr "type" "negnot")
8994 (set_attr "mode" "QI,SI")])
8996 ;; ??? Currently never generated - xor is used instead.
8997 (define_insn "*one_cmplsi2_1_zext"
8998 [(set (match_operand:DI 0 "register_operand" "=r")
9000 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9001 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9003 [(set_attr "type" "negnot")
9004 (set_attr "mode" "SI")])
9006 (define_insn "*one_cmpl<mode>2_2"
9007 [(set (reg FLAGS_REG)
9008 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9010 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9011 (not:SWI (match_dup 1)))]
9012 "ix86_match_ccmode (insn, CCNOmode)
9013 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9015 [(set_attr "type" "alu1")
9016 (set_attr "mode" "<MODE>")])
9019 [(set (match_operand 0 "flags_reg_operand" "")
9020 (match_operator 2 "compare_operator"
9021 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9023 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9024 (not:SWI (match_dup 3)))]
9025 "ix86_match_ccmode (insn, CCNOmode)"
9026 [(parallel [(set (match_dup 0)
9027 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9030 (xor:SWI (match_dup 3) (const_int -1)))])])
9032 ;; ??? Currently never generated - xor is used instead.
9033 (define_insn "*one_cmplsi2_2_zext"
9034 [(set (reg FLAGS_REG)
9035 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9037 (set (match_operand:DI 0 "register_operand" "=r")
9038 (zero_extend:DI (not:SI (match_dup 1))))]
9039 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9040 && ix86_unary_operator_ok (NOT, SImode, operands)"
9042 [(set_attr "type" "alu1")
9043 (set_attr "mode" "SI")])
9046 [(set (match_operand 0 "flags_reg_operand" "")
9047 (match_operator 2 "compare_operator"
9048 [(not:SI (match_operand:SI 3 "register_operand" ""))
9050 (set (match_operand:DI 1 "register_operand" "")
9051 (zero_extend:DI (not:SI (match_dup 3))))]
9052 "ix86_match_ccmode (insn, CCNOmode)"
9053 [(parallel [(set (match_dup 0)
9054 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9057 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9059 ;; Shift instructions
9061 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9062 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9063 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9064 ;; from the assembler input.
9066 ;; This instruction shifts the target reg/mem as usual, but instead of
9067 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9068 ;; is a left shift double, bits are taken from the high order bits of
9069 ;; reg, else if the insn is a shift right double, bits are taken from the
9070 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9071 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9073 ;; Since sh[lr]d does not change the `reg' operand, that is done
9074 ;; separately, making all shifts emit pairs of shift double and normal
9075 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9076 ;; support a 63 bit shift, each shift where the count is in a reg expands
9077 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9079 ;; If the shift count is a constant, we need never emit more than one
9080 ;; shift pair, instead using moves and sign extension for counts greater
9083 (define_expand "ashl<mode>3"
9084 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9085 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9086 (match_operand:QI 2 "nonmemory_operand" "")))]
9088 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9090 (define_insn "*ashl<mode>3_doubleword"
9091 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9092 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9093 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9094 (clobber (reg:CC FLAGS_REG))]
9097 [(set_attr "type" "multi")])
9100 [(set (match_operand:DWI 0 "register_operand" "")
9101 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9102 (match_operand:QI 2 "nonmemory_operand" "")))
9103 (clobber (reg:CC FLAGS_REG))]
9104 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9106 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9108 ;; By default we don't ask for a scratch register, because when DWImode
9109 ;; values are manipulated, registers are already at a premium. But if
9110 ;; we have one handy, we won't turn it away.
9113 [(match_scratch:DWIH 3 "r")
9114 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9116 (match_operand:<DWI> 1 "nonmemory_operand" "")
9117 (match_operand:QI 2 "nonmemory_operand" "")))
9118 (clobber (reg:CC FLAGS_REG))])
9122 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9124 (define_insn "x86_64_shld"
9125 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9126 (ior:DI (ashift:DI (match_dup 0)
9127 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9128 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9129 (minus:QI (const_int 64) (match_dup 2)))))
9130 (clobber (reg:CC FLAGS_REG))]
9132 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9133 [(set_attr "type" "ishift")
9134 (set_attr "prefix_0f" "1")
9135 (set_attr "mode" "DI")
9136 (set_attr "athlon_decode" "vector")
9137 (set_attr "amdfam10_decode" "vector")
9138 (set_attr "bdver1_decode" "vector")])
9140 (define_insn "x86_shld"
9141 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9142 (ior:SI (ashift:SI (match_dup 0)
9143 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9144 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9145 (minus:QI (const_int 32) (match_dup 2)))))
9146 (clobber (reg:CC FLAGS_REG))]
9148 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9149 [(set_attr "type" "ishift")
9150 (set_attr "prefix_0f" "1")
9151 (set_attr "mode" "SI")
9152 (set_attr "pent_pair" "np")
9153 (set_attr "athlon_decode" "vector")
9154 (set_attr "amdfam10_decode" "vector")
9155 (set_attr "bdver1_decode" "vector")])
9157 (define_expand "x86_shift<mode>_adj_1"
9158 [(set (reg:CCZ FLAGS_REG)
9159 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9162 (set (match_operand:SWI48 0 "register_operand" "")
9163 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9164 (match_operand:SWI48 1 "register_operand" "")
9167 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9168 (match_operand:SWI48 3 "register_operand" "r")
9171 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9173 (define_expand "x86_shift<mode>_adj_2"
9174 [(use (match_operand:SWI48 0 "register_operand" ""))
9175 (use (match_operand:SWI48 1 "register_operand" ""))
9176 (use (match_operand:QI 2 "register_operand" ""))]
9179 rtx label = gen_label_rtx ();
9182 emit_insn (gen_testqi_ccz_1 (operands[2],
9183 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9185 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9186 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9187 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9188 gen_rtx_LABEL_REF (VOIDmode, label),
9190 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9191 JUMP_LABEL (tmp) = label;
9193 emit_move_insn (operands[0], operands[1]);
9194 ix86_expand_clear (operands[1]);
9197 LABEL_NUSES (label) = 1;
9202 ;; Avoid useless masking of count operand.
9203 (define_insn_and_split "*ashl<mode>3_mask"
9204 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9206 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9209 (match_operand:SI 2 "nonimmediate_operand" "c")
9210 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9211 (clobber (reg:CC FLAGS_REG))]
9212 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9213 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9214 == GET_MODE_BITSIZE (<MODE>mode)-1"
9217 [(parallel [(set (match_dup 0)
9218 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9219 (clobber (reg:CC FLAGS_REG))])]
9221 if (can_create_pseudo_p ())
9222 operands [2] = force_reg (SImode, operands[2]);
9224 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9226 [(set_attr "type" "ishift")
9227 (set_attr "mode" "<MODE>")])
9229 (define_insn "*ashl<mode>3_1"
9230 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9231 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9232 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9233 (clobber (reg:CC FLAGS_REG))]
9234 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9236 switch (get_attr_type (insn))
9242 gcc_assert (operands[2] == const1_rtx);
9243 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9244 return "add{<imodesuffix>}\t%0, %0";
9247 if (operands[2] == const1_rtx
9248 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9249 return "sal{<imodesuffix>}\t%0";
9251 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9255 (cond [(eq_attr "alternative" "1")
9256 (const_string "lea")
9257 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9259 (match_operand 0 "register_operand" ""))
9260 (match_operand 2 "const1_operand" ""))
9261 (const_string "alu")
9263 (const_string "ishift")))
9264 (set (attr "length_immediate")
9266 (ior (eq_attr "type" "alu")
9267 (and (eq_attr "type" "ishift")
9268 (and (match_operand 2 "const1_operand" "")
9269 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9272 (const_string "*")))
9273 (set_attr "mode" "<MODE>")])
9275 (define_insn "*ashlsi3_1_zext"
9276 [(set (match_operand:DI 0 "register_operand" "=r,r")
9278 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9279 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9280 (clobber (reg:CC FLAGS_REG))]
9281 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9283 switch (get_attr_type (insn))
9289 gcc_assert (operands[2] == const1_rtx);
9290 return "add{l}\t%k0, %k0";
9293 if (operands[2] == const1_rtx
9294 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9295 return "sal{l}\t%k0";
9297 return "sal{l}\t{%2, %k0|%k0, %2}";
9301 (cond [(eq_attr "alternative" "1")
9302 (const_string "lea")
9303 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9305 (match_operand 2 "const1_operand" ""))
9306 (const_string "alu")
9308 (const_string "ishift")))
9309 (set (attr "length_immediate")
9311 (ior (eq_attr "type" "alu")
9312 (and (eq_attr "type" "ishift")
9313 (and (match_operand 2 "const1_operand" "")
9314 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9317 (const_string "*")))
9318 (set_attr "mode" "SI")])
9320 (define_insn "*ashlhi3_1"
9321 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9322 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9323 (match_operand:QI 2 "nonmemory_operand" "cI")))
9324 (clobber (reg:CC FLAGS_REG))]
9325 "TARGET_PARTIAL_REG_STALL
9326 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9328 switch (get_attr_type (insn))
9331 gcc_assert (operands[2] == const1_rtx);
9332 return "add{w}\t%0, %0";
9335 if (operands[2] == const1_rtx
9336 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9337 return "sal{w}\t%0";
9339 return "sal{w}\t{%2, %0|%0, %2}";
9343 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9345 (match_operand 0 "register_operand" ""))
9346 (match_operand 2 "const1_operand" ""))
9347 (const_string "alu")
9349 (const_string "ishift")))
9350 (set (attr "length_immediate")
9352 (ior (eq_attr "type" "alu")
9353 (and (eq_attr "type" "ishift")
9354 (and (match_operand 2 "const1_operand" "")
9355 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9358 (const_string "*")))
9359 (set_attr "mode" "HI")])
9361 (define_insn "*ashlhi3_1_lea"
9362 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9363 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9364 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9365 (clobber (reg:CC FLAGS_REG))]
9366 "!TARGET_PARTIAL_REG_STALL
9367 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9369 switch (get_attr_type (insn))
9375 gcc_assert (operands[2] == const1_rtx);
9376 return "add{w}\t%0, %0";
9379 if (operands[2] == const1_rtx
9380 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9381 return "sal{w}\t%0";
9383 return "sal{w}\t{%2, %0|%0, %2}";
9387 (cond [(eq_attr "alternative" "1")
9388 (const_string "lea")
9389 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9391 (match_operand 0 "register_operand" ""))
9392 (match_operand 2 "const1_operand" ""))
9393 (const_string "alu")
9395 (const_string "ishift")))
9396 (set (attr "length_immediate")
9398 (ior (eq_attr "type" "alu")
9399 (and (eq_attr "type" "ishift")
9400 (and (match_operand 2 "const1_operand" "")
9401 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9404 (const_string "*")))
9405 (set_attr "mode" "HI,SI")])
9407 (define_insn "*ashlqi3_1"
9408 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9409 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9410 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9411 (clobber (reg:CC FLAGS_REG))]
9412 "TARGET_PARTIAL_REG_STALL
9413 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9415 switch (get_attr_type (insn))
9418 gcc_assert (operands[2] == const1_rtx);
9419 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9420 return "add{l}\t%k0, %k0";
9422 return "add{b}\t%0, %0";
9425 if (operands[2] == const1_rtx
9426 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9428 if (get_attr_mode (insn) == MODE_SI)
9429 return "sal{l}\t%k0";
9431 return "sal{b}\t%0";
9435 if (get_attr_mode (insn) == MODE_SI)
9436 return "sal{l}\t{%2, %k0|%k0, %2}";
9438 return "sal{b}\t{%2, %0|%0, %2}";
9443 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9445 (match_operand 0 "register_operand" ""))
9446 (match_operand 2 "const1_operand" ""))
9447 (const_string "alu")
9449 (const_string "ishift")))
9450 (set (attr "length_immediate")
9452 (ior (eq_attr "type" "alu")
9453 (and (eq_attr "type" "ishift")
9454 (and (match_operand 2 "const1_operand" "")
9455 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9458 (const_string "*")))
9459 (set_attr "mode" "QI,SI")])
9461 ;; %%% Potential partial reg stall on alternative 2. What to do?
9462 (define_insn "*ashlqi3_1_lea"
9463 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9464 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9465 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9466 (clobber (reg:CC FLAGS_REG))]
9467 "!TARGET_PARTIAL_REG_STALL
9468 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9470 switch (get_attr_type (insn))
9476 gcc_assert (operands[2] == const1_rtx);
9477 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9478 return "add{l}\t%k0, %k0";
9480 return "add{b}\t%0, %0";
9483 if (operands[2] == const1_rtx
9484 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9486 if (get_attr_mode (insn) == MODE_SI)
9487 return "sal{l}\t%k0";
9489 return "sal{b}\t%0";
9493 if (get_attr_mode (insn) == MODE_SI)
9494 return "sal{l}\t{%2, %k0|%k0, %2}";
9496 return "sal{b}\t{%2, %0|%0, %2}";
9501 (cond [(eq_attr "alternative" "2")
9502 (const_string "lea")
9503 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9505 (match_operand 0 "register_operand" ""))
9506 (match_operand 2 "const1_operand" ""))
9507 (const_string "alu")
9509 (const_string "ishift")))
9510 (set (attr "length_immediate")
9512 (ior (eq_attr "type" "alu")
9513 (and (eq_attr "type" "ishift")
9514 (and (match_operand 2 "const1_operand" "")
9515 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9518 (const_string "*")))
9519 (set_attr "mode" "QI,SI,SI")])
9521 (define_insn "*ashlqi3_1_slp"
9522 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9523 (ashift:QI (match_dup 0)
9524 (match_operand:QI 1 "nonmemory_operand" "cI")))
9525 (clobber (reg:CC FLAGS_REG))]
9526 "(optimize_function_for_size_p (cfun)
9527 || !TARGET_PARTIAL_FLAG_REG_STALL
9528 || (operands[1] == const1_rtx
9530 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9532 switch (get_attr_type (insn))
9535 gcc_assert (operands[1] == const1_rtx);
9536 return "add{b}\t%0, %0";
9539 if (operands[1] == const1_rtx
9540 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9541 return "sal{b}\t%0";
9543 return "sal{b}\t{%1, %0|%0, %1}";
9547 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9549 (match_operand 0 "register_operand" ""))
9550 (match_operand 1 "const1_operand" ""))
9551 (const_string "alu")
9553 (const_string "ishift1")))
9554 (set (attr "length_immediate")
9556 (ior (eq_attr "type" "alu")
9557 (and (eq_attr "type" "ishift1")
9558 (and (match_operand 1 "const1_operand" "")
9559 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9562 (const_string "*")))
9563 (set_attr "mode" "QI")])
9565 ;; Convert lea to the lea pattern to avoid flags dependency.
9567 [(set (match_operand 0 "register_operand" "")
9568 (ashift (match_operand 1 "index_register_operand" "")
9569 (match_operand:QI 2 "const_int_operand" "")))
9570 (clobber (reg:CC FLAGS_REG))]
9572 && true_regnum (operands[0]) != true_regnum (operands[1])"
9576 enum machine_mode mode = GET_MODE (operands[0]);
9579 operands[1] = gen_lowpart (Pmode, operands[1]);
9580 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9582 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9584 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9585 operands[0] = gen_lowpart (SImode, operands[0]);
9587 if (TARGET_64BIT && mode != Pmode)
9588 pat = gen_rtx_SUBREG (SImode, pat, 0);
9590 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9594 ;; Convert lea to the lea pattern to avoid flags dependency.
9596 [(set (match_operand:DI 0 "register_operand" "")
9598 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9599 (match_operand:QI 2 "const_int_operand" ""))))
9600 (clobber (reg:CC FLAGS_REG))]
9601 "TARGET_64BIT && reload_completed
9602 && true_regnum (operands[0]) != true_regnum (operands[1])"
9604 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9606 operands[1] = gen_lowpart (DImode, operands[1]);
9607 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9610 ;; This pattern can't accept a variable shift count, since shifts by
9611 ;; zero don't affect the flags. We assume that shifts by constant
9612 ;; zero are optimized away.
9613 (define_insn "*ashl<mode>3_cmp"
9614 [(set (reg FLAGS_REG)
9616 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9617 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9619 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9620 (ashift:SWI (match_dup 1) (match_dup 2)))]
9621 "(optimize_function_for_size_p (cfun)
9622 || !TARGET_PARTIAL_FLAG_REG_STALL
9623 || (operands[2] == const1_rtx
9625 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9626 && ix86_match_ccmode (insn, CCGOCmode)
9627 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9629 switch (get_attr_type (insn))
9632 gcc_assert (operands[2] == const1_rtx);
9633 return "add{<imodesuffix>}\t%0, %0";
9636 if (operands[2] == const1_rtx
9637 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9638 return "sal{<imodesuffix>}\t%0";
9640 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9644 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9646 (match_operand 0 "register_operand" ""))
9647 (match_operand 2 "const1_operand" ""))
9648 (const_string "alu")
9650 (const_string "ishift")))
9651 (set (attr "length_immediate")
9653 (ior (eq_attr "type" "alu")
9654 (and (eq_attr "type" "ishift")
9655 (and (match_operand 2 "const1_operand" "")
9656 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9659 (const_string "*")))
9660 (set_attr "mode" "<MODE>")])
9662 (define_insn "*ashlsi3_cmp_zext"
9663 [(set (reg FLAGS_REG)
9665 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9666 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9668 (set (match_operand:DI 0 "register_operand" "=r")
9669 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9671 && (optimize_function_for_size_p (cfun)
9672 || !TARGET_PARTIAL_FLAG_REG_STALL
9673 || (operands[2] == const1_rtx
9675 || TARGET_DOUBLE_WITH_ADD)))
9676 && ix86_match_ccmode (insn, CCGOCmode)
9677 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9679 switch (get_attr_type (insn))
9682 gcc_assert (operands[2] == const1_rtx);
9683 return "add{l}\t%k0, %k0";
9686 if (operands[2] == const1_rtx
9687 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9688 return "sal{l}\t%k0";
9690 return "sal{l}\t{%2, %k0|%k0, %2}";
9694 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9696 (match_operand 2 "const1_operand" ""))
9697 (const_string "alu")
9699 (const_string "ishift")))
9700 (set (attr "length_immediate")
9702 (ior (eq_attr "type" "alu")
9703 (and (eq_attr "type" "ishift")
9704 (and (match_operand 2 "const1_operand" "")
9705 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9708 (const_string "*")))
9709 (set_attr "mode" "SI")])
9711 (define_insn "*ashl<mode>3_cconly"
9712 [(set (reg FLAGS_REG)
9714 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9715 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9717 (clobber (match_scratch:SWI 0 "=<r>"))]
9718 "(optimize_function_for_size_p (cfun)
9719 || !TARGET_PARTIAL_FLAG_REG_STALL
9720 || (operands[2] == const1_rtx
9722 || TARGET_DOUBLE_WITH_ADD)))
9723 && ix86_match_ccmode (insn, CCGOCmode)
9724 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9726 switch (get_attr_type (insn))
9729 gcc_assert (operands[2] == const1_rtx);
9730 return "add{<imodesuffix>}\t%0, %0";
9733 if (operands[2] == const1_rtx
9734 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9735 return "sal{<imodesuffix>}\t%0";
9737 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9741 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9743 (match_operand 0 "register_operand" ""))
9744 (match_operand 2 "const1_operand" ""))
9745 (const_string "alu")
9747 (const_string "ishift")))
9748 (set (attr "length_immediate")
9750 (ior (eq_attr "type" "alu")
9751 (and (eq_attr "type" "ishift")
9752 (and (match_operand 2 "const1_operand" "")
9753 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9756 (const_string "*")))
9757 (set_attr "mode" "<MODE>")])
9759 ;; See comment above `ashl<mode>3' about how this works.
9761 (define_expand "<shiftrt_insn><mode>3"
9762 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9763 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9764 (match_operand:QI 2 "nonmemory_operand" "")))]
9766 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9768 ;; Avoid useless masking of count operand.
9769 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9770 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9772 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9775 (match_operand:SI 2 "nonimmediate_operand" "c")
9776 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9777 (clobber (reg:CC FLAGS_REG))]
9778 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9779 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9780 == GET_MODE_BITSIZE (<MODE>mode)-1"
9783 [(parallel [(set (match_dup 0)
9784 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9785 (clobber (reg:CC FLAGS_REG))])]
9787 if (can_create_pseudo_p ())
9788 operands [2] = force_reg (SImode, operands[2]);
9790 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9792 [(set_attr "type" "ishift")
9793 (set_attr "mode" "<MODE>")])
9795 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9796 [(set (match_operand:DWI 0 "register_operand" "=r")
9797 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9798 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9799 (clobber (reg:CC FLAGS_REG))]
9802 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9804 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9805 [(set_attr "type" "multi")])
9807 ;; By default we don't ask for a scratch register, because when DWImode
9808 ;; values are manipulated, registers are already at a premium. But if
9809 ;; we have one handy, we won't turn it away.
9812 [(match_scratch:DWIH 3 "r")
9813 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9815 (match_operand:<DWI> 1 "register_operand" "")
9816 (match_operand:QI 2 "nonmemory_operand" "")))
9817 (clobber (reg:CC FLAGS_REG))])
9821 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9823 (define_insn "x86_64_shrd"
9824 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9825 (ior:DI (ashiftrt:DI (match_dup 0)
9826 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9827 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9828 (minus:QI (const_int 64) (match_dup 2)))))
9829 (clobber (reg:CC FLAGS_REG))]
9831 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9832 [(set_attr "type" "ishift")
9833 (set_attr "prefix_0f" "1")
9834 (set_attr "mode" "DI")
9835 (set_attr "athlon_decode" "vector")
9836 (set_attr "amdfam10_decode" "vector")
9837 (set_attr "bdver1_decode" "vector")])
9839 (define_insn "x86_shrd"
9840 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9841 (ior:SI (ashiftrt:SI (match_dup 0)
9842 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9843 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9844 (minus:QI (const_int 32) (match_dup 2)))))
9845 (clobber (reg:CC FLAGS_REG))]
9847 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9848 [(set_attr "type" "ishift")
9849 (set_attr "prefix_0f" "1")
9850 (set_attr "mode" "SI")
9851 (set_attr "pent_pair" "np")
9852 (set_attr "athlon_decode" "vector")
9853 (set_attr "amdfam10_decode" "vector")
9854 (set_attr "bdver1_decode" "vector")])
9856 (define_insn "ashrdi3_cvt"
9857 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9858 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9859 (match_operand:QI 2 "const_int_operand" "")))
9860 (clobber (reg:CC FLAGS_REG))]
9861 "TARGET_64BIT && INTVAL (operands[2]) == 63
9862 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9863 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9866 sar{q}\t{%2, %0|%0, %2}"
9867 [(set_attr "type" "imovx,ishift")
9868 (set_attr "prefix_0f" "0,*")
9869 (set_attr "length_immediate" "0,*")
9870 (set_attr "modrm" "0,1")
9871 (set_attr "mode" "DI")])
9873 (define_insn "ashrsi3_cvt"
9874 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9875 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9876 (match_operand:QI 2 "const_int_operand" "")))
9877 (clobber (reg:CC FLAGS_REG))]
9878 "INTVAL (operands[2]) == 31
9879 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9880 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9883 sar{l}\t{%2, %0|%0, %2}"
9884 [(set_attr "type" "imovx,ishift")
9885 (set_attr "prefix_0f" "0,*")
9886 (set_attr "length_immediate" "0,*")
9887 (set_attr "modrm" "0,1")
9888 (set_attr "mode" "SI")])
9890 (define_insn "*ashrsi3_cvt_zext"
9891 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9893 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9894 (match_operand:QI 2 "const_int_operand" ""))))
9895 (clobber (reg:CC FLAGS_REG))]
9896 "TARGET_64BIT && INTVAL (operands[2]) == 31
9897 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9898 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9901 sar{l}\t{%2, %k0|%k0, %2}"
9902 [(set_attr "type" "imovx,ishift")
9903 (set_attr "prefix_0f" "0,*")
9904 (set_attr "length_immediate" "0,*")
9905 (set_attr "modrm" "0,1")
9906 (set_attr "mode" "SI")])
9908 (define_expand "x86_shift<mode>_adj_3"
9909 [(use (match_operand:SWI48 0 "register_operand" ""))
9910 (use (match_operand:SWI48 1 "register_operand" ""))
9911 (use (match_operand:QI 2 "register_operand" ""))]
9914 rtx label = gen_label_rtx ();
9917 emit_insn (gen_testqi_ccz_1 (operands[2],
9918 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9920 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9921 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9922 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9923 gen_rtx_LABEL_REF (VOIDmode, label),
9925 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9926 JUMP_LABEL (tmp) = label;
9928 emit_move_insn (operands[0], operands[1]);
9929 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9930 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9932 LABEL_NUSES (label) = 1;
9937 (define_insn "*<shiftrt_insn><mode>3_1"
9938 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9939 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9940 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9941 (clobber (reg:CC FLAGS_REG))]
9942 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9944 if (operands[2] == const1_rtx
9945 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9946 return "<shiftrt>{<imodesuffix>}\t%0";
9948 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9950 [(set_attr "type" "ishift")
9951 (set (attr "length_immediate")
9953 (and (match_operand 2 "const1_operand" "")
9954 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9957 (const_string "*")))
9958 (set_attr "mode" "<MODE>")])
9960 (define_insn "*<shiftrt_insn>si3_1_zext"
9961 [(set (match_operand:DI 0 "register_operand" "=r")
9963 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9964 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9965 (clobber (reg:CC FLAGS_REG))]
9966 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9968 if (operands[2] == const1_rtx
9969 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9970 return "<shiftrt>{l}\t%k0";
9972 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9974 [(set_attr "type" "ishift")
9975 (set (attr "length_immediate")
9977 (and (match_operand 2 "const1_operand" "")
9978 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9981 (const_string "*")))
9982 (set_attr "mode" "SI")])
9984 (define_insn "*<shiftrt_insn>qi3_1_slp"
9985 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9986 (any_shiftrt:QI (match_dup 0)
9987 (match_operand:QI 1 "nonmemory_operand" "cI")))
9988 (clobber (reg:CC FLAGS_REG))]
9989 "(optimize_function_for_size_p (cfun)
9990 || !TARGET_PARTIAL_REG_STALL
9991 || (operands[1] == const1_rtx
9994 if (operands[1] == const1_rtx
9995 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9996 return "<shiftrt>{b}\t%0";
9998 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10000 [(set_attr "type" "ishift1")
10001 (set (attr "length_immediate")
10003 (and (match_operand 1 "const1_operand" "")
10004 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10007 (const_string "*")))
10008 (set_attr "mode" "QI")])
10010 ;; This pattern can't accept a variable shift count, since shifts by
10011 ;; zero don't affect the flags. We assume that shifts by constant
10012 ;; zero are optimized away.
10013 (define_insn "*<shiftrt_insn><mode>3_cmp"
10014 [(set (reg FLAGS_REG)
10017 (match_operand:SWI 1 "nonimmediate_operand" "0")
10018 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10020 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10021 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10022 "(optimize_function_for_size_p (cfun)
10023 || !TARGET_PARTIAL_FLAG_REG_STALL
10024 || (operands[2] == const1_rtx
10026 && ix86_match_ccmode (insn, CCGOCmode)
10027 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10029 if (operands[2] == const1_rtx
10030 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10031 return "<shiftrt>{<imodesuffix>}\t%0";
10033 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10035 [(set_attr "type" "ishift")
10036 (set (attr "length_immediate")
10038 (and (match_operand 2 "const1_operand" "")
10039 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10042 (const_string "*")))
10043 (set_attr "mode" "<MODE>")])
10045 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10046 [(set (reg FLAGS_REG)
10048 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10049 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10051 (set (match_operand:DI 0 "register_operand" "=r")
10052 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10054 && (optimize_function_for_size_p (cfun)
10055 || !TARGET_PARTIAL_FLAG_REG_STALL
10056 || (operands[2] == const1_rtx
10058 && ix86_match_ccmode (insn, CCGOCmode)
10059 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10061 if (operands[2] == const1_rtx
10062 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10063 return "<shiftrt>{l}\t%k0";
10065 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10067 [(set_attr "type" "ishift")
10068 (set (attr "length_immediate")
10070 (and (match_operand 2 "const1_operand" "")
10071 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10074 (const_string "*")))
10075 (set_attr "mode" "SI")])
10077 (define_insn "*<shiftrt_insn><mode>3_cconly"
10078 [(set (reg FLAGS_REG)
10081 (match_operand:SWI 1 "nonimmediate_operand" "0")
10082 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10084 (clobber (match_scratch:SWI 0 "=<r>"))]
10085 "(optimize_function_for_size_p (cfun)
10086 || !TARGET_PARTIAL_FLAG_REG_STALL
10087 || (operands[2] == const1_rtx
10089 && ix86_match_ccmode (insn, CCGOCmode)
10090 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10092 if (operands[2] == const1_rtx
10093 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10094 return "<shiftrt>{<imodesuffix>}\t%0";
10096 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10098 [(set_attr "type" "ishift")
10099 (set (attr "length_immediate")
10101 (and (match_operand 2 "const1_operand" "")
10102 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10105 (const_string "*")))
10106 (set_attr "mode" "<MODE>")])
10108 ;; Rotate instructions
10110 (define_expand "<rotate_insn>ti3"
10111 [(set (match_operand:TI 0 "register_operand" "")
10112 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10113 (match_operand:QI 2 "nonmemory_operand" "")))]
10116 if (const_1_to_63_operand (operands[2], VOIDmode))
10117 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10118 (operands[0], operands[1], operands[2]));
10125 (define_expand "<rotate_insn>di3"
10126 [(set (match_operand:DI 0 "shiftdi_operand" "")
10127 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10128 (match_operand:QI 2 "nonmemory_operand" "")))]
10132 ix86_expand_binary_operator (<CODE>, DImode, operands);
10133 else if (const_1_to_31_operand (operands[2], VOIDmode))
10134 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10135 (operands[0], operands[1], operands[2]));
10142 (define_expand "<rotate_insn><mode>3"
10143 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10144 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10145 (match_operand:QI 2 "nonmemory_operand" "")))]
10147 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10149 ;; Avoid useless masking of count operand.
10150 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10151 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10153 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10156 (match_operand:SI 2 "nonimmediate_operand" "c")
10157 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10158 (clobber (reg:CC FLAGS_REG))]
10159 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10160 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10161 == GET_MODE_BITSIZE (<MODE>mode)-1"
10164 [(parallel [(set (match_dup 0)
10165 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10166 (clobber (reg:CC FLAGS_REG))])]
10168 if (can_create_pseudo_p ())
10169 operands [2] = force_reg (SImode, operands[2]);
10171 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10173 [(set_attr "type" "rotate")
10174 (set_attr "mode" "<MODE>")])
10176 ;; Implement rotation using two double-precision
10177 ;; shift instructions and a scratch register.
10179 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10180 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10181 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10182 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10183 (clobber (reg:CC FLAGS_REG))
10184 (clobber (match_scratch:DWIH 3 "=&r"))]
10188 [(set (match_dup 3) (match_dup 4))
10190 [(set (match_dup 4)
10191 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10192 (lshiftrt:DWIH (match_dup 5)
10193 (minus:QI (match_dup 6) (match_dup 2)))))
10194 (clobber (reg:CC FLAGS_REG))])
10196 [(set (match_dup 5)
10197 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10198 (lshiftrt:DWIH (match_dup 3)
10199 (minus:QI (match_dup 6) (match_dup 2)))))
10200 (clobber (reg:CC FLAGS_REG))])]
10202 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10204 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10207 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10208 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10209 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10210 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10211 (clobber (reg:CC FLAGS_REG))
10212 (clobber (match_scratch:DWIH 3 "=&r"))]
10216 [(set (match_dup 3) (match_dup 4))
10218 [(set (match_dup 4)
10219 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10220 (ashift:DWIH (match_dup 5)
10221 (minus:QI (match_dup 6) (match_dup 2)))))
10222 (clobber (reg:CC FLAGS_REG))])
10224 [(set (match_dup 5)
10225 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10226 (ashift:DWIH (match_dup 3)
10227 (minus:QI (match_dup 6) (match_dup 2)))))
10228 (clobber (reg:CC FLAGS_REG))])]
10230 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10232 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10235 (define_insn "*<rotate_insn><mode>3_1"
10236 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10237 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10238 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10239 (clobber (reg:CC FLAGS_REG))]
10240 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10242 if (operands[2] == const1_rtx
10243 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10244 return "<rotate>{<imodesuffix>}\t%0";
10246 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10248 [(set_attr "type" "rotate")
10249 (set (attr "length_immediate")
10251 (and (match_operand 2 "const1_operand" "")
10252 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10255 (const_string "*")))
10256 (set_attr "mode" "<MODE>")])
10258 (define_insn "*<rotate_insn>si3_1_zext"
10259 [(set (match_operand:DI 0 "register_operand" "=r")
10261 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10262 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10263 (clobber (reg:CC FLAGS_REG))]
10264 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10266 if (operands[2] == const1_rtx
10267 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10268 return "<rotate>{l}\t%k0";
10270 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10272 [(set_attr "type" "rotate")
10273 (set (attr "length_immediate")
10275 (and (match_operand 2 "const1_operand" "")
10276 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10279 (const_string "*")))
10280 (set_attr "mode" "SI")])
10282 (define_insn "*<rotate_insn>qi3_1_slp"
10283 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10284 (any_rotate:QI (match_dup 0)
10285 (match_operand:QI 1 "nonmemory_operand" "cI")))
10286 (clobber (reg:CC FLAGS_REG))]
10287 "(optimize_function_for_size_p (cfun)
10288 || !TARGET_PARTIAL_REG_STALL
10289 || (operands[1] == const1_rtx
10290 && TARGET_SHIFT1))"
10292 if (operands[1] == const1_rtx
10293 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10294 return "<rotate>{b}\t%0";
10296 return "<rotate>{b}\t{%1, %0|%0, %1}";
10298 [(set_attr "type" "rotate1")
10299 (set (attr "length_immediate")
10301 (and (match_operand 1 "const1_operand" "")
10302 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10305 (const_string "*")))
10306 (set_attr "mode" "QI")])
10309 [(set (match_operand:HI 0 "register_operand" "")
10310 (any_rotate:HI (match_dup 0) (const_int 8)))
10311 (clobber (reg:CC FLAGS_REG))]
10313 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10314 [(parallel [(set (strict_low_part (match_dup 0))
10315 (bswap:HI (match_dup 0)))
10316 (clobber (reg:CC FLAGS_REG))])])
10318 ;; Bit set / bit test instructions
10320 (define_expand "extv"
10321 [(set (match_operand:SI 0 "register_operand" "")
10322 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10323 (match_operand:SI 2 "const8_operand" "")
10324 (match_operand:SI 3 "const8_operand" "")))]
10327 /* Handle extractions from %ah et al. */
10328 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10331 /* From mips.md: extract_bit_field doesn't verify that our source
10332 matches the predicate, so check it again here. */
10333 if (! ext_register_operand (operands[1], VOIDmode))
10337 (define_expand "extzv"
10338 [(set (match_operand:SI 0 "register_operand" "")
10339 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10340 (match_operand:SI 2 "const8_operand" "")
10341 (match_operand:SI 3 "const8_operand" "")))]
10344 /* Handle extractions from %ah et al. */
10345 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10348 /* From mips.md: extract_bit_field doesn't verify that our source
10349 matches the predicate, so check it again here. */
10350 if (! ext_register_operand (operands[1], VOIDmode))
10354 (define_expand "insv"
10355 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10356 (match_operand 1 "const8_operand" "")
10357 (match_operand 2 "const8_operand" ""))
10358 (match_operand 3 "register_operand" ""))]
10361 rtx (*gen_mov_insv_1) (rtx, rtx);
10363 /* Handle insertions to %ah et al. */
10364 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10367 /* From mips.md: insert_bit_field doesn't verify that our source
10368 matches the predicate, so check it again here. */
10369 if (! ext_register_operand (operands[0], VOIDmode))
10372 gen_mov_insv_1 = (TARGET_64BIT
10373 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10375 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10379 ;; %%% bts, btr, btc, bt.
10380 ;; In general these instructions are *slow* when applied to memory,
10381 ;; since they enforce atomic operation. When applied to registers,
10382 ;; it depends on the cpu implementation. They're never faster than
10383 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10384 ;; no point. But in 64-bit, we can't hold the relevant immediates
10385 ;; within the instruction itself, so operating on bits in the high
10386 ;; 32-bits of a register becomes easier.
10388 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10389 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10390 ;; negdf respectively, so they can never be disabled entirely.
10392 (define_insn "*btsq"
10393 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10395 (match_operand:DI 1 "const_0_to_63_operand" ""))
10397 (clobber (reg:CC FLAGS_REG))]
10398 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10399 "bts{q}\t{%1, %0|%0, %1}"
10400 [(set_attr "type" "alu1")
10401 (set_attr "prefix_0f" "1")
10402 (set_attr "mode" "DI")])
10404 (define_insn "*btrq"
10405 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10407 (match_operand:DI 1 "const_0_to_63_operand" ""))
10409 (clobber (reg:CC FLAGS_REG))]
10410 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10411 "btr{q}\t{%1, %0|%0, %1}"
10412 [(set_attr "type" "alu1")
10413 (set_attr "prefix_0f" "1")
10414 (set_attr "mode" "DI")])
10416 (define_insn "*btcq"
10417 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10419 (match_operand:DI 1 "const_0_to_63_operand" ""))
10420 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10421 (clobber (reg:CC FLAGS_REG))]
10422 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10423 "btc{q}\t{%1, %0|%0, %1}"
10424 [(set_attr "type" "alu1")
10425 (set_attr "prefix_0f" "1")
10426 (set_attr "mode" "DI")])
10428 ;; Allow Nocona to avoid these instructions if a register is available.
10431 [(match_scratch:DI 2 "r")
10432 (parallel [(set (zero_extract:DI
10433 (match_operand:DI 0 "register_operand" "")
10435 (match_operand:DI 1 "const_0_to_63_operand" ""))
10437 (clobber (reg:CC FLAGS_REG))])]
10438 "TARGET_64BIT && !TARGET_USE_BT"
10441 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10444 if (HOST_BITS_PER_WIDE_INT >= 64)
10445 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10446 else if (i < HOST_BITS_PER_WIDE_INT)
10447 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10449 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10451 op1 = immed_double_const (lo, hi, DImode);
10454 emit_move_insn (operands[2], op1);
10458 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10463 [(match_scratch:DI 2 "r")
10464 (parallel [(set (zero_extract:DI
10465 (match_operand:DI 0 "register_operand" "")
10467 (match_operand:DI 1 "const_0_to_63_operand" ""))
10469 (clobber (reg:CC FLAGS_REG))])]
10470 "TARGET_64BIT && !TARGET_USE_BT"
10473 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10476 if (HOST_BITS_PER_WIDE_INT >= 64)
10477 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10478 else if (i < HOST_BITS_PER_WIDE_INT)
10479 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10481 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10483 op1 = immed_double_const (~lo, ~hi, DImode);
10486 emit_move_insn (operands[2], op1);
10490 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10495 [(match_scratch:DI 2 "r")
10496 (parallel [(set (zero_extract:DI
10497 (match_operand:DI 0 "register_operand" "")
10499 (match_operand:DI 1 "const_0_to_63_operand" ""))
10500 (not:DI (zero_extract:DI
10501 (match_dup 0) (const_int 1) (match_dup 1))))
10502 (clobber (reg:CC FLAGS_REG))])]
10503 "TARGET_64BIT && !TARGET_USE_BT"
10506 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10509 if (HOST_BITS_PER_WIDE_INT >= 64)
10510 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10511 else if (i < HOST_BITS_PER_WIDE_INT)
10512 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10514 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10516 op1 = immed_double_const (lo, hi, DImode);
10519 emit_move_insn (operands[2], op1);
10523 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10527 (define_insn "*bt<mode>"
10528 [(set (reg:CCC FLAGS_REG)
10530 (zero_extract:SWI48
10531 (match_operand:SWI48 0 "register_operand" "r")
10533 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10535 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10536 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10537 [(set_attr "type" "alu1")
10538 (set_attr "prefix_0f" "1")
10539 (set_attr "mode" "<MODE>")])
10541 ;; Store-flag instructions.
10543 ;; For all sCOND expanders, also expand the compare or test insn that
10544 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10546 (define_insn_and_split "*setcc_di_1"
10547 [(set (match_operand:DI 0 "register_operand" "=q")
10548 (match_operator:DI 1 "ix86_comparison_operator"
10549 [(reg FLAGS_REG) (const_int 0)]))]
10550 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10552 "&& reload_completed"
10553 [(set (match_dup 2) (match_dup 1))
10554 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10556 PUT_MODE (operands[1], QImode);
10557 operands[2] = gen_lowpart (QImode, operands[0]);
10560 (define_insn_and_split "*setcc_si_1_and"
10561 [(set (match_operand:SI 0 "register_operand" "=q")
10562 (match_operator:SI 1 "ix86_comparison_operator"
10563 [(reg FLAGS_REG) (const_int 0)]))
10564 (clobber (reg:CC FLAGS_REG))]
10565 "!TARGET_PARTIAL_REG_STALL
10566 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10568 "&& reload_completed"
10569 [(set (match_dup 2) (match_dup 1))
10570 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10571 (clobber (reg:CC FLAGS_REG))])]
10573 PUT_MODE (operands[1], QImode);
10574 operands[2] = gen_lowpart (QImode, operands[0]);
10577 (define_insn_and_split "*setcc_si_1_movzbl"
10578 [(set (match_operand:SI 0 "register_operand" "=q")
10579 (match_operator:SI 1 "ix86_comparison_operator"
10580 [(reg FLAGS_REG) (const_int 0)]))]
10581 "!TARGET_PARTIAL_REG_STALL
10582 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10584 "&& reload_completed"
10585 [(set (match_dup 2) (match_dup 1))
10586 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10588 PUT_MODE (operands[1], QImode);
10589 operands[2] = gen_lowpart (QImode, operands[0]);
10592 (define_insn "*setcc_qi"
10593 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10594 (match_operator:QI 1 "ix86_comparison_operator"
10595 [(reg FLAGS_REG) (const_int 0)]))]
10598 [(set_attr "type" "setcc")
10599 (set_attr "mode" "QI")])
10601 (define_insn "*setcc_qi_slp"
10602 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10603 (match_operator:QI 1 "ix86_comparison_operator"
10604 [(reg FLAGS_REG) (const_int 0)]))]
10607 [(set_attr "type" "setcc")
10608 (set_attr "mode" "QI")])
10610 ;; In general it is not safe to assume too much about CCmode registers,
10611 ;; so simplify-rtx stops when it sees a second one. Under certain
10612 ;; conditions this is safe on x86, so help combine not create
10619 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10620 (ne:QI (match_operator 1 "ix86_comparison_operator"
10621 [(reg FLAGS_REG) (const_int 0)])
10624 [(set (match_dup 0) (match_dup 1))]
10625 "PUT_MODE (operands[1], QImode);")
10628 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10629 (ne:QI (match_operator 1 "ix86_comparison_operator"
10630 [(reg FLAGS_REG) (const_int 0)])
10633 [(set (match_dup 0) (match_dup 1))]
10634 "PUT_MODE (operands[1], QImode);")
10637 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10638 (eq:QI (match_operator 1 "ix86_comparison_operator"
10639 [(reg FLAGS_REG) (const_int 0)])
10642 [(set (match_dup 0) (match_dup 1))]
10644 rtx new_op1 = copy_rtx (operands[1]);
10645 operands[1] = new_op1;
10646 PUT_MODE (new_op1, QImode);
10647 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10648 GET_MODE (XEXP (new_op1, 0))));
10650 /* Make sure that (a) the CCmode we have for the flags is strong
10651 enough for the reversed compare or (b) we have a valid FP compare. */
10652 if (! ix86_comparison_operator (new_op1, VOIDmode))
10657 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10658 (eq:QI (match_operator 1 "ix86_comparison_operator"
10659 [(reg FLAGS_REG) (const_int 0)])
10662 [(set (match_dup 0) (match_dup 1))]
10664 rtx new_op1 = copy_rtx (operands[1]);
10665 operands[1] = new_op1;
10666 PUT_MODE (new_op1, QImode);
10667 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10668 GET_MODE (XEXP (new_op1, 0))));
10670 /* Make sure that (a) the CCmode we have for the flags is strong
10671 enough for the reversed compare or (b) we have a valid FP compare. */
10672 if (! ix86_comparison_operator (new_op1, VOIDmode))
10676 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10677 ;; subsequent logical operations are used to imitate conditional moves.
10678 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10681 (define_insn "*avx_setcc<mode>"
10682 [(set (match_operand:MODEF 0 "register_operand" "=x")
10683 (match_operator:MODEF 1 "avx_comparison_float_operator"
10684 [(match_operand:MODEF 2 "register_operand" "x")
10685 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10687 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10688 [(set_attr "type" "ssecmp")
10689 (set_attr "prefix" "vex")
10690 (set_attr "length_immediate" "1")
10691 (set_attr "mode" "<MODE>")])
10693 (define_insn "*sse_setcc<mode>"
10694 [(set (match_operand:MODEF 0 "register_operand" "=x")
10695 (match_operator:MODEF 1 "sse_comparison_operator"
10696 [(match_operand:MODEF 2 "register_operand" "0")
10697 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10698 "SSE_FLOAT_MODE_P (<MODE>mode)"
10699 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10700 [(set_attr "type" "ssecmp")
10701 (set_attr "length_immediate" "1")
10702 (set_attr "mode" "<MODE>")])
10704 ;; Basic conditional jump instructions.
10705 ;; We ignore the overflow flag for signed branch instructions.
10707 (define_insn "*jcc_1"
10709 (if_then_else (match_operator 1 "ix86_comparison_operator"
10710 [(reg FLAGS_REG) (const_int 0)])
10711 (label_ref (match_operand 0 "" ""))
10715 [(set_attr "type" "ibr")
10716 (set_attr "modrm" "0")
10717 (set (attr "length")
10718 (if_then_else (and (ge (minus (match_dup 0) (pc))
10720 (lt (minus (match_dup 0) (pc))
10725 (define_insn "*jcc_2"
10727 (if_then_else (match_operator 1 "ix86_comparison_operator"
10728 [(reg FLAGS_REG) (const_int 0)])
10730 (label_ref (match_operand 0 "" ""))))]
10733 [(set_attr "type" "ibr")
10734 (set_attr "modrm" "0")
10735 (set (attr "length")
10736 (if_then_else (and (ge (minus (match_dup 0) (pc))
10738 (lt (minus (match_dup 0) (pc))
10743 ;; In general it is not safe to assume too much about CCmode registers,
10744 ;; so simplify-rtx stops when it sees a second one. Under certain
10745 ;; conditions this is safe on x86, so help combine not create
10753 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10754 [(reg FLAGS_REG) (const_int 0)])
10756 (label_ref (match_operand 1 "" ""))
10760 (if_then_else (match_dup 0)
10761 (label_ref (match_dup 1))
10763 "PUT_MODE (operands[0], VOIDmode);")
10767 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10768 [(reg FLAGS_REG) (const_int 0)])
10770 (label_ref (match_operand 1 "" ""))
10774 (if_then_else (match_dup 0)
10775 (label_ref (match_dup 1))
10778 rtx new_op0 = copy_rtx (operands[0]);
10779 operands[0] = new_op0;
10780 PUT_MODE (new_op0, VOIDmode);
10781 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10782 GET_MODE (XEXP (new_op0, 0))));
10784 /* Make sure that (a) the CCmode we have for the flags is strong
10785 enough for the reversed compare or (b) we have a valid FP compare. */
10786 if (! ix86_comparison_operator (new_op0, VOIDmode))
10790 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10791 ;; pass generates from shift insn with QImode operand. Actually, the mode
10792 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10793 ;; appropriate modulo of the bit offset value.
10795 (define_insn_and_split "*jcc_bt<mode>"
10797 (if_then_else (match_operator 0 "bt_comparison_operator"
10798 [(zero_extract:SWI48
10799 (match_operand:SWI48 1 "register_operand" "r")
10802 (match_operand:QI 2 "register_operand" "r")))
10804 (label_ref (match_operand 3 "" ""))
10806 (clobber (reg:CC FLAGS_REG))]
10807 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10810 [(set (reg:CCC FLAGS_REG)
10812 (zero_extract:SWI48
10818 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10819 (label_ref (match_dup 3))
10822 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10824 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10827 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10828 ;; also for DImode, this is what combine produces.
10829 (define_insn_and_split "*jcc_bt<mode>_mask"
10831 (if_then_else (match_operator 0 "bt_comparison_operator"
10832 [(zero_extract:SWI48
10833 (match_operand:SWI48 1 "register_operand" "r")
10836 (match_operand:SI 2 "register_operand" "r")
10837 (match_operand:SI 3 "const_int_operand" "n")))])
10838 (label_ref (match_operand 4 "" ""))
10840 (clobber (reg:CC FLAGS_REG))]
10841 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10842 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10843 == GET_MODE_BITSIZE (<MODE>mode)-1"
10846 [(set (reg:CCC FLAGS_REG)
10848 (zero_extract:SWI48
10854 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10855 (label_ref (match_dup 4))
10858 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10860 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10863 (define_insn_and_split "*jcc_btsi_1"
10865 (if_then_else (match_operator 0 "bt_comparison_operator"
10868 (match_operand:SI 1 "register_operand" "r")
10869 (match_operand:QI 2 "register_operand" "r"))
10872 (label_ref (match_operand 3 "" ""))
10874 (clobber (reg:CC FLAGS_REG))]
10875 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10878 [(set (reg:CCC FLAGS_REG)
10886 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10887 (label_ref (match_dup 3))
10890 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10892 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10895 ;; avoid useless masking of bit offset operand
10896 (define_insn_and_split "*jcc_btsi_mask_1"
10899 (match_operator 0 "bt_comparison_operator"
10902 (match_operand:SI 1 "register_operand" "r")
10905 (match_operand:SI 2 "register_operand" "r")
10906 (match_operand:SI 3 "const_int_operand" "n")) 0))
10909 (label_ref (match_operand 4 "" ""))
10911 (clobber (reg:CC FLAGS_REG))]
10912 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10913 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10916 [(set (reg:CCC FLAGS_REG)
10924 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10925 (label_ref (match_dup 4))
10927 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10929 ;; Define combination compare-and-branch fp compare instructions to help
10932 (define_insn "*fp_jcc_1_387"
10934 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10935 [(match_operand 1 "register_operand" "f")
10936 (match_operand 2 "nonimmediate_operand" "fm")])
10937 (label_ref (match_operand 3 "" ""))
10939 (clobber (reg:CCFP FPSR_REG))
10940 (clobber (reg:CCFP FLAGS_REG))
10941 (clobber (match_scratch:HI 4 "=a"))]
10943 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10944 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10945 && SELECT_CC_MODE (GET_CODE (operands[0]),
10946 operands[1], operands[2]) == CCFPmode
10950 (define_insn "*fp_jcc_1r_387"
10952 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10953 [(match_operand 1 "register_operand" "f")
10954 (match_operand 2 "nonimmediate_operand" "fm")])
10956 (label_ref (match_operand 3 "" ""))))
10957 (clobber (reg:CCFP FPSR_REG))
10958 (clobber (reg:CCFP FLAGS_REG))
10959 (clobber (match_scratch:HI 4 "=a"))]
10961 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10962 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10963 && SELECT_CC_MODE (GET_CODE (operands[0]),
10964 operands[1], operands[2]) == CCFPmode
10968 (define_insn "*fp_jcc_2_387"
10970 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10971 [(match_operand 1 "register_operand" "f")
10972 (match_operand 2 "register_operand" "f")])
10973 (label_ref (match_operand 3 "" ""))
10975 (clobber (reg:CCFP FPSR_REG))
10976 (clobber (reg:CCFP FLAGS_REG))
10977 (clobber (match_scratch:HI 4 "=a"))]
10978 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10979 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10983 (define_insn "*fp_jcc_2r_387"
10985 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10986 [(match_operand 1 "register_operand" "f")
10987 (match_operand 2 "register_operand" "f")])
10989 (label_ref (match_operand 3 "" ""))))
10990 (clobber (reg:CCFP FPSR_REG))
10991 (clobber (reg:CCFP FLAGS_REG))
10992 (clobber (match_scratch:HI 4 "=a"))]
10993 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10994 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10998 (define_insn "*fp_jcc_3_387"
11000 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11001 [(match_operand 1 "register_operand" "f")
11002 (match_operand 2 "const0_operand" "")])
11003 (label_ref (match_operand 3 "" ""))
11005 (clobber (reg:CCFP FPSR_REG))
11006 (clobber (reg:CCFP FLAGS_REG))
11007 (clobber (match_scratch:HI 4 "=a"))]
11008 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11009 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11010 && SELECT_CC_MODE (GET_CODE (operands[0]),
11011 operands[1], operands[2]) == CCFPmode
11017 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11018 [(match_operand 1 "register_operand" "")
11019 (match_operand 2 "nonimmediate_operand" "")])
11020 (match_operand 3 "" "")
11021 (match_operand 4 "" "")))
11022 (clobber (reg:CCFP FPSR_REG))
11023 (clobber (reg:CCFP FLAGS_REG))]
11027 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11028 operands[3], operands[4], NULL_RTX, NULL_RTX);
11034 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11035 [(match_operand 1 "register_operand" "")
11036 (match_operand 2 "general_operand" "")])
11037 (match_operand 3 "" "")
11038 (match_operand 4 "" "")))
11039 (clobber (reg:CCFP FPSR_REG))
11040 (clobber (reg:CCFP FLAGS_REG))
11041 (clobber (match_scratch:HI 5 "=a"))]
11045 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11046 operands[3], operands[4], operands[5], NULL_RTX);
11050 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11051 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11052 ;; with a precedence over other operators and is always put in the first
11053 ;; place. Swap condition and operands to match ficom instruction.
11055 (define_insn "*fp_jcc_4_<mode>_387"
11058 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11059 [(match_operator 1 "float_operator"
11060 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11061 (match_operand 3 "register_operand" "f,f")])
11062 (label_ref (match_operand 4 "" ""))
11064 (clobber (reg:CCFP FPSR_REG))
11065 (clobber (reg:CCFP FLAGS_REG))
11066 (clobber (match_scratch:HI 5 "=a,a"))]
11067 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11068 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11069 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11070 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11077 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11078 [(match_operator 1 "float_operator"
11079 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11080 (match_operand 3 "register_operand" "")])
11081 (match_operand 4 "" "")
11082 (match_operand 5 "" "")))
11083 (clobber (reg:CCFP FPSR_REG))
11084 (clobber (reg:CCFP FLAGS_REG))
11085 (clobber (match_scratch:HI 6 "=a"))]
11089 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11091 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11092 operands[3], operands[7],
11093 operands[4], operands[5], operands[6], NULL_RTX);
11097 ;; %%% Kill this when reload knows how to do it.
11101 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11102 [(match_operator 1 "float_operator"
11103 [(match_operand:X87MODEI12 2 "register_operand" "")])
11104 (match_operand 3 "register_operand" "")])
11105 (match_operand 4 "" "")
11106 (match_operand 5 "" "")))
11107 (clobber (reg:CCFP FPSR_REG))
11108 (clobber (reg:CCFP FLAGS_REG))
11109 (clobber (match_scratch:HI 6 "=a"))]
11113 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11114 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11116 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11117 operands[3], operands[7],
11118 operands[4], operands[5], operands[6], operands[2]);
11122 ;; Unconditional and other jump instructions
11124 (define_insn "jump"
11126 (label_ref (match_operand 0 "" "")))]
11129 [(set_attr "type" "ibr")
11130 (set (attr "length")
11131 (if_then_else (and (ge (minus (match_dup 0) (pc))
11133 (lt (minus (match_dup 0) (pc))
11137 (set_attr "modrm" "0")])
11139 (define_expand "indirect_jump"
11140 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11144 (define_insn "*indirect_jump"
11145 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11148 [(set_attr "type" "ibr")
11149 (set_attr "length_immediate" "0")])
11151 (define_expand "tablejump"
11152 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11153 (use (label_ref (match_operand 1 "" "")))])]
11156 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11157 relative. Convert the relative address to an absolute address. */
11161 enum rtx_code code;
11163 /* We can't use @GOTOFF for text labels on VxWorks;
11164 see gotoff_operand. */
11165 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11169 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11171 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11175 op1 = pic_offset_table_rtx;
11180 op0 = pic_offset_table_rtx;
11184 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11189 (define_insn "*tablejump_1"
11190 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11191 (use (label_ref (match_operand 1 "" "")))]
11194 [(set_attr "type" "ibr")
11195 (set_attr "length_immediate" "0")])
11197 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11200 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11201 (set (match_operand:QI 1 "register_operand" "")
11202 (match_operator:QI 2 "ix86_comparison_operator"
11203 [(reg FLAGS_REG) (const_int 0)]))
11204 (set (match_operand 3 "q_regs_operand" "")
11205 (zero_extend (match_dup 1)))]
11206 "(peep2_reg_dead_p (3, operands[1])
11207 || operands_match_p (operands[1], operands[3]))
11208 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11209 [(set (match_dup 4) (match_dup 0))
11210 (set (strict_low_part (match_dup 5))
11213 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11214 operands[5] = gen_lowpart (QImode, operands[3]);
11215 ix86_expand_clear (operands[3]);
11218 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11221 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11222 (set (match_operand:QI 1 "register_operand" "")
11223 (match_operator:QI 2 "ix86_comparison_operator"
11224 [(reg FLAGS_REG) (const_int 0)]))
11225 (parallel [(set (match_operand 3 "q_regs_operand" "")
11226 (zero_extend (match_dup 1)))
11227 (clobber (reg:CC FLAGS_REG))])]
11228 "(peep2_reg_dead_p (3, operands[1])
11229 || operands_match_p (operands[1], operands[3]))
11230 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11231 [(set (match_dup 4) (match_dup 0))
11232 (set (strict_low_part (match_dup 5))
11235 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11236 operands[5] = gen_lowpart (QImode, operands[3]);
11237 ix86_expand_clear (operands[3]);
11240 ;; Call instructions.
11242 ;; The predicates normally associated with named expanders are not properly
11243 ;; checked for calls. This is a bug in the generic code, but it isn't that
11244 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11246 ;; P6 processors will jump to the address after the decrement when %esp
11247 ;; is used as a call operand, so they will execute return address as a code.
11248 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11250 ;; Call subroutine returning no value.
11252 (define_expand "call_pop"
11253 [(parallel [(call (match_operand:QI 0 "" "")
11254 (match_operand:SI 1 "" ""))
11255 (set (reg:SI SP_REG)
11256 (plus:SI (reg:SI SP_REG)
11257 (match_operand:SI 3 "" "")))])]
11260 ix86_expand_call (NULL, operands[0], operands[1],
11261 operands[2], operands[3], 0);
11265 (define_insn_and_split "*call_pop_0_vzeroupper"
11267 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11268 (match_operand:SI 1 "" ""))
11269 (set (reg:SI SP_REG)
11270 (plus:SI (reg:SI SP_REG)
11271 (match_operand:SI 2 "immediate_operand" "")))])
11272 (unspec [(match_operand 3 "const_int_operand" "")]
11273 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11274 "TARGET_VZEROUPPER && !TARGET_64BIT"
11276 "&& reload_completed"
11278 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11279 [(set_attr "type" "call")])
11281 (define_insn "*call_pop_0"
11282 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11283 (match_operand:SI 1 "" ""))
11284 (set (reg:SI SP_REG)
11285 (plus:SI (reg:SI SP_REG)
11286 (match_operand:SI 2 "immediate_operand" "")))]
11289 if (SIBLING_CALL_P (insn))
11292 return "call\t%P0";
11294 [(set_attr "type" "call")])
11296 (define_insn_and_split "*call_pop_1_vzeroupper"
11298 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11299 (match_operand:SI 1 "" ""))
11300 (set (reg:SI SP_REG)
11301 (plus:SI (reg:SI SP_REG)
11302 (match_operand:SI 2 "immediate_operand" "i")))])
11303 (unspec [(match_operand 3 "const_int_operand" "")]
11304 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11305 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11307 "&& reload_completed"
11309 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11310 [(set_attr "type" "call")])
11312 (define_insn "*call_pop_1"
11313 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11314 (match_operand:SI 1 "" ""))
11315 (set (reg:SI SP_REG)
11316 (plus:SI (reg:SI SP_REG)
11317 (match_operand:SI 2 "immediate_operand" "i")))]
11318 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11320 if (constant_call_address_operand (operands[0], Pmode))
11321 return "call\t%P0";
11322 return "call\t%A0";
11324 [(set_attr "type" "call")])
11326 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11328 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11329 (match_operand:SI 1 "" ""))
11330 (set (reg:SI SP_REG)
11331 (plus:SI (reg:SI SP_REG)
11332 (match_operand:SI 2 "immediate_operand" "i,i")))])
11333 (unspec [(match_operand 3 "const_int_operand" "")]
11334 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11335 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11337 "&& reload_completed"
11339 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11340 [(set_attr "type" "call")])
11342 (define_insn "*sibcall_pop_1"
11343 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11344 (match_operand:SI 1 "" ""))
11345 (set (reg:SI SP_REG)
11346 (plus:SI (reg:SI SP_REG)
11347 (match_operand:SI 2 "immediate_operand" "i,i")))]
11348 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11352 [(set_attr "type" "call")])
11354 (define_expand "call"
11355 [(call (match_operand:QI 0 "" "")
11356 (match_operand 1 "" ""))
11357 (use (match_operand 2 "" ""))]
11360 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11364 (define_expand "sibcall"
11365 [(call (match_operand:QI 0 "" "")
11366 (match_operand 1 "" ""))
11367 (use (match_operand 2 "" ""))]
11370 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11374 (define_insn_and_split "*call_0_vzeroupper"
11375 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11376 (match_operand 1 "" ""))
11377 (unspec [(match_operand 2 "const_int_operand" "")]
11378 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11379 "TARGET_VZEROUPPER"
11381 "&& reload_completed"
11383 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11384 [(set_attr "type" "call")])
11386 (define_insn "*call_0"
11387 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11388 (match_operand 1 "" ""))]
11390 { return ix86_output_call_insn (insn, operands[0], 0); }
11391 [(set_attr "type" "call")])
11393 (define_insn_and_split "*call_1_vzeroupper"
11394 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11395 (match_operand 1 "" ""))
11396 (unspec [(match_operand 2 "const_int_operand" "")]
11397 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11398 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11400 "&& reload_completed"
11402 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11403 [(set_attr "type" "call")])
11405 (define_insn "*call_1"
11406 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11407 (match_operand 1 "" ""))]
11408 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11409 { return ix86_output_call_insn (insn, operands[0], 0); }
11410 [(set_attr "type" "call")])
11412 (define_insn_and_split "*sibcall_1_vzeroupper"
11413 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11414 (match_operand 1 "" ""))
11415 (unspec [(match_operand 2 "const_int_operand" "")]
11416 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11417 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11419 "&& reload_completed"
11421 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11422 [(set_attr "type" "call")])
11424 (define_insn "*sibcall_1"
11425 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11426 (match_operand 1 "" ""))]
11427 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11428 { return ix86_output_call_insn (insn, operands[0], 0); }
11429 [(set_attr "type" "call")])
11431 (define_insn_and_split "*call_1_rex64_vzeroupper"
11432 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11433 (match_operand 1 "" ""))
11434 (unspec [(match_operand 2 "const_int_operand" "")]
11435 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11436 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11437 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11439 "&& reload_completed"
11441 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11442 [(set_attr "type" "call")])
11444 (define_insn "*call_1_rex64"
11445 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11446 (match_operand 1 "" ""))]
11447 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11448 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11449 { return ix86_output_call_insn (insn, operands[0], 0); }
11450 [(set_attr "type" "call")])
11452 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11454 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11455 (match_operand 1 "" ""))
11456 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11457 (clobber (reg:TI XMM6_REG))
11458 (clobber (reg:TI XMM7_REG))
11459 (clobber (reg:TI XMM8_REG))
11460 (clobber (reg:TI XMM9_REG))
11461 (clobber (reg:TI XMM10_REG))
11462 (clobber (reg:TI XMM11_REG))
11463 (clobber (reg:TI XMM12_REG))
11464 (clobber (reg:TI XMM13_REG))
11465 (clobber (reg:TI XMM14_REG))
11466 (clobber (reg:TI XMM15_REG))
11467 (clobber (reg:DI SI_REG))
11468 (clobber (reg:DI DI_REG))])
11469 (unspec [(match_operand 2 "const_int_operand" "")]
11470 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11471 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11473 "&& reload_completed"
11475 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11476 [(set_attr "type" "call")])
11478 (define_insn "*call_1_rex64_ms_sysv"
11479 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11480 (match_operand 1 "" ""))
11481 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11482 (clobber (reg:TI XMM6_REG))
11483 (clobber (reg:TI XMM7_REG))
11484 (clobber (reg:TI XMM8_REG))
11485 (clobber (reg:TI XMM9_REG))
11486 (clobber (reg:TI XMM10_REG))
11487 (clobber (reg:TI XMM11_REG))
11488 (clobber (reg:TI XMM12_REG))
11489 (clobber (reg:TI XMM13_REG))
11490 (clobber (reg:TI XMM14_REG))
11491 (clobber (reg:TI XMM15_REG))
11492 (clobber (reg:DI SI_REG))
11493 (clobber (reg:DI DI_REG))]
11494 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11495 { return ix86_output_call_insn (insn, operands[0], 0); }
11496 [(set_attr "type" "call")])
11498 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11499 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11500 (match_operand 1 "" ""))
11501 (unspec [(match_operand 2 "const_int_operand" "")]
11502 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11503 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11505 "&& reload_completed"
11507 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11508 [(set_attr "type" "call")])
11510 (define_insn "*call_1_rex64_large"
11511 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11512 (match_operand 1 "" ""))]
11513 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11514 { return ix86_output_call_insn (insn, operands[0], 0); }
11515 [(set_attr "type" "call")])
11517 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11518 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11519 (match_operand 1 "" ""))
11520 (unspec [(match_operand 2 "const_int_operand" "")]
11521 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11522 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11524 "&& reload_completed"
11526 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11527 [(set_attr "type" "call")])
11529 (define_insn "*sibcall_1_rex64"
11530 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11531 (match_operand 1 "" ""))]
11532 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11533 { return ix86_output_call_insn (insn, operands[0], 0); }
11534 [(set_attr "type" "call")])
11536 ;; Call subroutine, returning value in operand 0
11537 (define_expand "call_value_pop"
11538 [(parallel [(set (match_operand 0 "" "")
11539 (call (match_operand:QI 1 "" "")
11540 (match_operand:SI 2 "" "")))
11541 (set (reg:SI SP_REG)
11542 (plus:SI (reg:SI SP_REG)
11543 (match_operand:SI 4 "" "")))])]
11546 ix86_expand_call (operands[0], operands[1], operands[2],
11547 operands[3], operands[4], 0);
11551 (define_expand "call_value"
11552 [(set (match_operand 0 "" "")
11553 (call (match_operand:QI 1 "" "")
11554 (match_operand:SI 2 "" "")))
11555 (use (match_operand:SI 3 "" ""))]
11556 ;; Operand 3 is not used on the i386.
11559 ix86_expand_call (operands[0], operands[1], operands[2],
11560 operands[3], NULL, 0);
11564 (define_expand "sibcall_value"
11565 [(set (match_operand 0 "" "")
11566 (call (match_operand:QI 1 "" "")
11567 (match_operand:SI 2 "" "")))
11568 (use (match_operand:SI 3 "" ""))]
11569 ;; Operand 3 is not used on the i386.
11572 ix86_expand_call (operands[0], operands[1], operands[2],
11573 operands[3], NULL, 1);
11577 ;; Call subroutine returning any type.
11579 (define_expand "untyped_call"
11580 [(parallel [(call (match_operand 0 "" "")
11582 (match_operand 1 "" "")
11583 (match_operand 2 "" "")])]
11588 /* In order to give reg-stack an easier job in validating two
11589 coprocessor registers as containing a possible return value,
11590 simply pretend the untyped call returns a complex long double
11593 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11594 and should have the default ABI. */
11596 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11597 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11598 operands[0], const0_rtx,
11599 GEN_INT ((TARGET_64BIT
11600 ? (ix86_abi == SYSV_ABI
11601 ? X86_64_SSE_REGPARM_MAX
11602 : X86_64_MS_SSE_REGPARM_MAX)
11603 : X86_32_SSE_REGPARM_MAX)
11607 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11609 rtx set = XVECEXP (operands[2], 0, i);
11610 emit_move_insn (SET_DEST (set), SET_SRC (set));
11613 /* The optimizer does not know that the call sets the function value
11614 registers we stored in the result block. We avoid problems by
11615 claiming that all hard registers are used and clobbered at this
11617 emit_insn (gen_blockage ());
11622 ;; Prologue and epilogue instructions
11624 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11625 ;; all of memory. This blocks insns from being moved across this point.
11627 (define_insn "blockage"
11628 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11631 [(set_attr "length" "0")])
11633 ;; Do not schedule instructions accessing memory across this point.
11635 (define_expand "memory_blockage"
11636 [(set (match_dup 0)
11637 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11640 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11641 MEM_VOLATILE_P (operands[0]) = 1;
11644 (define_insn "*memory_blockage"
11645 [(set (match_operand:BLK 0 "" "")
11646 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11649 [(set_attr "length" "0")])
11651 ;; As USE insns aren't meaningful after reload, this is used instead
11652 ;; to prevent deleting instructions setting registers for PIC code
11653 (define_insn "prologue_use"
11654 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11657 [(set_attr "length" "0")])
11659 ;; Insn emitted into the body of a function to return from a function.
11660 ;; This is only done if the function's epilogue is known to be simple.
11661 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11663 (define_expand "return"
11665 "ix86_can_use_return_insn_p ()"
11667 if (crtl->args.pops_args)
11669 rtx popc = GEN_INT (crtl->args.pops_args);
11670 emit_jump_insn (gen_return_pop_internal (popc));
11675 (define_insn "return_internal"
11679 [(set_attr "length" "1")
11680 (set_attr "atom_unit" "jeu")
11681 (set_attr "length_immediate" "0")
11682 (set_attr "modrm" "0")])
11684 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11685 ;; instruction Athlon and K8 have.
11687 (define_insn "return_internal_long"
11689 (unspec [(const_int 0)] UNSPEC_REP)]
11692 [(set_attr "length" "2")
11693 (set_attr "atom_unit" "jeu")
11694 (set_attr "length_immediate" "0")
11695 (set_attr "prefix_rep" "1")
11696 (set_attr "modrm" "0")])
11698 (define_insn "return_pop_internal"
11700 (use (match_operand:SI 0 "const_int_operand" ""))]
11703 [(set_attr "length" "3")
11704 (set_attr "atom_unit" "jeu")
11705 (set_attr "length_immediate" "2")
11706 (set_attr "modrm" "0")])
11708 (define_insn "return_indirect_internal"
11710 (use (match_operand:SI 0 "register_operand" "r"))]
11713 [(set_attr "type" "ibr")
11714 (set_attr "length_immediate" "0")])
11720 [(set_attr "length" "1")
11721 (set_attr "length_immediate" "0")
11722 (set_attr "modrm" "0")])
11724 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11725 (define_insn "nops"
11726 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11730 int num = INTVAL (operands[0]);
11732 gcc_assert (num >= 1 && num <= 8);
11735 fputs ("\tnop\n", asm_out_file);
11739 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11740 (set_attr "length_immediate" "0")
11741 (set_attr "modrm" "0")])
11743 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11744 ;; branch prediction penalty for the third jump in a 16-byte
11748 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11751 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11752 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11754 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11755 The align insn is used to avoid 3 jump instructions in the row to improve
11756 branch prediction and the benefits hardly outweigh the cost of extra 8
11757 nops on the average inserted by full alignment pseudo operation. */
11761 [(set_attr "length" "16")])
11763 (define_expand "prologue"
11766 "ix86_expand_prologue (); DONE;")
11768 (define_insn "set_got"
11769 [(set (match_operand:SI 0 "register_operand" "=r")
11770 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11771 (clobber (reg:CC FLAGS_REG))]
11773 "* return output_set_got (operands[0], NULL_RTX);"
11774 [(set_attr "type" "multi")
11775 (set_attr "length" "12")])
11777 (define_insn "set_got_labelled"
11778 [(set (match_operand:SI 0 "register_operand" "=r")
11779 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11781 (clobber (reg:CC FLAGS_REG))]
11783 "* return output_set_got (operands[0], operands[1]);"
11784 [(set_attr "type" "multi")
11785 (set_attr "length" "12")])
11787 (define_insn "set_got_rex64"
11788 [(set (match_operand:DI 0 "register_operand" "=r")
11789 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11791 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11792 [(set_attr "type" "lea")
11793 (set_attr "length_address" "4")
11794 (set_attr "mode" "DI")])
11796 (define_insn "set_rip_rex64"
11797 [(set (match_operand:DI 0 "register_operand" "=r")
11798 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11800 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11801 [(set_attr "type" "lea")
11802 (set_attr "length_address" "4")
11803 (set_attr "mode" "DI")])
11805 (define_insn "set_got_offset_rex64"
11806 [(set (match_operand:DI 0 "register_operand" "=r")
11808 [(label_ref (match_operand 1 "" ""))]
11809 UNSPEC_SET_GOT_OFFSET))]
11811 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11812 [(set_attr "type" "imov")
11813 (set_attr "length_immediate" "0")
11814 (set_attr "length_address" "8")
11815 (set_attr "mode" "DI")])
11817 (define_expand "epilogue"
11820 "ix86_expand_epilogue (1); DONE;")
11822 (define_expand "sibcall_epilogue"
11825 "ix86_expand_epilogue (0); DONE;")
11827 (define_expand "eh_return"
11828 [(use (match_operand 0 "register_operand" ""))]
11831 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11833 /* Tricky bit: we write the address of the handler to which we will
11834 be returning into someone else's stack frame, one word below the
11835 stack address we wish to restore. */
11836 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11837 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11838 tmp = gen_rtx_MEM (Pmode, tmp);
11839 emit_move_insn (tmp, ra);
11841 emit_jump_insn (gen_eh_return_internal ());
11846 (define_insn_and_split "eh_return_internal"
11850 "epilogue_completed"
11852 "ix86_expand_epilogue (2); DONE;")
11854 (define_insn "leave"
11855 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11856 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11857 (clobber (mem:BLK (scratch)))]
11860 [(set_attr "type" "leave")])
11862 (define_insn "leave_rex64"
11863 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11864 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11865 (clobber (mem:BLK (scratch)))]
11868 [(set_attr "type" "leave")])
11870 ;; Handle -fsplit-stack.
11872 (define_expand "split_stack_prologue"
11876 ix86_expand_split_stack_prologue ();
11880 ;; In order to support the call/return predictor, we use a return
11881 ;; instruction which the middle-end doesn't see.
11882 (define_insn "split_stack_return"
11883 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11884 UNSPECV_SPLIT_STACK_RETURN)]
11887 if (operands[0] == const0_rtx)
11892 [(set_attr "atom_unit" "jeu")
11893 (set_attr "modrm" "0")
11894 (set (attr "length")
11895 (if_then_else (match_operand:SI 0 "const0_operand" "")
11898 (set (attr "length_immediate")
11899 (if_then_else (match_operand:SI 0 "const0_operand" "")
11903 ;; If there are operand 0 bytes available on the stack, jump to
11906 (define_expand "split_stack_space_check"
11907 [(set (pc) (if_then_else
11908 (ltu (minus (reg SP_REG)
11909 (match_operand 0 "register_operand" ""))
11910 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11911 (label_ref (match_operand 1 "" ""))
11915 rtx reg, size, limit;
11917 reg = gen_reg_rtx (Pmode);
11918 size = force_reg (Pmode, operands[0]);
11919 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11920 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11921 UNSPEC_STACK_CHECK);
11922 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11923 ix86_expand_branch (GEU, reg, limit, operands[1]);
11928 ;; Bit manipulation instructions.
11930 (define_expand "ffs<mode>2"
11931 [(set (match_dup 2) (const_int -1))
11932 (parallel [(set (reg:CCZ FLAGS_REG)
11934 (match_operand:SWI48 1 "nonimmediate_operand" "")
11936 (set (match_operand:SWI48 0 "register_operand" "")
11937 (ctz:SWI48 (match_dup 1)))])
11938 (set (match_dup 0) (if_then_else:SWI48
11939 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11942 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11943 (clobber (reg:CC FLAGS_REG))])]
11946 if (<MODE>mode == SImode && !TARGET_CMOVE)
11948 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11951 operands[2] = gen_reg_rtx (<MODE>mode);
11954 (define_insn_and_split "ffssi2_no_cmove"
11955 [(set (match_operand:SI 0 "register_operand" "=r")
11956 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11957 (clobber (match_scratch:SI 2 "=&q"))
11958 (clobber (reg:CC FLAGS_REG))]
11961 "&& reload_completed"
11962 [(parallel [(set (reg:CCZ FLAGS_REG)
11963 (compare:CCZ (match_dup 1) (const_int 0)))
11964 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11965 (set (strict_low_part (match_dup 3))
11966 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11967 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11968 (clobber (reg:CC FLAGS_REG))])
11969 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11970 (clobber (reg:CC FLAGS_REG))])
11971 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11972 (clobber (reg:CC FLAGS_REG))])]
11974 operands[3] = gen_lowpart (QImode, operands[2]);
11975 ix86_expand_clear (operands[2]);
11978 (define_insn "*ffs<mode>_1"
11979 [(set (reg:CCZ FLAGS_REG)
11980 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11982 (set (match_operand:SWI48 0 "register_operand" "=r")
11983 (ctz:SWI48 (match_dup 1)))]
11985 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11986 [(set_attr "type" "alu1")
11987 (set_attr "prefix_0f" "1")
11988 (set_attr "mode" "<MODE>")])
11990 (define_insn "ctz<mode>2"
11991 [(set (match_operand:SWI48 0 "register_operand" "=r")
11992 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11993 (clobber (reg:CC FLAGS_REG))]
11995 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11996 [(set_attr "type" "alu1")
11997 (set_attr "prefix_0f" "1")
11998 (set_attr "mode" "<MODE>")])
12000 (define_expand "clz<mode>2"
12002 [(set (match_operand:SWI248 0 "register_operand" "")
12005 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12006 (clobber (reg:CC FLAGS_REG))])
12008 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12009 (clobber (reg:CC FLAGS_REG))])]
12014 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12017 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12020 (define_insn "clz<mode>2_abm"
12021 [(set (match_operand:SWI248 0 "register_operand" "=r")
12022 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12023 (clobber (reg:CC FLAGS_REG))]
12025 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12026 [(set_attr "prefix_rep" "1")
12027 (set_attr "type" "bitmanip")
12028 (set_attr "mode" "<MODE>")])
12030 (define_insn "bsr_rex64"
12031 [(set (match_operand:DI 0 "register_operand" "=r")
12032 (minus:DI (const_int 63)
12033 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12034 (clobber (reg:CC FLAGS_REG))]
12036 "bsr{q}\t{%1, %0|%0, %1}"
12037 [(set_attr "type" "alu1")
12038 (set_attr "prefix_0f" "1")
12039 (set_attr "mode" "DI")])
12042 [(set (match_operand:SI 0 "register_operand" "=r")
12043 (minus:SI (const_int 31)
12044 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12045 (clobber (reg:CC FLAGS_REG))]
12047 "bsr{l}\t{%1, %0|%0, %1}"
12048 [(set_attr "type" "alu1")
12049 (set_attr "prefix_0f" "1")
12050 (set_attr "mode" "SI")])
12052 (define_insn "*bsrhi"
12053 [(set (match_operand:HI 0 "register_operand" "=r")
12054 (minus:HI (const_int 15)
12055 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12056 (clobber (reg:CC FLAGS_REG))]
12058 "bsr{w}\t{%1, %0|%0, %1}"
12059 [(set_attr "type" "alu1")
12060 (set_attr "prefix_0f" "1")
12061 (set_attr "mode" "HI")])
12063 (define_insn "popcount<mode>2"
12064 [(set (match_operand:SWI248 0 "register_operand" "=r")
12066 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12067 (clobber (reg:CC FLAGS_REG))]
12071 return "popcnt\t{%1, %0|%0, %1}";
12073 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12076 [(set_attr "prefix_rep" "1")
12077 (set_attr "type" "bitmanip")
12078 (set_attr "mode" "<MODE>")])
12080 (define_insn "*popcount<mode>2_cmp"
12081 [(set (reg FLAGS_REG)
12084 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12086 (set (match_operand:SWI248 0 "register_operand" "=r")
12087 (popcount:SWI248 (match_dup 1)))]
12088 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12091 return "popcnt\t{%1, %0|%0, %1}";
12093 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12096 [(set_attr "prefix_rep" "1")
12097 (set_attr "type" "bitmanip")
12098 (set_attr "mode" "<MODE>")])
12100 (define_insn "*popcountsi2_cmp_zext"
12101 [(set (reg FLAGS_REG)
12103 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12105 (set (match_operand:DI 0 "register_operand" "=r")
12106 (zero_extend:DI(popcount:SI (match_dup 1))))]
12107 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12110 return "popcnt\t{%1, %0|%0, %1}";
12112 return "popcnt{l}\t{%1, %0|%0, %1}";
12115 [(set_attr "prefix_rep" "1")
12116 (set_attr "type" "bitmanip")
12117 (set_attr "mode" "SI")])
12119 (define_expand "bswap<mode>2"
12120 [(set (match_operand:SWI48 0 "register_operand" "")
12121 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12124 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12126 rtx x = operands[0];
12128 emit_move_insn (x, operands[1]);
12129 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12130 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12131 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12136 (define_insn "*bswap<mode>2_movbe"
12137 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12138 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12140 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12143 movbe\t{%1, %0|%0, %1}
12144 movbe\t{%1, %0|%0, %1}"
12145 [(set_attr "type" "bitmanip,imov,imov")
12146 (set_attr "modrm" "0,1,1")
12147 (set_attr "prefix_0f" "*,1,1")
12148 (set_attr "prefix_extra" "*,1,1")
12149 (set_attr "mode" "<MODE>")])
12151 (define_insn "*bswap<mode>2_1"
12152 [(set (match_operand:SWI48 0 "register_operand" "=r")
12153 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12156 [(set_attr "type" "bitmanip")
12157 (set_attr "modrm" "0")
12158 (set_attr "mode" "<MODE>")])
12160 (define_insn "*bswaphi_lowpart_1"
12161 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12162 (bswap:HI (match_dup 0)))
12163 (clobber (reg:CC FLAGS_REG))]
12164 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12166 xchg{b}\t{%h0, %b0|%b0, %h0}
12167 rol{w}\t{$8, %0|%0, 8}"
12168 [(set_attr "length" "2,4")
12169 (set_attr "mode" "QI,HI")])
12171 (define_insn "bswaphi_lowpart"
12172 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12173 (bswap:HI (match_dup 0)))
12174 (clobber (reg:CC FLAGS_REG))]
12176 "rol{w}\t{$8, %0|%0, 8}"
12177 [(set_attr "length" "4")
12178 (set_attr "mode" "HI")])
12180 (define_expand "paritydi2"
12181 [(set (match_operand:DI 0 "register_operand" "")
12182 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12185 rtx scratch = gen_reg_rtx (QImode);
12188 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12189 NULL_RTX, operands[1]));
12191 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12192 gen_rtx_REG (CCmode, FLAGS_REG),
12194 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12197 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12200 rtx tmp = gen_reg_rtx (SImode);
12202 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12203 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12208 (define_expand "paritysi2"
12209 [(set (match_operand:SI 0 "register_operand" "")
12210 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12213 rtx scratch = gen_reg_rtx (QImode);
12216 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12218 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12219 gen_rtx_REG (CCmode, FLAGS_REG),
12221 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12223 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12227 (define_insn_and_split "paritydi2_cmp"
12228 [(set (reg:CC FLAGS_REG)
12229 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12231 (clobber (match_scratch:DI 0 "=r"))
12232 (clobber (match_scratch:SI 1 "=&r"))
12233 (clobber (match_scratch:HI 2 "=Q"))]
12236 "&& reload_completed"
12238 [(set (match_dup 1)
12239 (xor:SI (match_dup 1) (match_dup 4)))
12240 (clobber (reg:CC FLAGS_REG))])
12242 [(set (reg:CC FLAGS_REG)
12243 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12244 (clobber (match_dup 1))
12245 (clobber (match_dup 2))])]
12247 operands[4] = gen_lowpart (SImode, operands[3]);
12251 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12252 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12255 operands[1] = gen_highpart (SImode, operands[3]);
12258 (define_insn_and_split "paritysi2_cmp"
12259 [(set (reg:CC FLAGS_REG)
12260 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12262 (clobber (match_scratch:SI 0 "=r"))
12263 (clobber (match_scratch:HI 1 "=&Q"))]
12266 "&& reload_completed"
12268 [(set (match_dup 1)
12269 (xor:HI (match_dup 1) (match_dup 3)))
12270 (clobber (reg:CC FLAGS_REG))])
12272 [(set (reg:CC FLAGS_REG)
12273 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12274 (clobber (match_dup 1))])]
12276 operands[3] = gen_lowpart (HImode, operands[2]);
12278 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12279 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12282 (define_insn "*parityhi2_cmp"
12283 [(set (reg:CC FLAGS_REG)
12284 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12286 (clobber (match_scratch:HI 0 "=Q"))]
12288 "xor{b}\t{%h0, %b0|%b0, %h0}"
12289 [(set_attr "length" "2")
12290 (set_attr "mode" "HI")])
12292 ;; Thread-local storage patterns for ELF.
12294 ;; Note that these code sequences must appear exactly as shown
12295 ;; in order to allow linker relaxation.
12297 (define_insn "*tls_global_dynamic_32_gnu"
12298 [(set (match_operand:SI 0 "register_operand" "=a")
12299 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12300 (match_operand:SI 2 "tls_symbolic_operand" "")
12301 (match_operand:SI 3 "call_insn_operand" "")]
12303 (clobber (match_scratch:SI 4 "=d"))
12304 (clobber (match_scratch:SI 5 "=c"))
12305 (clobber (reg:CC FLAGS_REG))]
12306 "!TARGET_64BIT && TARGET_GNU_TLS"
12307 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12308 [(set_attr "type" "multi")
12309 (set_attr "length" "12")])
12311 (define_expand "tls_global_dynamic_32"
12312 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12315 (match_operand:SI 1 "tls_symbolic_operand" "")
12318 (clobber (match_scratch:SI 4 ""))
12319 (clobber (match_scratch:SI 5 ""))
12320 (clobber (reg:CC FLAGS_REG))])]
12324 operands[2] = pic_offset_table_rtx;
12327 operands[2] = gen_reg_rtx (Pmode);
12328 emit_insn (gen_set_got (operands[2]));
12330 if (TARGET_GNU2_TLS)
12332 emit_insn (gen_tls_dynamic_gnu2_32
12333 (operands[0], operands[1], operands[2]));
12336 operands[3] = ix86_tls_get_addr ();
12339 (define_insn "*tls_global_dynamic_64"
12340 [(set (match_operand:DI 0 "register_operand" "=a")
12341 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12342 (match_operand:DI 3 "" "")))
12343 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12346 { 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"; }
12347 [(set_attr "type" "multi")
12348 (set_attr "length" "16")])
12350 (define_expand "tls_global_dynamic_64"
12351 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12352 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12353 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12357 if (TARGET_GNU2_TLS)
12359 emit_insn (gen_tls_dynamic_gnu2_64
12360 (operands[0], operands[1]));
12363 operands[2] = ix86_tls_get_addr ();
12366 (define_insn "*tls_local_dynamic_base_32_gnu"
12367 [(set (match_operand:SI 0 "register_operand" "=a")
12368 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12369 (match_operand:SI 2 "call_insn_operand" "")]
12370 UNSPEC_TLS_LD_BASE))
12371 (clobber (match_scratch:SI 3 "=d"))
12372 (clobber (match_scratch:SI 4 "=c"))
12373 (clobber (reg:CC FLAGS_REG))]
12374 "!TARGET_64BIT && TARGET_GNU_TLS"
12375 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12376 [(set_attr "type" "multi")
12377 (set_attr "length" "11")])
12379 (define_expand "tls_local_dynamic_base_32"
12380 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12381 (unspec:SI [(match_dup 1) (match_dup 2)]
12382 UNSPEC_TLS_LD_BASE))
12383 (clobber (match_scratch:SI 3 ""))
12384 (clobber (match_scratch:SI 4 ""))
12385 (clobber (reg:CC FLAGS_REG))])]
12389 operands[1] = pic_offset_table_rtx;
12392 operands[1] = gen_reg_rtx (Pmode);
12393 emit_insn (gen_set_got (operands[1]));
12395 if (TARGET_GNU2_TLS)
12397 emit_insn (gen_tls_dynamic_gnu2_32
12398 (operands[0], ix86_tls_module_base (), operands[1]));
12401 operands[2] = ix86_tls_get_addr ();
12404 (define_insn "*tls_local_dynamic_base_64"
12405 [(set (match_operand:DI 0 "register_operand" "=a")
12406 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12407 (match_operand:DI 2 "" "")))
12408 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12410 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12411 [(set_attr "type" "multi")
12412 (set_attr "length" "12")])
12414 (define_expand "tls_local_dynamic_base_64"
12415 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12416 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12417 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12420 if (TARGET_GNU2_TLS)
12422 emit_insn (gen_tls_dynamic_gnu2_64
12423 (operands[0], ix86_tls_module_base ()));
12426 operands[1] = ix86_tls_get_addr ();
12429 ;; Local dynamic of a single variable is a lose. Show combine how
12430 ;; to convert that back to global dynamic.
12432 (define_insn_and_split "*tls_local_dynamic_32_once"
12433 [(set (match_operand:SI 0 "register_operand" "=a")
12434 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12435 (match_operand:SI 2 "call_insn_operand" "")]
12436 UNSPEC_TLS_LD_BASE)
12437 (const:SI (unspec:SI
12438 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12440 (clobber (match_scratch:SI 4 "=d"))
12441 (clobber (match_scratch:SI 5 "=c"))
12442 (clobber (reg:CC FLAGS_REG))]
12446 [(parallel [(set (match_dup 0)
12447 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12449 (clobber (match_dup 4))
12450 (clobber (match_dup 5))
12451 (clobber (reg:CC FLAGS_REG))])])
12453 ;; Segment register for the thread base ptr load
12454 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12456 ;; Load and add the thread base pointer from %gs:0.
12457 (define_insn "*load_tp_<mode>"
12458 [(set (match_operand:P 0 "register_operand" "=r")
12459 (unspec:P [(const_int 0)] UNSPEC_TP))]
12461 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12462 [(set_attr "type" "imov")
12463 (set_attr "modrm" "0")
12464 (set_attr "length" "7")
12465 (set_attr "memory" "load")
12466 (set_attr "imm_disp" "false")])
12468 (define_insn "*add_tp_<mode>"
12469 [(set (match_operand:P 0 "register_operand" "=r")
12470 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12471 (match_operand:P 1 "register_operand" "0")))
12472 (clobber (reg:CC FLAGS_REG))]
12474 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12475 [(set_attr "type" "alu")
12476 (set_attr "modrm" "0")
12477 (set_attr "length" "7")
12478 (set_attr "memory" "load")
12479 (set_attr "imm_disp" "false")])
12481 ;; GNU2 TLS patterns can be split.
12483 (define_expand "tls_dynamic_gnu2_32"
12484 [(set (match_dup 3)
12485 (plus:SI (match_operand:SI 2 "register_operand" "")
12487 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12490 [(set (match_operand:SI 0 "register_operand" "")
12491 (unspec:SI [(match_dup 1) (match_dup 3)
12492 (match_dup 2) (reg:SI SP_REG)]
12494 (clobber (reg:CC FLAGS_REG))])]
12495 "!TARGET_64BIT && TARGET_GNU2_TLS"
12497 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12498 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12501 (define_insn "*tls_dynamic_lea_32"
12502 [(set (match_operand:SI 0 "register_operand" "=r")
12503 (plus:SI (match_operand:SI 1 "register_operand" "b")
12505 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12506 UNSPEC_TLSDESC))))]
12507 "!TARGET_64BIT && TARGET_GNU2_TLS"
12508 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12509 [(set_attr "type" "lea")
12510 (set_attr "mode" "SI")
12511 (set_attr "length" "6")
12512 (set_attr "length_address" "4")])
12514 (define_insn "*tls_dynamic_call_32"
12515 [(set (match_operand:SI 0 "register_operand" "=a")
12516 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12517 (match_operand:SI 2 "register_operand" "0")
12518 ;; we have to make sure %ebx still points to the GOT
12519 (match_operand:SI 3 "register_operand" "b")
12522 (clobber (reg:CC FLAGS_REG))]
12523 "!TARGET_64BIT && TARGET_GNU2_TLS"
12524 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12525 [(set_attr "type" "call")
12526 (set_attr "length" "2")
12527 (set_attr "length_address" "0")])
12529 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12530 [(set (match_operand:SI 0 "register_operand" "=&a")
12532 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12533 (match_operand:SI 4 "" "")
12534 (match_operand:SI 2 "register_operand" "b")
12537 (const:SI (unspec:SI
12538 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12540 (clobber (reg:CC FLAGS_REG))]
12541 "!TARGET_64BIT && TARGET_GNU2_TLS"
12544 [(set (match_dup 0) (match_dup 5))]
12546 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12547 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12550 (define_expand "tls_dynamic_gnu2_64"
12551 [(set (match_dup 2)
12552 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12555 [(set (match_operand:DI 0 "register_operand" "")
12556 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12558 (clobber (reg:CC FLAGS_REG))])]
12559 "TARGET_64BIT && TARGET_GNU2_TLS"
12561 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12562 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12565 (define_insn "*tls_dynamic_lea_64"
12566 [(set (match_operand:DI 0 "register_operand" "=r")
12567 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12569 "TARGET_64BIT && TARGET_GNU2_TLS"
12570 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12571 [(set_attr "type" "lea")
12572 (set_attr "mode" "DI")
12573 (set_attr "length" "7")
12574 (set_attr "length_address" "4")])
12576 (define_insn "*tls_dynamic_call_64"
12577 [(set (match_operand:DI 0 "register_operand" "=a")
12578 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12579 (match_operand:DI 2 "register_operand" "0")
12582 (clobber (reg:CC FLAGS_REG))]
12583 "TARGET_64BIT && TARGET_GNU2_TLS"
12584 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12585 [(set_attr "type" "call")
12586 (set_attr "length" "2")
12587 (set_attr "length_address" "0")])
12589 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12590 [(set (match_operand:DI 0 "register_operand" "=&a")
12592 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12593 (match_operand:DI 3 "" "")
12596 (const:DI (unspec:DI
12597 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12599 (clobber (reg:CC FLAGS_REG))]
12600 "TARGET_64BIT && TARGET_GNU2_TLS"
12603 [(set (match_dup 0) (match_dup 4))]
12605 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12606 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12609 ;; These patterns match the binary 387 instructions for addM3, subM3,
12610 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12611 ;; SFmode. The first is the normal insn, the second the same insn but
12612 ;; with one operand a conversion, and the third the same insn but with
12613 ;; the other operand a conversion. The conversion may be SFmode or
12614 ;; SImode if the target mode DFmode, but only SImode if the target mode
12617 ;; Gcc is slightly more smart about handling normal two address instructions
12618 ;; so use special patterns for add and mull.
12620 (define_insn "*fop_<mode>_comm_mixed_avx"
12621 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12622 (match_operator:MODEF 3 "binary_fp_operator"
12623 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12624 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12625 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12626 && COMMUTATIVE_ARITH_P (operands[3])
12627 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12628 "* return output_387_binary_op (insn, operands);"
12629 [(set (attr "type")
12630 (if_then_else (eq_attr "alternative" "1")
12631 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12632 (const_string "ssemul")
12633 (const_string "sseadd"))
12634 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12635 (const_string "fmul")
12636 (const_string "fop"))))
12637 (set_attr "prefix" "orig,maybe_vex")
12638 (set_attr "mode" "<MODE>")])
12640 (define_insn "*fop_<mode>_comm_mixed"
12641 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12642 (match_operator:MODEF 3 "binary_fp_operator"
12643 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12644 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12645 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12646 && COMMUTATIVE_ARITH_P (operands[3])
12647 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12648 "* return output_387_binary_op (insn, operands);"
12649 [(set (attr "type")
12650 (if_then_else (eq_attr "alternative" "1")
12651 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12652 (const_string "ssemul")
12653 (const_string "sseadd"))
12654 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12655 (const_string "fmul")
12656 (const_string "fop"))))
12657 (set_attr "mode" "<MODE>")])
12659 (define_insn "*fop_<mode>_comm_avx"
12660 [(set (match_operand:MODEF 0 "register_operand" "=x")
12661 (match_operator:MODEF 3 "binary_fp_operator"
12662 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12663 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12664 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12665 && COMMUTATIVE_ARITH_P (operands[3])
12666 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12667 "* return output_387_binary_op (insn, operands);"
12668 [(set (attr "type")
12669 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12670 (const_string "ssemul")
12671 (const_string "sseadd")))
12672 (set_attr "prefix" "vex")
12673 (set_attr "mode" "<MODE>")])
12675 (define_insn "*fop_<mode>_comm_sse"
12676 [(set (match_operand:MODEF 0 "register_operand" "=x")
12677 (match_operator:MODEF 3 "binary_fp_operator"
12678 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12679 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12680 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12681 && COMMUTATIVE_ARITH_P (operands[3])
12682 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12683 "* return output_387_binary_op (insn, operands);"
12684 [(set (attr "type")
12685 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12686 (const_string "ssemul")
12687 (const_string "sseadd")))
12688 (set_attr "mode" "<MODE>")])
12690 (define_insn "*fop_<mode>_comm_i387"
12691 [(set (match_operand:MODEF 0 "register_operand" "=f")
12692 (match_operator:MODEF 3 "binary_fp_operator"
12693 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12694 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12695 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12696 && COMMUTATIVE_ARITH_P (operands[3])
12697 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12698 "* return output_387_binary_op (insn, operands);"
12699 [(set (attr "type")
12700 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12701 (const_string "fmul")
12702 (const_string "fop")))
12703 (set_attr "mode" "<MODE>")])
12705 (define_insn "*fop_<mode>_1_mixed_avx"
12706 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12707 (match_operator:MODEF 3 "binary_fp_operator"
12708 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12709 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12710 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12711 && !COMMUTATIVE_ARITH_P (operands[3])
12712 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12713 "* return output_387_binary_op (insn, operands);"
12714 [(set (attr "type")
12715 (cond [(and (eq_attr "alternative" "2")
12716 (match_operand:MODEF 3 "mult_operator" ""))
12717 (const_string "ssemul")
12718 (and (eq_attr "alternative" "2")
12719 (match_operand:MODEF 3 "div_operator" ""))
12720 (const_string "ssediv")
12721 (eq_attr "alternative" "2")
12722 (const_string "sseadd")
12723 (match_operand:MODEF 3 "mult_operator" "")
12724 (const_string "fmul")
12725 (match_operand:MODEF 3 "div_operator" "")
12726 (const_string "fdiv")
12728 (const_string "fop")))
12729 (set_attr "prefix" "orig,orig,maybe_vex")
12730 (set_attr "mode" "<MODE>")])
12732 (define_insn "*fop_<mode>_1_mixed"
12733 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12734 (match_operator:MODEF 3 "binary_fp_operator"
12735 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12736 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12737 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12738 && !COMMUTATIVE_ARITH_P (operands[3])
12739 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12740 "* return output_387_binary_op (insn, operands);"
12741 [(set (attr "type")
12742 (cond [(and (eq_attr "alternative" "2")
12743 (match_operand:MODEF 3 "mult_operator" ""))
12744 (const_string "ssemul")
12745 (and (eq_attr "alternative" "2")
12746 (match_operand:MODEF 3 "div_operator" ""))
12747 (const_string "ssediv")
12748 (eq_attr "alternative" "2")
12749 (const_string "sseadd")
12750 (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 "mode" "<MODE>")])
12758 (define_insn "*rcpsf2_sse"
12759 [(set (match_operand:SF 0 "register_operand" "=x")
12760 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12763 "%vrcpss\t{%1, %d0|%d0, %1}"
12764 [(set_attr "type" "sse")
12765 (set_attr "atom_sse_attr" "rcp")
12766 (set_attr "prefix" "maybe_vex")
12767 (set_attr "mode" "SF")])
12769 (define_insn "*fop_<mode>_1_avx"
12770 [(set (match_operand:MODEF 0 "register_operand" "=x")
12771 (match_operator:MODEF 3 "binary_fp_operator"
12772 [(match_operand:MODEF 1 "register_operand" "x")
12773 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12774 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12775 && !COMMUTATIVE_ARITH_P (operands[3])"
12776 "* return output_387_binary_op (insn, operands);"
12777 [(set (attr "type")
12778 (cond [(match_operand:MODEF 3 "mult_operator" "")
12779 (const_string "ssemul")
12780 (match_operand:MODEF 3 "div_operator" "")
12781 (const_string "ssediv")
12783 (const_string "sseadd")))
12784 (set_attr "prefix" "vex")
12785 (set_attr "mode" "<MODE>")])
12787 (define_insn "*fop_<mode>_1_sse"
12788 [(set (match_operand:MODEF 0 "register_operand" "=x")
12789 (match_operator:MODEF 3 "binary_fp_operator"
12790 [(match_operand:MODEF 1 "register_operand" "0")
12791 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12792 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12793 && !COMMUTATIVE_ARITH_P (operands[3])"
12794 "* return output_387_binary_op (insn, operands);"
12795 [(set (attr "type")
12796 (cond [(match_operand:MODEF 3 "mult_operator" "")
12797 (const_string "ssemul")
12798 (match_operand:MODEF 3 "div_operator" "")
12799 (const_string "ssediv")
12801 (const_string "sseadd")))
12802 (set_attr "mode" "<MODE>")])
12804 ;; This pattern is not fully shadowed by the pattern above.
12805 (define_insn "*fop_<mode>_1_i387"
12806 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12807 (match_operator:MODEF 3 "binary_fp_operator"
12808 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12809 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12810 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12811 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12812 && !COMMUTATIVE_ARITH_P (operands[3])
12813 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12814 "* return output_387_binary_op (insn, operands);"
12815 [(set (attr "type")
12816 (cond [(match_operand:MODEF 3 "mult_operator" "")
12817 (const_string "fmul")
12818 (match_operand:MODEF 3 "div_operator" "")
12819 (const_string "fdiv")
12821 (const_string "fop")))
12822 (set_attr "mode" "<MODE>")])
12824 ;; ??? Add SSE splitters for these!
12825 (define_insn "*fop_<MODEF:mode>_2_i387"
12826 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12827 (match_operator:MODEF 3 "binary_fp_operator"
12829 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12830 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12831 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12832 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12833 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12834 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12835 [(set (attr "type")
12836 (cond [(match_operand:MODEF 3 "mult_operator" "")
12837 (const_string "fmul")
12838 (match_operand:MODEF 3 "div_operator" "")
12839 (const_string "fdiv")
12841 (const_string "fop")))
12842 (set_attr "fp_int_src" "true")
12843 (set_attr "mode" "<X87MODEI12:MODE>")])
12845 (define_insn "*fop_<MODEF:mode>_3_i387"
12846 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12847 (match_operator:MODEF 3 "binary_fp_operator"
12848 [(match_operand:MODEF 1 "register_operand" "0,0")
12850 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12851 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12852 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12853 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12854 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12855 [(set (attr "type")
12856 (cond [(match_operand:MODEF 3 "mult_operator" "")
12857 (const_string "fmul")
12858 (match_operand:MODEF 3 "div_operator" "")
12859 (const_string "fdiv")
12861 (const_string "fop")))
12862 (set_attr "fp_int_src" "true")
12863 (set_attr "mode" "<MODE>")])
12865 (define_insn "*fop_df_4_i387"
12866 [(set (match_operand:DF 0 "register_operand" "=f,f")
12867 (match_operator:DF 3 "binary_fp_operator"
12869 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12870 (match_operand:DF 2 "register_operand" "0,f")]))]
12871 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12872 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12873 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12874 "* return output_387_binary_op (insn, operands);"
12875 [(set (attr "type")
12876 (cond [(match_operand:DF 3 "mult_operator" "")
12877 (const_string "fmul")
12878 (match_operand:DF 3 "div_operator" "")
12879 (const_string "fdiv")
12881 (const_string "fop")))
12882 (set_attr "mode" "SF")])
12884 (define_insn "*fop_df_5_i387"
12885 [(set (match_operand:DF 0 "register_operand" "=f,f")
12886 (match_operator:DF 3 "binary_fp_operator"
12887 [(match_operand:DF 1 "register_operand" "0,f")
12889 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12890 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12891 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12892 "* return output_387_binary_op (insn, operands);"
12893 [(set (attr "type")
12894 (cond [(match_operand:DF 3 "mult_operator" "")
12895 (const_string "fmul")
12896 (match_operand:DF 3 "div_operator" "")
12897 (const_string "fdiv")
12899 (const_string "fop")))
12900 (set_attr "mode" "SF")])
12902 (define_insn "*fop_df_6_i387"
12903 [(set (match_operand:DF 0 "register_operand" "=f,f")
12904 (match_operator:DF 3 "binary_fp_operator"
12906 (match_operand:SF 1 "register_operand" "0,f"))
12908 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12909 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12910 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12911 "* return output_387_binary_op (insn, operands);"
12912 [(set (attr "type")
12913 (cond [(match_operand:DF 3 "mult_operator" "")
12914 (const_string "fmul")
12915 (match_operand:DF 3 "div_operator" "")
12916 (const_string "fdiv")
12918 (const_string "fop")))
12919 (set_attr "mode" "SF")])
12921 (define_insn "*fop_xf_comm_i387"
12922 [(set (match_operand:XF 0 "register_operand" "=f")
12923 (match_operator:XF 3 "binary_fp_operator"
12924 [(match_operand:XF 1 "register_operand" "%0")
12925 (match_operand:XF 2 "register_operand" "f")]))]
12927 && COMMUTATIVE_ARITH_P (operands[3])"
12928 "* return output_387_binary_op (insn, operands);"
12929 [(set (attr "type")
12930 (if_then_else (match_operand:XF 3 "mult_operator" "")
12931 (const_string "fmul")
12932 (const_string "fop")))
12933 (set_attr "mode" "XF")])
12935 (define_insn "*fop_xf_1_i387"
12936 [(set (match_operand:XF 0 "register_operand" "=f,f")
12937 (match_operator:XF 3 "binary_fp_operator"
12938 [(match_operand:XF 1 "register_operand" "0,f")
12939 (match_operand:XF 2 "register_operand" "f,0")]))]
12941 && !COMMUTATIVE_ARITH_P (operands[3])"
12942 "* return output_387_binary_op (insn, operands);"
12943 [(set (attr "type")
12944 (cond [(match_operand:XF 3 "mult_operator" "")
12945 (const_string "fmul")
12946 (match_operand:XF 3 "div_operator" "")
12947 (const_string "fdiv")
12949 (const_string "fop")))
12950 (set_attr "mode" "XF")])
12952 (define_insn "*fop_xf_2_i387"
12953 [(set (match_operand:XF 0 "register_operand" "=f,f")
12954 (match_operator:XF 3 "binary_fp_operator"
12956 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12957 (match_operand:XF 2 "register_operand" "0,0")]))]
12958 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12959 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12960 [(set (attr "type")
12961 (cond [(match_operand:XF 3 "mult_operator" "")
12962 (const_string "fmul")
12963 (match_operand:XF 3 "div_operator" "")
12964 (const_string "fdiv")
12966 (const_string "fop")))
12967 (set_attr "fp_int_src" "true")
12968 (set_attr "mode" "<MODE>")])
12970 (define_insn "*fop_xf_3_i387"
12971 [(set (match_operand:XF 0 "register_operand" "=f,f")
12972 (match_operator:XF 3 "binary_fp_operator"
12973 [(match_operand:XF 1 "register_operand" "0,0")
12975 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12976 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12977 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12978 [(set (attr "type")
12979 (cond [(match_operand:XF 3 "mult_operator" "")
12980 (const_string "fmul")
12981 (match_operand:XF 3 "div_operator" "")
12982 (const_string "fdiv")
12984 (const_string "fop")))
12985 (set_attr "fp_int_src" "true")
12986 (set_attr "mode" "<MODE>")])
12988 (define_insn "*fop_xf_4_i387"
12989 [(set (match_operand:XF 0 "register_operand" "=f,f")
12990 (match_operator:XF 3 "binary_fp_operator"
12992 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12993 (match_operand:XF 2 "register_operand" "0,f")]))]
12995 "* return output_387_binary_op (insn, operands);"
12996 [(set (attr "type")
12997 (cond [(match_operand:XF 3 "mult_operator" "")
12998 (const_string "fmul")
12999 (match_operand:XF 3 "div_operator" "")
13000 (const_string "fdiv")
13002 (const_string "fop")))
13003 (set_attr "mode" "<MODE>")])
13005 (define_insn "*fop_xf_5_i387"
13006 [(set (match_operand:XF 0 "register_operand" "=f,f")
13007 (match_operator:XF 3 "binary_fp_operator"
13008 [(match_operand:XF 1 "register_operand" "0,f")
13010 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13012 "* return output_387_binary_op (insn, operands);"
13013 [(set (attr "type")
13014 (cond [(match_operand:XF 3 "mult_operator" "")
13015 (const_string "fmul")
13016 (match_operand:XF 3 "div_operator" "")
13017 (const_string "fdiv")
13019 (const_string "fop")))
13020 (set_attr "mode" "<MODE>")])
13022 (define_insn "*fop_xf_6_i387"
13023 [(set (match_operand:XF 0 "register_operand" "=f,f")
13024 (match_operator:XF 3 "binary_fp_operator"
13026 (match_operand:MODEF 1 "register_operand" "0,f"))
13028 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13030 "* return output_387_binary_op (insn, operands);"
13031 [(set (attr "type")
13032 (cond [(match_operand:XF 3 "mult_operator" "")
13033 (const_string "fmul")
13034 (match_operand:XF 3 "div_operator" "")
13035 (const_string "fdiv")
13037 (const_string "fop")))
13038 (set_attr "mode" "<MODE>")])
13041 [(set (match_operand 0 "register_operand" "")
13042 (match_operator 3 "binary_fp_operator"
13043 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13044 (match_operand 2 "register_operand" "")]))]
13046 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13047 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13050 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13051 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13052 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13053 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13054 GET_MODE (operands[3]),
13057 ix86_free_from_memory (GET_MODE (operands[1]));
13062 [(set (match_operand 0 "register_operand" "")
13063 (match_operator 3 "binary_fp_operator"
13064 [(match_operand 1 "register_operand" "")
13065 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13067 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13068 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13071 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13072 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13073 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13074 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13075 GET_MODE (operands[3]),
13078 ix86_free_from_memory (GET_MODE (operands[2]));
13082 ;; FPU special functions.
13084 ;; This pattern implements a no-op XFmode truncation for
13085 ;; all fancy i386 XFmode math functions.
13087 (define_insn "truncxf<mode>2_i387_noop_unspec"
13088 [(set (match_operand:MODEF 0 "register_operand" "=f")
13089 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13090 UNSPEC_TRUNC_NOOP))]
13091 "TARGET_USE_FANCY_MATH_387"
13092 "* return output_387_reg_move (insn, operands);"
13093 [(set_attr "type" "fmov")
13094 (set_attr "mode" "<MODE>")])
13096 (define_insn "sqrtxf2"
13097 [(set (match_operand:XF 0 "register_operand" "=f")
13098 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13099 "TARGET_USE_FANCY_MATH_387"
13101 [(set_attr "type" "fpspc")
13102 (set_attr "mode" "XF")
13103 (set_attr "athlon_decode" "direct")
13104 (set_attr "amdfam10_decode" "direct")
13105 (set_attr "bdver1_decode" "direct")])
13107 (define_insn "sqrt_extend<mode>xf2_i387"
13108 [(set (match_operand:XF 0 "register_operand" "=f")
13111 (match_operand:MODEF 1 "register_operand" "0"))))]
13112 "TARGET_USE_FANCY_MATH_387"
13114 [(set_attr "type" "fpspc")
13115 (set_attr "mode" "XF")
13116 (set_attr "athlon_decode" "direct")
13117 (set_attr "amdfam10_decode" "direct")
13118 (set_attr "bdver1_decode" "direct")])
13120 (define_insn "*rsqrtsf2_sse"
13121 [(set (match_operand:SF 0 "register_operand" "=x")
13122 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13125 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13126 [(set_attr "type" "sse")
13127 (set_attr "atom_sse_attr" "rcp")
13128 (set_attr "prefix" "maybe_vex")
13129 (set_attr "mode" "SF")])
13131 (define_expand "rsqrtsf2"
13132 [(set (match_operand:SF 0 "register_operand" "")
13133 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13137 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13141 (define_insn "*sqrt<mode>2_sse"
13142 [(set (match_operand:MODEF 0 "register_operand" "=x")
13144 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13145 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13146 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13147 [(set_attr "type" "sse")
13148 (set_attr "atom_sse_attr" "sqrt")
13149 (set_attr "prefix" "maybe_vex")
13150 (set_attr "mode" "<MODE>")
13151 (set_attr "athlon_decode" "*")
13152 (set_attr "amdfam10_decode" "*")
13153 (set_attr "bdver1_decode" "*")])
13155 (define_expand "sqrt<mode>2"
13156 [(set (match_operand:MODEF 0 "register_operand" "")
13158 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13159 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13160 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13162 if (<MODE>mode == SFmode
13163 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13164 && flag_finite_math_only && !flag_trapping_math
13165 && flag_unsafe_math_optimizations)
13167 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13171 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13173 rtx op0 = gen_reg_rtx (XFmode);
13174 rtx op1 = force_reg (<MODE>mode, operands[1]);
13176 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13177 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13182 (define_insn "fpremxf4_i387"
13183 [(set (match_operand:XF 0 "register_operand" "=f")
13184 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13185 (match_operand:XF 3 "register_operand" "1")]
13187 (set (match_operand:XF 1 "register_operand" "=u")
13188 (unspec:XF [(match_dup 2) (match_dup 3)]
13190 (set (reg:CCFP FPSR_REG)
13191 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13193 "TARGET_USE_FANCY_MATH_387"
13195 [(set_attr "type" "fpspc")
13196 (set_attr "mode" "XF")])
13198 (define_expand "fmodxf3"
13199 [(use (match_operand:XF 0 "register_operand" ""))
13200 (use (match_operand:XF 1 "general_operand" ""))
13201 (use (match_operand:XF 2 "general_operand" ""))]
13202 "TARGET_USE_FANCY_MATH_387"
13204 rtx label = gen_label_rtx ();
13206 rtx op1 = gen_reg_rtx (XFmode);
13207 rtx op2 = gen_reg_rtx (XFmode);
13209 emit_move_insn (op2, operands[2]);
13210 emit_move_insn (op1, operands[1]);
13212 emit_label (label);
13213 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13214 ix86_emit_fp_unordered_jump (label);
13215 LABEL_NUSES (label) = 1;
13217 emit_move_insn (operands[0], op1);
13221 (define_expand "fmod<mode>3"
13222 [(use (match_operand:MODEF 0 "register_operand" ""))
13223 (use (match_operand:MODEF 1 "general_operand" ""))
13224 (use (match_operand:MODEF 2 "general_operand" ""))]
13225 "TARGET_USE_FANCY_MATH_387"
13227 rtx (*gen_truncxf) (rtx, rtx);
13229 rtx label = gen_label_rtx ();
13231 rtx op1 = gen_reg_rtx (XFmode);
13232 rtx op2 = gen_reg_rtx (XFmode);
13234 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13235 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13237 emit_label (label);
13238 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13239 ix86_emit_fp_unordered_jump (label);
13240 LABEL_NUSES (label) = 1;
13242 /* Truncate the result properly for strict SSE math. */
13243 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13244 && !TARGET_MIX_SSE_I387)
13245 gen_truncxf = gen_truncxf<mode>2;
13247 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13249 emit_insn (gen_truncxf (operands[0], op1));
13253 (define_insn "fprem1xf4_i387"
13254 [(set (match_operand:XF 0 "register_operand" "=f")
13255 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13256 (match_operand:XF 3 "register_operand" "1")]
13258 (set (match_operand:XF 1 "register_operand" "=u")
13259 (unspec:XF [(match_dup 2) (match_dup 3)]
13261 (set (reg:CCFP FPSR_REG)
13262 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13264 "TARGET_USE_FANCY_MATH_387"
13266 [(set_attr "type" "fpspc")
13267 (set_attr "mode" "XF")])
13269 (define_expand "remainderxf3"
13270 [(use (match_operand:XF 0 "register_operand" ""))
13271 (use (match_operand:XF 1 "general_operand" ""))
13272 (use (match_operand:XF 2 "general_operand" ""))]
13273 "TARGET_USE_FANCY_MATH_387"
13275 rtx label = gen_label_rtx ();
13277 rtx op1 = gen_reg_rtx (XFmode);
13278 rtx op2 = gen_reg_rtx (XFmode);
13280 emit_move_insn (op2, operands[2]);
13281 emit_move_insn (op1, operands[1]);
13283 emit_label (label);
13284 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13285 ix86_emit_fp_unordered_jump (label);
13286 LABEL_NUSES (label) = 1;
13288 emit_move_insn (operands[0], op1);
13292 (define_expand "remainder<mode>3"
13293 [(use (match_operand:MODEF 0 "register_operand" ""))
13294 (use (match_operand:MODEF 1 "general_operand" ""))
13295 (use (match_operand:MODEF 2 "general_operand" ""))]
13296 "TARGET_USE_FANCY_MATH_387"
13298 rtx (*gen_truncxf) (rtx, rtx);
13300 rtx label = gen_label_rtx ();
13302 rtx op1 = gen_reg_rtx (XFmode);
13303 rtx op2 = gen_reg_rtx (XFmode);
13305 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13306 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13308 emit_label (label);
13310 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13311 ix86_emit_fp_unordered_jump (label);
13312 LABEL_NUSES (label) = 1;
13314 /* Truncate the result properly for strict SSE math. */
13315 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13316 && !TARGET_MIX_SSE_I387)
13317 gen_truncxf = gen_truncxf<mode>2;
13319 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13321 emit_insn (gen_truncxf (operands[0], op1));
13325 (define_insn "*sinxf2_i387"
13326 [(set (match_operand:XF 0 "register_operand" "=f")
13327 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13328 "TARGET_USE_FANCY_MATH_387
13329 && flag_unsafe_math_optimizations"
13331 [(set_attr "type" "fpspc")
13332 (set_attr "mode" "XF")])
13334 (define_insn "*sin_extend<mode>xf2_i387"
13335 [(set (match_operand:XF 0 "register_operand" "=f")
13336 (unspec:XF [(float_extend:XF
13337 (match_operand:MODEF 1 "register_operand" "0"))]
13339 "TARGET_USE_FANCY_MATH_387
13340 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13341 || TARGET_MIX_SSE_I387)
13342 && flag_unsafe_math_optimizations"
13344 [(set_attr "type" "fpspc")
13345 (set_attr "mode" "XF")])
13347 (define_insn "*cosxf2_i387"
13348 [(set (match_operand:XF 0 "register_operand" "=f")
13349 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13350 "TARGET_USE_FANCY_MATH_387
13351 && flag_unsafe_math_optimizations"
13353 [(set_attr "type" "fpspc")
13354 (set_attr "mode" "XF")])
13356 (define_insn "*cos_extend<mode>xf2_i387"
13357 [(set (match_operand:XF 0 "register_operand" "=f")
13358 (unspec:XF [(float_extend:XF
13359 (match_operand:MODEF 1 "register_operand" "0"))]
13361 "TARGET_USE_FANCY_MATH_387
13362 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13363 || TARGET_MIX_SSE_I387)
13364 && flag_unsafe_math_optimizations"
13366 [(set_attr "type" "fpspc")
13367 (set_attr "mode" "XF")])
13369 ;; When sincos pattern is defined, sin and cos builtin functions will be
13370 ;; expanded to sincos pattern with one of its outputs left unused.
13371 ;; CSE pass will figure out if two sincos patterns can be combined,
13372 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13373 ;; depending on the unused output.
13375 (define_insn "sincosxf3"
13376 [(set (match_operand:XF 0 "register_operand" "=f")
13377 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13378 UNSPEC_SINCOS_COS))
13379 (set (match_operand:XF 1 "register_operand" "=u")
13380 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13381 "TARGET_USE_FANCY_MATH_387
13382 && flag_unsafe_math_optimizations"
13384 [(set_attr "type" "fpspc")
13385 (set_attr "mode" "XF")])
13388 [(set (match_operand:XF 0 "register_operand" "")
13389 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13390 UNSPEC_SINCOS_COS))
13391 (set (match_operand:XF 1 "register_operand" "")
13392 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13393 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13394 && !(reload_completed || reload_in_progress)"
13395 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13398 [(set (match_operand:XF 0 "register_operand" "")
13399 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13400 UNSPEC_SINCOS_COS))
13401 (set (match_operand:XF 1 "register_operand" "")
13402 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13403 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13404 && !(reload_completed || reload_in_progress)"
13405 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13407 (define_insn "sincos_extend<mode>xf3_i387"
13408 [(set (match_operand:XF 0 "register_operand" "=f")
13409 (unspec:XF [(float_extend:XF
13410 (match_operand:MODEF 2 "register_operand" "0"))]
13411 UNSPEC_SINCOS_COS))
13412 (set (match_operand:XF 1 "register_operand" "=u")
13413 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13414 "TARGET_USE_FANCY_MATH_387
13415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13416 || TARGET_MIX_SSE_I387)
13417 && flag_unsafe_math_optimizations"
13419 [(set_attr "type" "fpspc")
13420 (set_attr "mode" "XF")])
13423 [(set (match_operand:XF 0 "register_operand" "")
13424 (unspec:XF [(float_extend:XF
13425 (match_operand:MODEF 2 "register_operand" ""))]
13426 UNSPEC_SINCOS_COS))
13427 (set (match_operand:XF 1 "register_operand" "")
13428 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13429 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13430 && !(reload_completed || reload_in_progress)"
13431 [(set (match_dup 1)
13432 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13435 [(set (match_operand:XF 0 "register_operand" "")
13436 (unspec:XF [(float_extend:XF
13437 (match_operand:MODEF 2 "register_operand" ""))]
13438 UNSPEC_SINCOS_COS))
13439 (set (match_operand:XF 1 "register_operand" "")
13440 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13441 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13442 && !(reload_completed || reload_in_progress)"
13443 [(set (match_dup 0)
13444 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13446 (define_expand "sincos<mode>3"
13447 [(use (match_operand:MODEF 0 "register_operand" ""))
13448 (use (match_operand:MODEF 1 "register_operand" ""))
13449 (use (match_operand:MODEF 2 "register_operand" ""))]
13450 "TARGET_USE_FANCY_MATH_387
13451 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13452 || TARGET_MIX_SSE_I387)
13453 && flag_unsafe_math_optimizations"
13455 rtx op0 = gen_reg_rtx (XFmode);
13456 rtx op1 = gen_reg_rtx (XFmode);
13458 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13459 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13460 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13464 (define_insn "fptanxf4_i387"
13465 [(set (match_operand:XF 0 "register_operand" "=f")
13466 (match_operand:XF 3 "const_double_operand" "F"))
13467 (set (match_operand:XF 1 "register_operand" "=u")
13468 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13470 "TARGET_USE_FANCY_MATH_387
13471 && flag_unsafe_math_optimizations
13472 && standard_80387_constant_p (operands[3]) == 2"
13474 [(set_attr "type" "fpspc")
13475 (set_attr "mode" "XF")])
13477 (define_insn "fptan_extend<mode>xf4_i387"
13478 [(set (match_operand:MODEF 0 "register_operand" "=f")
13479 (match_operand:MODEF 3 "const_double_operand" "F"))
13480 (set (match_operand:XF 1 "register_operand" "=u")
13481 (unspec:XF [(float_extend:XF
13482 (match_operand:MODEF 2 "register_operand" "0"))]
13484 "TARGET_USE_FANCY_MATH_387
13485 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13486 || TARGET_MIX_SSE_I387)
13487 && flag_unsafe_math_optimizations
13488 && standard_80387_constant_p (operands[3]) == 2"
13490 [(set_attr "type" "fpspc")
13491 (set_attr "mode" "XF")])
13493 (define_expand "tanxf2"
13494 [(use (match_operand:XF 0 "register_operand" ""))
13495 (use (match_operand:XF 1 "register_operand" ""))]
13496 "TARGET_USE_FANCY_MATH_387
13497 && flag_unsafe_math_optimizations"
13499 rtx one = gen_reg_rtx (XFmode);
13500 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13502 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13506 (define_expand "tan<mode>2"
13507 [(use (match_operand:MODEF 0 "register_operand" ""))
13508 (use (match_operand:MODEF 1 "register_operand" ""))]
13509 "TARGET_USE_FANCY_MATH_387
13510 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13511 || TARGET_MIX_SSE_I387)
13512 && flag_unsafe_math_optimizations"
13514 rtx op0 = gen_reg_rtx (XFmode);
13516 rtx one = gen_reg_rtx (<MODE>mode);
13517 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13519 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13520 operands[1], op2));
13521 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13525 (define_insn "*fpatanxf3_i387"
13526 [(set (match_operand:XF 0 "register_operand" "=f")
13527 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13528 (match_operand:XF 2 "register_operand" "u")]
13530 (clobber (match_scratch:XF 3 "=2"))]
13531 "TARGET_USE_FANCY_MATH_387
13532 && flag_unsafe_math_optimizations"
13534 [(set_attr "type" "fpspc")
13535 (set_attr "mode" "XF")])
13537 (define_insn "fpatan_extend<mode>xf3_i387"
13538 [(set (match_operand:XF 0 "register_operand" "=f")
13539 (unspec:XF [(float_extend:XF
13540 (match_operand:MODEF 1 "register_operand" "0"))
13542 (match_operand:MODEF 2 "register_operand" "u"))]
13544 (clobber (match_scratch:XF 3 "=2"))]
13545 "TARGET_USE_FANCY_MATH_387
13546 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13547 || TARGET_MIX_SSE_I387)
13548 && flag_unsafe_math_optimizations"
13550 [(set_attr "type" "fpspc")
13551 (set_attr "mode" "XF")])
13553 (define_expand "atan2xf3"
13554 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13555 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13556 (match_operand:XF 1 "register_operand" "")]
13558 (clobber (match_scratch:XF 3 ""))])]
13559 "TARGET_USE_FANCY_MATH_387
13560 && flag_unsafe_math_optimizations")
13562 (define_expand "atan2<mode>3"
13563 [(use (match_operand:MODEF 0 "register_operand" ""))
13564 (use (match_operand:MODEF 1 "register_operand" ""))
13565 (use (match_operand:MODEF 2 "register_operand" ""))]
13566 "TARGET_USE_FANCY_MATH_387
13567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13568 || TARGET_MIX_SSE_I387)
13569 && flag_unsafe_math_optimizations"
13571 rtx op0 = gen_reg_rtx (XFmode);
13573 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13574 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13578 (define_expand "atanxf2"
13579 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13580 (unspec:XF [(match_dup 2)
13581 (match_operand:XF 1 "register_operand" "")]
13583 (clobber (match_scratch:XF 3 ""))])]
13584 "TARGET_USE_FANCY_MATH_387
13585 && flag_unsafe_math_optimizations"
13587 operands[2] = gen_reg_rtx (XFmode);
13588 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13591 (define_expand "atan<mode>2"
13592 [(use (match_operand:MODEF 0 "register_operand" ""))
13593 (use (match_operand:MODEF 1 "register_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);
13601 rtx op2 = gen_reg_rtx (<MODE>mode);
13602 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13604 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13605 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13609 (define_expand "asinxf2"
13610 [(set (match_dup 2)
13611 (mult:XF (match_operand:XF 1 "register_operand" "")
13613 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13614 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13615 (parallel [(set (match_operand:XF 0 "register_operand" "")
13616 (unspec:XF [(match_dup 5) (match_dup 1)]
13618 (clobber (match_scratch:XF 6 ""))])]
13619 "TARGET_USE_FANCY_MATH_387
13620 && flag_unsafe_math_optimizations"
13624 if (optimize_insn_for_size_p ())
13627 for (i = 2; i < 6; i++)
13628 operands[i] = gen_reg_rtx (XFmode);
13630 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13633 (define_expand "asin<mode>2"
13634 [(use (match_operand:MODEF 0 "register_operand" ""))
13635 (use (match_operand:MODEF 1 "general_operand" ""))]
13636 "TARGET_USE_FANCY_MATH_387
13637 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13638 || TARGET_MIX_SSE_I387)
13639 && flag_unsafe_math_optimizations"
13641 rtx op0 = gen_reg_rtx (XFmode);
13642 rtx op1 = gen_reg_rtx (XFmode);
13644 if (optimize_insn_for_size_p ())
13647 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13648 emit_insn (gen_asinxf2 (op0, op1));
13649 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13653 (define_expand "acosxf2"
13654 [(set (match_dup 2)
13655 (mult:XF (match_operand:XF 1 "register_operand" "")
13657 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13658 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13659 (parallel [(set (match_operand:XF 0 "register_operand" "")
13660 (unspec:XF [(match_dup 1) (match_dup 5)]
13662 (clobber (match_scratch:XF 6 ""))])]
13663 "TARGET_USE_FANCY_MATH_387
13664 && flag_unsafe_math_optimizations"
13668 if (optimize_insn_for_size_p ())
13671 for (i = 2; i < 6; i++)
13672 operands[i] = gen_reg_rtx (XFmode);
13674 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13677 (define_expand "acos<mode>2"
13678 [(use (match_operand:MODEF 0 "register_operand" ""))
13679 (use (match_operand:MODEF 1 "general_operand" ""))]
13680 "TARGET_USE_FANCY_MATH_387
13681 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13682 || TARGET_MIX_SSE_I387)
13683 && flag_unsafe_math_optimizations"
13685 rtx op0 = gen_reg_rtx (XFmode);
13686 rtx op1 = gen_reg_rtx (XFmode);
13688 if (optimize_insn_for_size_p ())
13691 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13692 emit_insn (gen_acosxf2 (op0, op1));
13693 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13697 (define_insn "fyl2xxf3_i387"
13698 [(set (match_operand:XF 0 "register_operand" "=f")
13699 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13700 (match_operand:XF 2 "register_operand" "u")]
13702 (clobber (match_scratch:XF 3 "=2"))]
13703 "TARGET_USE_FANCY_MATH_387
13704 && flag_unsafe_math_optimizations"
13706 [(set_attr "type" "fpspc")
13707 (set_attr "mode" "XF")])
13709 (define_insn "fyl2x_extend<mode>xf3_i387"
13710 [(set (match_operand:XF 0 "register_operand" "=f")
13711 (unspec:XF [(float_extend:XF
13712 (match_operand:MODEF 1 "register_operand" "0"))
13713 (match_operand:XF 2 "register_operand" "u")]
13715 (clobber (match_scratch:XF 3 "=2"))]
13716 "TARGET_USE_FANCY_MATH_387
13717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13718 || TARGET_MIX_SSE_I387)
13719 && flag_unsafe_math_optimizations"
13721 [(set_attr "type" "fpspc")
13722 (set_attr "mode" "XF")])
13724 (define_expand "logxf2"
13725 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13726 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13727 (match_dup 2)] UNSPEC_FYL2X))
13728 (clobber (match_scratch:XF 3 ""))])]
13729 "TARGET_USE_FANCY_MATH_387
13730 && flag_unsafe_math_optimizations"
13732 operands[2] = gen_reg_rtx (XFmode);
13733 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13736 (define_expand "log<mode>2"
13737 [(use (match_operand:MODEF 0 "register_operand" ""))
13738 (use (match_operand:MODEF 1 "register_operand" ""))]
13739 "TARGET_USE_FANCY_MATH_387
13740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13741 || TARGET_MIX_SSE_I387)
13742 && flag_unsafe_math_optimizations"
13744 rtx op0 = gen_reg_rtx (XFmode);
13746 rtx op2 = gen_reg_rtx (XFmode);
13747 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13749 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13750 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13754 (define_expand "log10xf2"
13755 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13756 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13757 (match_dup 2)] UNSPEC_FYL2X))
13758 (clobber (match_scratch:XF 3 ""))])]
13759 "TARGET_USE_FANCY_MATH_387
13760 && flag_unsafe_math_optimizations"
13762 operands[2] = gen_reg_rtx (XFmode);
13763 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13766 (define_expand "log10<mode>2"
13767 [(use (match_operand:MODEF 0 "register_operand" ""))
13768 (use (match_operand:MODEF 1 "register_operand" ""))]
13769 "TARGET_USE_FANCY_MATH_387
13770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13771 || TARGET_MIX_SSE_I387)
13772 && flag_unsafe_math_optimizations"
13774 rtx op0 = gen_reg_rtx (XFmode);
13776 rtx op2 = gen_reg_rtx (XFmode);
13777 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13779 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13780 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13784 (define_expand "log2xf2"
13785 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13786 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13787 (match_dup 2)] UNSPEC_FYL2X))
13788 (clobber (match_scratch:XF 3 ""))])]
13789 "TARGET_USE_FANCY_MATH_387
13790 && flag_unsafe_math_optimizations"
13792 operands[2] = gen_reg_rtx (XFmode);
13793 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13796 (define_expand "log2<mode>2"
13797 [(use (match_operand:MODEF 0 "register_operand" ""))
13798 (use (match_operand:MODEF 1 "register_operand" ""))]
13799 "TARGET_USE_FANCY_MATH_387
13800 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13801 || TARGET_MIX_SSE_I387)
13802 && flag_unsafe_math_optimizations"
13804 rtx op0 = gen_reg_rtx (XFmode);
13806 rtx op2 = gen_reg_rtx (XFmode);
13807 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13809 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13810 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13814 (define_insn "fyl2xp1xf3_i387"
13815 [(set (match_operand:XF 0 "register_operand" "=f")
13816 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13817 (match_operand:XF 2 "register_operand" "u")]
13819 (clobber (match_scratch:XF 3 "=2"))]
13820 "TARGET_USE_FANCY_MATH_387
13821 && flag_unsafe_math_optimizations"
13823 [(set_attr "type" "fpspc")
13824 (set_attr "mode" "XF")])
13826 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13827 [(set (match_operand:XF 0 "register_operand" "=f")
13828 (unspec:XF [(float_extend:XF
13829 (match_operand:MODEF 1 "register_operand" "0"))
13830 (match_operand:XF 2 "register_operand" "u")]
13832 (clobber (match_scratch:XF 3 "=2"))]
13833 "TARGET_USE_FANCY_MATH_387
13834 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13835 || TARGET_MIX_SSE_I387)
13836 && flag_unsafe_math_optimizations"
13838 [(set_attr "type" "fpspc")
13839 (set_attr "mode" "XF")])
13841 (define_expand "log1pxf2"
13842 [(use (match_operand:XF 0 "register_operand" ""))
13843 (use (match_operand:XF 1 "register_operand" ""))]
13844 "TARGET_USE_FANCY_MATH_387
13845 && flag_unsafe_math_optimizations"
13847 if (optimize_insn_for_size_p ())
13850 ix86_emit_i387_log1p (operands[0], operands[1]);
13854 (define_expand "log1p<mode>2"
13855 [(use (match_operand:MODEF 0 "register_operand" ""))
13856 (use (match_operand:MODEF 1 "register_operand" ""))]
13857 "TARGET_USE_FANCY_MATH_387
13858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13859 || TARGET_MIX_SSE_I387)
13860 && flag_unsafe_math_optimizations"
13864 if (optimize_insn_for_size_p ())
13867 op0 = gen_reg_rtx (XFmode);
13869 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13871 ix86_emit_i387_log1p (op0, operands[1]);
13872 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13876 (define_insn "fxtractxf3_i387"
13877 [(set (match_operand:XF 0 "register_operand" "=f")
13878 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13879 UNSPEC_XTRACT_FRACT))
13880 (set (match_operand:XF 1 "register_operand" "=u")
13881 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13882 "TARGET_USE_FANCY_MATH_387
13883 && flag_unsafe_math_optimizations"
13885 [(set_attr "type" "fpspc")
13886 (set_attr "mode" "XF")])
13888 (define_insn "fxtract_extend<mode>xf3_i387"
13889 [(set (match_operand:XF 0 "register_operand" "=f")
13890 (unspec:XF [(float_extend:XF
13891 (match_operand:MODEF 2 "register_operand" "0"))]
13892 UNSPEC_XTRACT_FRACT))
13893 (set (match_operand:XF 1 "register_operand" "=u")
13894 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13895 "TARGET_USE_FANCY_MATH_387
13896 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13897 || TARGET_MIX_SSE_I387)
13898 && flag_unsafe_math_optimizations"
13900 [(set_attr "type" "fpspc")
13901 (set_attr "mode" "XF")])
13903 (define_expand "logbxf2"
13904 [(parallel [(set (match_dup 2)
13905 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13906 UNSPEC_XTRACT_FRACT))
13907 (set (match_operand:XF 0 "register_operand" "")
13908 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13909 "TARGET_USE_FANCY_MATH_387
13910 && flag_unsafe_math_optimizations"
13911 "operands[2] = gen_reg_rtx (XFmode);")
13913 (define_expand "logb<mode>2"
13914 [(use (match_operand:MODEF 0 "register_operand" ""))
13915 (use (match_operand:MODEF 1 "register_operand" ""))]
13916 "TARGET_USE_FANCY_MATH_387
13917 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13918 || TARGET_MIX_SSE_I387)
13919 && flag_unsafe_math_optimizations"
13921 rtx op0 = gen_reg_rtx (XFmode);
13922 rtx op1 = gen_reg_rtx (XFmode);
13924 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13925 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13929 (define_expand "ilogbxf2"
13930 [(use (match_operand:SI 0 "register_operand" ""))
13931 (use (match_operand:XF 1 "register_operand" ""))]
13932 "TARGET_USE_FANCY_MATH_387
13933 && flag_unsafe_math_optimizations"
13937 if (optimize_insn_for_size_p ())
13940 op0 = gen_reg_rtx (XFmode);
13941 op1 = gen_reg_rtx (XFmode);
13943 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13944 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13948 (define_expand "ilogb<mode>2"
13949 [(use (match_operand:SI 0 "register_operand" ""))
13950 (use (match_operand:MODEF 1 "register_operand" ""))]
13951 "TARGET_USE_FANCY_MATH_387
13952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13953 || TARGET_MIX_SSE_I387)
13954 && flag_unsafe_math_optimizations"
13958 if (optimize_insn_for_size_p ())
13961 op0 = gen_reg_rtx (XFmode);
13962 op1 = gen_reg_rtx (XFmode);
13964 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13965 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13969 (define_insn "*f2xm1xf2_i387"
13970 [(set (match_operand:XF 0 "register_operand" "=f")
13971 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13973 "TARGET_USE_FANCY_MATH_387
13974 && flag_unsafe_math_optimizations"
13976 [(set_attr "type" "fpspc")
13977 (set_attr "mode" "XF")])
13979 (define_insn "*fscalexf4_i387"
13980 [(set (match_operand:XF 0 "register_operand" "=f")
13981 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13982 (match_operand:XF 3 "register_operand" "1")]
13983 UNSPEC_FSCALE_FRACT))
13984 (set (match_operand:XF 1 "register_operand" "=u")
13985 (unspec:XF [(match_dup 2) (match_dup 3)]
13986 UNSPEC_FSCALE_EXP))]
13987 "TARGET_USE_FANCY_MATH_387
13988 && flag_unsafe_math_optimizations"
13990 [(set_attr "type" "fpspc")
13991 (set_attr "mode" "XF")])
13993 (define_expand "expNcorexf3"
13994 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13995 (match_operand:XF 2 "register_operand" "")))
13996 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13997 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13998 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13999 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14000 (parallel [(set (match_operand:XF 0 "register_operand" "")
14001 (unspec:XF [(match_dup 8) (match_dup 4)]
14002 UNSPEC_FSCALE_FRACT))
14004 (unspec:XF [(match_dup 8) (match_dup 4)]
14005 UNSPEC_FSCALE_EXP))])]
14006 "TARGET_USE_FANCY_MATH_387
14007 && flag_unsafe_math_optimizations"
14011 if (optimize_insn_for_size_p ())
14014 for (i = 3; i < 10; i++)
14015 operands[i] = gen_reg_rtx (XFmode);
14017 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14020 (define_expand "expxf2"
14021 [(use (match_operand:XF 0 "register_operand" ""))
14022 (use (match_operand:XF 1 "register_operand" ""))]
14023 "TARGET_USE_FANCY_MATH_387
14024 && flag_unsafe_math_optimizations"
14028 if (optimize_insn_for_size_p ())
14031 op2 = gen_reg_rtx (XFmode);
14032 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14034 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14038 (define_expand "exp<mode>2"
14039 [(use (match_operand:MODEF 0 "register_operand" ""))
14040 (use (match_operand:MODEF 1 "general_operand" ""))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14043 || TARGET_MIX_SSE_I387)
14044 && flag_unsafe_math_optimizations"
14048 if (optimize_insn_for_size_p ())
14051 op0 = gen_reg_rtx (XFmode);
14052 op1 = gen_reg_rtx (XFmode);
14054 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14055 emit_insn (gen_expxf2 (op0, op1));
14056 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14060 (define_expand "exp10xf2"
14061 [(use (match_operand:XF 0 "register_operand" ""))
14062 (use (match_operand:XF 1 "register_operand" ""))]
14063 "TARGET_USE_FANCY_MATH_387
14064 && flag_unsafe_math_optimizations"
14068 if (optimize_insn_for_size_p ())
14071 op2 = gen_reg_rtx (XFmode);
14072 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14074 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14078 (define_expand "exp10<mode>2"
14079 [(use (match_operand:MODEF 0 "register_operand" ""))
14080 (use (match_operand:MODEF 1 "general_operand" ""))]
14081 "TARGET_USE_FANCY_MATH_387
14082 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14083 || TARGET_MIX_SSE_I387)
14084 && flag_unsafe_math_optimizations"
14088 if (optimize_insn_for_size_p ())
14091 op0 = gen_reg_rtx (XFmode);
14092 op1 = gen_reg_rtx (XFmode);
14094 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14095 emit_insn (gen_exp10xf2 (op0, op1));
14096 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14100 (define_expand "exp2xf2"
14101 [(use (match_operand:XF 0 "register_operand" ""))
14102 (use (match_operand:XF 1 "register_operand" ""))]
14103 "TARGET_USE_FANCY_MATH_387
14104 && flag_unsafe_math_optimizations"
14108 if (optimize_insn_for_size_p ())
14111 op2 = gen_reg_rtx (XFmode);
14112 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14114 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14118 (define_expand "exp2<mode>2"
14119 [(use (match_operand:MODEF 0 "register_operand" ""))
14120 (use (match_operand:MODEF 1 "general_operand" ""))]
14121 "TARGET_USE_FANCY_MATH_387
14122 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14123 || TARGET_MIX_SSE_I387)
14124 && flag_unsafe_math_optimizations"
14128 if (optimize_insn_for_size_p ())
14131 op0 = gen_reg_rtx (XFmode);
14132 op1 = gen_reg_rtx (XFmode);
14134 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14135 emit_insn (gen_exp2xf2 (op0, op1));
14136 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14140 (define_expand "expm1xf2"
14141 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14143 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14144 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14145 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14146 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14147 (parallel [(set (match_dup 7)
14148 (unspec:XF [(match_dup 6) (match_dup 4)]
14149 UNSPEC_FSCALE_FRACT))
14151 (unspec:XF [(match_dup 6) (match_dup 4)]
14152 UNSPEC_FSCALE_EXP))])
14153 (parallel [(set (match_dup 10)
14154 (unspec:XF [(match_dup 9) (match_dup 8)]
14155 UNSPEC_FSCALE_FRACT))
14156 (set (match_dup 11)
14157 (unspec:XF [(match_dup 9) (match_dup 8)]
14158 UNSPEC_FSCALE_EXP))])
14159 (set (match_dup 12) (minus:XF (match_dup 10)
14160 (float_extend:XF (match_dup 13))))
14161 (set (match_operand:XF 0 "register_operand" "")
14162 (plus:XF (match_dup 12) (match_dup 7)))]
14163 "TARGET_USE_FANCY_MATH_387
14164 && flag_unsafe_math_optimizations"
14168 if (optimize_insn_for_size_p ())
14171 for (i = 2; i < 13; i++)
14172 operands[i] = gen_reg_rtx (XFmode);
14175 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14177 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14180 (define_expand "expm1<mode>2"
14181 [(use (match_operand:MODEF 0 "register_operand" ""))
14182 (use (match_operand:MODEF 1 "general_operand" ""))]
14183 "TARGET_USE_FANCY_MATH_387
14184 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14185 || TARGET_MIX_SSE_I387)
14186 && flag_unsafe_math_optimizations"
14190 if (optimize_insn_for_size_p ())
14193 op0 = gen_reg_rtx (XFmode);
14194 op1 = gen_reg_rtx (XFmode);
14196 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14197 emit_insn (gen_expm1xf2 (op0, op1));
14198 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14202 (define_expand "ldexpxf3"
14203 [(set (match_dup 3)
14204 (float:XF (match_operand:SI 2 "register_operand" "")))
14205 (parallel [(set (match_operand:XF 0 " register_operand" "")
14206 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14208 UNSPEC_FSCALE_FRACT))
14210 (unspec:XF [(match_dup 1) (match_dup 3)]
14211 UNSPEC_FSCALE_EXP))])]
14212 "TARGET_USE_FANCY_MATH_387
14213 && flag_unsafe_math_optimizations"
14215 if (optimize_insn_for_size_p ())
14218 operands[3] = gen_reg_rtx (XFmode);
14219 operands[4] = gen_reg_rtx (XFmode);
14222 (define_expand "ldexp<mode>3"
14223 [(use (match_operand:MODEF 0 "register_operand" ""))
14224 (use (match_operand:MODEF 1 "general_operand" ""))
14225 (use (match_operand:SI 2 "register_operand" ""))]
14226 "TARGET_USE_FANCY_MATH_387
14227 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14228 || TARGET_MIX_SSE_I387)
14229 && flag_unsafe_math_optimizations"
14233 if (optimize_insn_for_size_p ())
14236 op0 = gen_reg_rtx (XFmode);
14237 op1 = gen_reg_rtx (XFmode);
14239 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14240 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14241 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14245 (define_expand "scalbxf3"
14246 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14247 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14248 (match_operand:XF 2 "register_operand" "")]
14249 UNSPEC_FSCALE_FRACT))
14251 (unspec:XF [(match_dup 1) (match_dup 2)]
14252 UNSPEC_FSCALE_EXP))])]
14253 "TARGET_USE_FANCY_MATH_387
14254 && flag_unsafe_math_optimizations"
14256 if (optimize_insn_for_size_p ())
14259 operands[3] = gen_reg_rtx (XFmode);
14262 (define_expand "scalb<mode>3"
14263 [(use (match_operand:MODEF 0 "register_operand" ""))
14264 (use (match_operand:MODEF 1 "general_operand" ""))
14265 (use (match_operand:MODEF 2 "general_operand" ""))]
14266 "TARGET_USE_FANCY_MATH_387
14267 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14268 || TARGET_MIX_SSE_I387)
14269 && flag_unsafe_math_optimizations"
14273 if (optimize_insn_for_size_p ())
14276 op0 = gen_reg_rtx (XFmode);
14277 op1 = gen_reg_rtx (XFmode);
14278 op2 = gen_reg_rtx (XFmode);
14280 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14281 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14282 emit_insn (gen_scalbxf3 (op0, op1, op2));
14283 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14287 (define_expand "significandxf2"
14288 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14289 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14290 UNSPEC_XTRACT_FRACT))
14292 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14293 "TARGET_USE_FANCY_MATH_387
14294 && flag_unsafe_math_optimizations"
14295 "operands[2] = gen_reg_rtx (XFmode);")
14297 (define_expand "significand<mode>2"
14298 [(use (match_operand:MODEF 0 "register_operand" ""))
14299 (use (match_operand:MODEF 1 "register_operand" ""))]
14300 "TARGET_USE_FANCY_MATH_387
14301 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14302 || TARGET_MIX_SSE_I387)
14303 && flag_unsafe_math_optimizations"
14305 rtx op0 = gen_reg_rtx (XFmode);
14306 rtx op1 = gen_reg_rtx (XFmode);
14308 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14309 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14314 (define_insn "sse4_1_round<mode>2"
14315 [(set (match_operand:MODEF 0 "register_operand" "=x")
14316 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14317 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14320 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14321 [(set_attr "type" "ssecvt")
14322 (set_attr "prefix_extra" "1")
14323 (set_attr "prefix" "maybe_vex")
14324 (set_attr "mode" "<MODE>")])
14326 (define_insn "rintxf2"
14327 [(set (match_operand:XF 0 "register_operand" "=f")
14328 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14330 "TARGET_USE_FANCY_MATH_387
14331 && flag_unsafe_math_optimizations"
14333 [(set_attr "type" "fpspc")
14334 (set_attr "mode" "XF")])
14336 (define_expand "rint<mode>2"
14337 [(use (match_operand:MODEF 0 "register_operand" ""))
14338 (use (match_operand:MODEF 1 "register_operand" ""))]
14339 "(TARGET_USE_FANCY_MATH_387
14340 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14341 || TARGET_MIX_SSE_I387)
14342 && flag_unsafe_math_optimizations)
14343 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14344 && !flag_trapping_math)"
14346 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14347 && !flag_trapping_math)
14349 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14352 emit_insn (gen_sse4_1_round<mode>2
14353 (operands[0], operands[1], GEN_INT (0x04)));
14355 ix86_expand_rint (operand0, operand1);
14359 rtx op0 = gen_reg_rtx (XFmode);
14360 rtx op1 = gen_reg_rtx (XFmode);
14362 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14363 emit_insn (gen_rintxf2 (op0, op1));
14365 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14370 (define_expand "round<mode>2"
14371 [(match_operand:MODEF 0 "register_operand" "")
14372 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14373 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14374 && !flag_trapping_math && !flag_rounding_math"
14376 if (optimize_insn_for_size_p ())
14378 if (TARGET_64BIT || (<MODE>mode != DFmode))
14379 ix86_expand_round (operand0, operand1);
14381 ix86_expand_rounddf_32 (operand0, operand1);
14385 (define_insn_and_split "*fistdi2_1"
14386 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14387 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14389 "TARGET_USE_FANCY_MATH_387
14390 && can_create_pseudo_p ()"
14395 if (memory_operand (operands[0], VOIDmode))
14396 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14399 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14400 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14405 [(set_attr "type" "fpspc")
14406 (set_attr "mode" "DI")])
14408 (define_insn "fistdi2"
14409 [(set (match_operand:DI 0 "memory_operand" "=m")
14410 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14412 (clobber (match_scratch:XF 2 "=&1f"))]
14413 "TARGET_USE_FANCY_MATH_387"
14414 "* return output_fix_trunc (insn, operands, 0);"
14415 [(set_attr "type" "fpspc")
14416 (set_attr "mode" "DI")])
14418 (define_insn "fistdi2_with_temp"
14419 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14420 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14422 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14423 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14424 "TARGET_USE_FANCY_MATH_387"
14426 [(set_attr "type" "fpspc")
14427 (set_attr "mode" "DI")])
14430 [(set (match_operand:DI 0 "register_operand" "")
14431 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14433 (clobber (match_operand:DI 2 "memory_operand" ""))
14434 (clobber (match_scratch 3 ""))]
14436 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14437 (clobber (match_dup 3))])
14438 (set (match_dup 0) (match_dup 2))])
14441 [(set (match_operand:DI 0 "memory_operand" "")
14442 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14444 (clobber (match_operand:DI 2 "memory_operand" ""))
14445 (clobber (match_scratch 3 ""))]
14447 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14448 (clobber (match_dup 3))])])
14450 (define_insn_and_split "*fist<mode>2_1"
14451 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14452 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14454 "TARGET_USE_FANCY_MATH_387
14455 && can_create_pseudo_p ()"
14460 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14461 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14465 [(set_attr "type" "fpspc")
14466 (set_attr "mode" "<MODE>")])
14468 (define_insn "fist<mode>2"
14469 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14470 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14472 "TARGET_USE_FANCY_MATH_387"
14473 "* return output_fix_trunc (insn, operands, 0);"
14474 [(set_attr "type" "fpspc")
14475 (set_attr "mode" "<MODE>")])
14477 (define_insn "fist<mode>2_with_temp"
14478 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14479 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14481 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14482 "TARGET_USE_FANCY_MATH_387"
14484 [(set_attr "type" "fpspc")
14485 (set_attr "mode" "<MODE>")])
14488 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14489 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14491 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14493 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14494 (set (match_dup 0) (match_dup 2))])
14497 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14498 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14500 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14502 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14504 (define_expand "lrintxf<mode>2"
14505 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14506 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14508 "TARGET_USE_FANCY_MATH_387")
14510 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14511 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14512 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14513 UNSPEC_FIX_NOTRUNC))]
14514 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14515 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14517 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14518 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14519 (match_operand:MODEF 1 "register_operand" "")]
14520 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14521 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14522 && !flag_trapping_math && !flag_rounding_math"
14524 if (optimize_insn_for_size_p ())
14526 ix86_expand_lround (operand0, operand1);
14530 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14531 (define_insn_and_split "frndintxf2_floor"
14532 [(set (match_operand:XF 0 "register_operand" "")
14533 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14534 UNSPEC_FRNDINT_FLOOR))
14535 (clobber (reg:CC FLAGS_REG))]
14536 "TARGET_USE_FANCY_MATH_387
14537 && flag_unsafe_math_optimizations
14538 && can_create_pseudo_p ()"
14543 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14545 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14546 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14548 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14549 operands[2], operands[3]));
14552 [(set_attr "type" "frndint")
14553 (set_attr "i387_cw" "floor")
14554 (set_attr "mode" "XF")])
14556 (define_insn "frndintxf2_floor_i387"
14557 [(set (match_operand:XF 0 "register_operand" "=f")
14558 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14559 UNSPEC_FRNDINT_FLOOR))
14560 (use (match_operand:HI 2 "memory_operand" "m"))
14561 (use (match_operand:HI 3 "memory_operand" "m"))]
14562 "TARGET_USE_FANCY_MATH_387
14563 && flag_unsafe_math_optimizations"
14564 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14565 [(set_attr "type" "frndint")
14566 (set_attr "i387_cw" "floor")
14567 (set_attr "mode" "XF")])
14569 (define_expand "floorxf2"
14570 [(use (match_operand:XF 0 "register_operand" ""))
14571 (use (match_operand:XF 1 "register_operand" ""))]
14572 "TARGET_USE_FANCY_MATH_387
14573 && flag_unsafe_math_optimizations"
14575 if (optimize_insn_for_size_p ())
14577 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14581 (define_expand "floor<mode>2"
14582 [(use (match_operand:MODEF 0 "register_operand" ""))
14583 (use (match_operand:MODEF 1 "register_operand" ""))]
14584 "(TARGET_USE_FANCY_MATH_387
14585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586 || TARGET_MIX_SSE_I387)
14587 && flag_unsafe_math_optimizations)
14588 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14589 && !flag_trapping_math)"
14591 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14592 && !flag_trapping_math
14593 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14595 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14598 emit_insn (gen_sse4_1_round<mode>2
14599 (operands[0], operands[1], GEN_INT (0x01)));
14600 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14601 ix86_expand_floorceil (operand0, operand1, true);
14603 ix86_expand_floorceildf_32 (operand0, operand1, true);
14609 if (optimize_insn_for_size_p ())
14612 op0 = gen_reg_rtx (XFmode);
14613 op1 = gen_reg_rtx (XFmode);
14614 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14615 emit_insn (gen_frndintxf2_floor (op0, op1));
14617 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14622 (define_insn_and_split "*fist<mode>2_floor_1"
14623 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14624 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14625 UNSPEC_FIST_FLOOR))
14626 (clobber (reg:CC FLAGS_REG))]
14627 "TARGET_USE_FANCY_MATH_387
14628 && flag_unsafe_math_optimizations
14629 && can_create_pseudo_p ()"
14634 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14636 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14637 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14638 if (memory_operand (operands[0], VOIDmode))
14639 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14640 operands[2], operands[3]));
14643 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14644 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14645 operands[2], operands[3],
14650 [(set_attr "type" "fistp")
14651 (set_attr "i387_cw" "floor")
14652 (set_attr "mode" "<MODE>")])
14654 (define_insn "fistdi2_floor"
14655 [(set (match_operand:DI 0 "memory_operand" "=m")
14656 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14657 UNSPEC_FIST_FLOOR))
14658 (use (match_operand:HI 2 "memory_operand" "m"))
14659 (use (match_operand:HI 3 "memory_operand" "m"))
14660 (clobber (match_scratch:XF 4 "=&1f"))]
14661 "TARGET_USE_FANCY_MATH_387
14662 && flag_unsafe_math_optimizations"
14663 "* return output_fix_trunc (insn, operands, 0);"
14664 [(set_attr "type" "fistp")
14665 (set_attr "i387_cw" "floor")
14666 (set_attr "mode" "DI")])
14668 (define_insn "fistdi2_floor_with_temp"
14669 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14670 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14671 UNSPEC_FIST_FLOOR))
14672 (use (match_operand:HI 2 "memory_operand" "m,m"))
14673 (use (match_operand:HI 3 "memory_operand" "m,m"))
14674 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14675 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14676 "TARGET_USE_FANCY_MATH_387
14677 && flag_unsafe_math_optimizations"
14679 [(set_attr "type" "fistp")
14680 (set_attr "i387_cw" "floor")
14681 (set_attr "mode" "DI")])
14684 [(set (match_operand:DI 0 "register_operand" "")
14685 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14686 UNSPEC_FIST_FLOOR))
14687 (use (match_operand:HI 2 "memory_operand" ""))
14688 (use (match_operand:HI 3 "memory_operand" ""))
14689 (clobber (match_operand:DI 4 "memory_operand" ""))
14690 (clobber (match_scratch 5 ""))]
14692 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14693 (use (match_dup 2))
14694 (use (match_dup 3))
14695 (clobber (match_dup 5))])
14696 (set (match_dup 0) (match_dup 4))])
14699 [(set (match_operand:DI 0 "memory_operand" "")
14700 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14701 UNSPEC_FIST_FLOOR))
14702 (use (match_operand:HI 2 "memory_operand" ""))
14703 (use (match_operand:HI 3 "memory_operand" ""))
14704 (clobber (match_operand:DI 4 "memory_operand" ""))
14705 (clobber (match_scratch 5 ""))]
14707 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14708 (use (match_dup 2))
14709 (use (match_dup 3))
14710 (clobber (match_dup 5))])])
14712 (define_insn "fist<mode>2_floor"
14713 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14714 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14715 UNSPEC_FIST_FLOOR))
14716 (use (match_operand:HI 2 "memory_operand" "m"))
14717 (use (match_operand:HI 3 "memory_operand" "m"))]
14718 "TARGET_USE_FANCY_MATH_387
14719 && flag_unsafe_math_optimizations"
14720 "* return output_fix_trunc (insn, operands, 0);"
14721 [(set_attr "type" "fistp")
14722 (set_attr "i387_cw" "floor")
14723 (set_attr "mode" "<MODE>")])
14725 (define_insn "fist<mode>2_floor_with_temp"
14726 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14727 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14728 UNSPEC_FIST_FLOOR))
14729 (use (match_operand:HI 2 "memory_operand" "m,m"))
14730 (use (match_operand:HI 3 "memory_operand" "m,m"))
14731 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14732 "TARGET_USE_FANCY_MATH_387
14733 && flag_unsafe_math_optimizations"
14735 [(set_attr "type" "fistp")
14736 (set_attr "i387_cw" "floor")
14737 (set_attr "mode" "<MODE>")])
14740 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14741 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14742 UNSPEC_FIST_FLOOR))
14743 (use (match_operand:HI 2 "memory_operand" ""))
14744 (use (match_operand:HI 3 "memory_operand" ""))
14745 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14747 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14748 UNSPEC_FIST_FLOOR))
14749 (use (match_dup 2))
14750 (use (match_dup 3))])
14751 (set (match_dup 0) (match_dup 4))])
14754 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14755 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14756 UNSPEC_FIST_FLOOR))
14757 (use (match_operand:HI 2 "memory_operand" ""))
14758 (use (match_operand:HI 3 "memory_operand" ""))
14759 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14761 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14762 UNSPEC_FIST_FLOOR))
14763 (use (match_dup 2))
14764 (use (match_dup 3))])])
14766 (define_expand "lfloorxf<mode>2"
14767 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14768 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14769 UNSPEC_FIST_FLOOR))
14770 (clobber (reg:CC FLAGS_REG))])]
14771 "TARGET_USE_FANCY_MATH_387
14772 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14773 && flag_unsafe_math_optimizations")
14775 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14776 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14777 (match_operand:MODEF 1 "register_operand" "")]
14778 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14779 && !flag_trapping_math"
14781 if (TARGET_64BIT && optimize_insn_for_size_p ())
14783 ix86_expand_lfloorceil (operand0, operand1, true);
14787 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14788 (define_insn_and_split "frndintxf2_ceil"
14789 [(set (match_operand:XF 0 "register_operand" "")
14790 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14791 UNSPEC_FRNDINT_CEIL))
14792 (clobber (reg:CC FLAGS_REG))]
14793 "TARGET_USE_FANCY_MATH_387
14794 && flag_unsafe_math_optimizations
14795 && can_create_pseudo_p ()"
14800 ix86_optimize_mode_switching[I387_CEIL] = 1;
14802 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14803 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14805 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14806 operands[2], operands[3]));
14809 [(set_attr "type" "frndint")
14810 (set_attr "i387_cw" "ceil")
14811 (set_attr "mode" "XF")])
14813 (define_insn "frndintxf2_ceil_i387"
14814 [(set (match_operand:XF 0 "register_operand" "=f")
14815 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14816 UNSPEC_FRNDINT_CEIL))
14817 (use (match_operand:HI 2 "memory_operand" "m"))
14818 (use (match_operand:HI 3 "memory_operand" "m"))]
14819 "TARGET_USE_FANCY_MATH_387
14820 && flag_unsafe_math_optimizations"
14821 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14822 [(set_attr "type" "frndint")
14823 (set_attr "i387_cw" "ceil")
14824 (set_attr "mode" "XF")])
14826 (define_expand "ceilxf2"
14827 [(use (match_operand:XF 0 "register_operand" ""))
14828 (use (match_operand:XF 1 "register_operand" ""))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && flag_unsafe_math_optimizations"
14832 if (optimize_insn_for_size_p ())
14834 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14838 (define_expand "ceil<mode>2"
14839 [(use (match_operand:MODEF 0 "register_operand" ""))
14840 (use (match_operand:MODEF 1 "register_operand" ""))]
14841 "(TARGET_USE_FANCY_MATH_387
14842 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14843 || TARGET_MIX_SSE_I387)
14844 && flag_unsafe_math_optimizations)
14845 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14846 && !flag_trapping_math)"
14848 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14849 && !flag_trapping_math
14850 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14853 emit_insn (gen_sse4_1_round<mode>2
14854 (operands[0], operands[1], GEN_INT (0x02)));
14855 else if (optimize_insn_for_size_p ())
14857 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14858 ix86_expand_floorceil (operand0, operand1, false);
14860 ix86_expand_floorceildf_32 (operand0, operand1, false);
14866 if (optimize_insn_for_size_p ())
14869 op0 = gen_reg_rtx (XFmode);
14870 op1 = gen_reg_rtx (XFmode);
14871 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14872 emit_insn (gen_frndintxf2_ceil (op0, op1));
14874 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14879 (define_insn_and_split "*fist<mode>2_ceil_1"
14880 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14881 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14883 (clobber (reg:CC FLAGS_REG))]
14884 "TARGET_USE_FANCY_MATH_387
14885 && flag_unsafe_math_optimizations
14886 && can_create_pseudo_p ()"
14891 ix86_optimize_mode_switching[I387_CEIL] = 1;
14893 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14894 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14895 if (memory_operand (operands[0], VOIDmode))
14896 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14897 operands[2], operands[3]));
14900 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14901 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14902 operands[2], operands[3],
14907 [(set_attr "type" "fistp")
14908 (set_attr "i387_cw" "ceil")
14909 (set_attr "mode" "<MODE>")])
14911 (define_insn "fistdi2_ceil"
14912 [(set (match_operand:DI 0 "memory_operand" "=m")
14913 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14915 (use (match_operand:HI 2 "memory_operand" "m"))
14916 (use (match_operand:HI 3 "memory_operand" "m"))
14917 (clobber (match_scratch:XF 4 "=&1f"))]
14918 "TARGET_USE_FANCY_MATH_387
14919 && flag_unsafe_math_optimizations"
14920 "* return output_fix_trunc (insn, operands, 0);"
14921 [(set_attr "type" "fistp")
14922 (set_attr "i387_cw" "ceil")
14923 (set_attr "mode" "DI")])
14925 (define_insn "fistdi2_ceil_with_temp"
14926 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14927 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14929 (use (match_operand:HI 2 "memory_operand" "m,m"))
14930 (use (match_operand:HI 3 "memory_operand" "m,m"))
14931 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14932 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14933 "TARGET_USE_FANCY_MATH_387
14934 && flag_unsafe_math_optimizations"
14936 [(set_attr "type" "fistp")
14937 (set_attr "i387_cw" "ceil")
14938 (set_attr "mode" "DI")])
14941 [(set (match_operand:DI 0 "register_operand" "")
14942 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14944 (use (match_operand:HI 2 "memory_operand" ""))
14945 (use (match_operand:HI 3 "memory_operand" ""))
14946 (clobber (match_operand:DI 4 "memory_operand" ""))
14947 (clobber (match_scratch 5 ""))]
14949 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14950 (use (match_dup 2))
14951 (use (match_dup 3))
14952 (clobber (match_dup 5))])
14953 (set (match_dup 0) (match_dup 4))])
14956 [(set (match_operand:DI 0 "memory_operand" "")
14957 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14959 (use (match_operand:HI 2 "memory_operand" ""))
14960 (use (match_operand:HI 3 "memory_operand" ""))
14961 (clobber (match_operand:DI 4 "memory_operand" ""))
14962 (clobber (match_scratch 5 ""))]
14964 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14965 (use (match_dup 2))
14966 (use (match_dup 3))
14967 (clobber (match_dup 5))])])
14969 (define_insn "fist<mode>2_ceil"
14970 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14971 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14973 (use (match_operand:HI 2 "memory_operand" "m"))
14974 (use (match_operand:HI 3 "memory_operand" "m"))]
14975 "TARGET_USE_FANCY_MATH_387
14976 && flag_unsafe_math_optimizations"
14977 "* return output_fix_trunc (insn, operands, 0);"
14978 [(set_attr "type" "fistp")
14979 (set_attr "i387_cw" "ceil")
14980 (set_attr "mode" "<MODE>")])
14982 (define_insn "fist<mode>2_ceil_with_temp"
14983 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14984 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14986 (use (match_operand:HI 2 "memory_operand" "m,m"))
14987 (use (match_operand:HI 3 "memory_operand" "m,m"))
14988 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14989 "TARGET_USE_FANCY_MATH_387
14990 && flag_unsafe_math_optimizations"
14992 [(set_attr "type" "fistp")
14993 (set_attr "i387_cw" "ceil")
14994 (set_attr "mode" "<MODE>")])
14997 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14998 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15000 (use (match_operand:HI 2 "memory_operand" ""))
15001 (use (match_operand:HI 3 "memory_operand" ""))
15002 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15004 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15006 (use (match_dup 2))
15007 (use (match_dup 3))])
15008 (set (match_dup 0) (match_dup 4))])
15011 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15012 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15014 (use (match_operand:HI 2 "memory_operand" ""))
15015 (use (match_operand:HI 3 "memory_operand" ""))
15016 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15018 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15020 (use (match_dup 2))
15021 (use (match_dup 3))])])
15023 (define_expand "lceilxf<mode>2"
15024 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15025 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15027 (clobber (reg:CC FLAGS_REG))])]
15028 "TARGET_USE_FANCY_MATH_387
15029 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15030 && flag_unsafe_math_optimizations")
15032 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15033 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15034 (match_operand:MODEF 1 "register_operand" "")]
15035 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15036 && !flag_trapping_math"
15038 ix86_expand_lfloorceil (operand0, operand1, false);
15042 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15043 (define_insn_and_split "frndintxf2_trunc"
15044 [(set (match_operand:XF 0 "register_operand" "")
15045 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15046 UNSPEC_FRNDINT_TRUNC))
15047 (clobber (reg:CC FLAGS_REG))]
15048 "TARGET_USE_FANCY_MATH_387
15049 && flag_unsafe_math_optimizations
15050 && can_create_pseudo_p ()"
15055 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15057 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15058 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15060 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15061 operands[2], operands[3]));
15064 [(set_attr "type" "frndint")
15065 (set_attr "i387_cw" "trunc")
15066 (set_attr "mode" "XF")])
15068 (define_insn "frndintxf2_trunc_i387"
15069 [(set (match_operand:XF 0 "register_operand" "=f")
15070 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15071 UNSPEC_FRNDINT_TRUNC))
15072 (use (match_operand:HI 2 "memory_operand" "m"))
15073 (use (match_operand:HI 3 "memory_operand" "m"))]
15074 "TARGET_USE_FANCY_MATH_387
15075 && flag_unsafe_math_optimizations"
15076 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15077 [(set_attr "type" "frndint")
15078 (set_attr "i387_cw" "trunc")
15079 (set_attr "mode" "XF")])
15081 (define_expand "btruncxf2"
15082 [(use (match_operand:XF 0 "register_operand" ""))
15083 (use (match_operand:XF 1 "register_operand" ""))]
15084 "TARGET_USE_FANCY_MATH_387
15085 && flag_unsafe_math_optimizations"
15087 if (optimize_insn_for_size_p ())
15089 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15093 (define_expand "btrunc<mode>2"
15094 [(use (match_operand:MODEF 0 "register_operand" ""))
15095 (use (match_operand:MODEF 1 "register_operand" ""))]
15096 "(TARGET_USE_FANCY_MATH_387
15097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15098 || TARGET_MIX_SSE_I387)
15099 && flag_unsafe_math_optimizations)
15100 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15101 && !flag_trapping_math)"
15103 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15104 && !flag_trapping_math
15105 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15108 emit_insn (gen_sse4_1_round<mode>2
15109 (operands[0], operands[1], GEN_INT (0x03)));
15110 else if (optimize_insn_for_size_p ())
15112 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15113 ix86_expand_trunc (operand0, operand1);
15115 ix86_expand_truncdf_32 (operand0, operand1);
15121 if (optimize_insn_for_size_p ())
15124 op0 = gen_reg_rtx (XFmode);
15125 op1 = gen_reg_rtx (XFmode);
15126 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15127 emit_insn (gen_frndintxf2_trunc (op0, op1));
15129 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15134 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15135 (define_insn_and_split "frndintxf2_mask_pm"
15136 [(set (match_operand:XF 0 "register_operand" "")
15137 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15138 UNSPEC_FRNDINT_MASK_PM))
15139 (clobber (reg:CC FLAGS_REG))]
15140 "TARGET_USE_FANCY_MATH_387
15141 && flag_unsafe_math_optimizations
15142 && can_create_pseudo_p ()"
15147 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15149 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15150 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15152 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15153 operands[2], operands[3]));
15156 [(set_attr "type" "frndint")
15157 (set_attr "i387_cw" "mask_pm")
15158 (set_attr "mode" "XF")])
15160 (define_insn "frndintxf2_mask_pm_i387"
15161 [(set (match_operand:XF 0 "register_operand" "=f")
15162 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15163 UNSPEC_FRNDINT_MASK_PM))
15164 (use (match_operand:HI 2 "memory_operand" "m"))
15165 (use (match_operand:HI 3 "memory_operand" "m"))]
15166 "TARGET_USE_FANCY_MATH_387
15167 && flag_unsafe_math_optimizations"
15168 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15169 [(set_attr "type" "frndint")
15170 (set_attr "i387_cw" "mask_pm")
15171 (set_attr "mode" "XF")])
15173 (define_expand "nearbyintxf2"
15174 [(use (match_operand:XF 0 "register_operand" ""))
15175 (use (match_operand:XF 1 "register_operand" ""))]
15176 "TARGET_USE_FANCY_MATH_387
15177 && flag_unsafe_math_optimizations"
15179 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15183 (define_expand "nearbyint<mode>2"
15184 [(use (match_operand:MODEF 0 "register_operand" ""))
15185 (use (match_operand:MODEF 1 "register_operand" ""))]
15186 "TARGET_USE_FANCY_MATH_387
15187 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15188 || TARGET_MIX_SSE_I387)
15189 && flag_unsafe_math_optimizations"
15191 rtx op0 = gen_reg_rtx (XFmode);
15192 rtx op1 = gen_reg_rtx (XFmode);
15194 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15195 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15197 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15201 (define_insn "fxam<mode>2_i387"
15202 [(set (match_operand:HI 0 "register_operand" "=a")
15204 [(match_operand:X87MODEF 1 "register_operand" "f")]
15206 "TARGET_USE_FANCY_MATH_387"
15207 "fxam\n\tfnstsw\t%0"
15208 [(set_attr "type" "multi")
15209 (set_attr "length" "4")
15210 (set_attr "unit" "i387")
15211 (set_attr "mode" "<MODE>")])
15213 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15214 [(set (match_operand:HI 0 "register_operand" "")
15216 [(match_operand:MODEF 1 "memory_operand" "")]
15218 "TARGET_USE_FANCY_MATH_387
15219 && can_create_pseudo_p ()"
15222 [(set (match_dup 2)(match_dup 1))
15224 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15226 operands[2] = gen_reg_rtx (<MODE>mode);
15228 MEM_VOLATILE_P (operands[1]) = 1;
15230 [(set_attr "type" "multi")
15231 (set_attr "unit" "i387")
15232 (set_attr "mode" "<MODE>")])
15234 (define_expand "isinfxf2"
15235 [(use (match_operand:SI 0 "register_operand" ""))
15236 (use (match_operand:XF 1 "register_operand" ""))]
15237 "TARGET_USE_FANCY_MATH_387
15238 && TARGET_C99_FUNCTIONS"
15240 rtx mask = GEN_INT (0x45);
15241 rtx val = GEN_INT (0x05);
15245 rtx scratch = gen_reg_rtx (HImode);
15246 rtx res = gen_reg_rtx (QImode);
15248 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15250 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15251 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15252 cond = gen_rtx_fmt_ee (EQ, QImode,
15253 gen_rtx_REG (CCmode, FLAGS_REG),
15255 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15256 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15260 (define_expand "isinf<mode>2"
15261 [(use (match_operand:SI 0 "register_operand" ""))
15262 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15263 "TARGET_USE_FANCY_MATH_387
15264 && TARGET_C99_FUNCTIONS
15265 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15267 rtx mask = GEN_INT (0x45);
15268 rtx val = GEN_INT (0x05);
15272 rtx scratch = gen_reg_rtx (HImode);
15273 rtx res = gen_reg_rtx (QImode);
15275 /* Remove excess precision by forcing value through memory. */
15276 if (memory_operand (operands[1], VOIDmode))
15277 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15280 enum ix86_stack_slot slot = (virtuals_instantiated
15283 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15285 emit_move_insn (temp, operands[1]);
15286 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15289 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15290 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15291 cond = gen_rtx_fmt_ee (EQ, QImode,
15292 gen_rtx_REG (CCmode, FLAGS_REG),
15294 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15295 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15299 (define_expand "signbitxf2"
15300 [(use (match_operand:SI 0 "register_operand" ""))
15301 (use (match_operand:XF 1 "register_operand" ""))]
15302 "TARGET_USE_FANCY_MATH_387"
15304 rtx scratch = gen_reg_rtx (HImode);
15306 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15307 emit_insn (gen_andsi3 (operands[0],
15308 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15312 (define_insn "movmsk_df"
15313 [(set (match_operand:SI 0 "register_operand" "=r")
15315 [(match_operand:DF 1 "register_operand" "x")]
15317 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15318 "%vmovmskpd\t{%1, %0|%0, %1}"
15319 [(set_attr "type" "ssemov")
15320 (set_attr "prefix" "maybe_vex")
15321 (set_attr "mode" "DF")])
15323 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15324 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15325 (define_expand "signbitdf2"
15326 [(use (match_operand:SI 0 "register_operand" ""))
15327 (use (match_operand:DF 1 "register_operand" ""))]
15328 "TARGET_USE_FANCY_MATH_387
15329 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15331 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15333 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15334 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15338 rtx scratch = gen_reg_rtx (HImode);
15340 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15341 emit_insn (gen_andsi3 (operands[0],
15342 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15347 (define_expand "signbitsf2"
15348 [(use (match_operand:SI 0 "register_operand" ""))
15349 (use (match_operand:SF 1 "register_operand" ""))]
15350 "TARGET_USE_FANCY_MATH_387
15351 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15353 rtx scratch = gen_reg_rtx (HImode);
15355 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15356 emit_insn (gen_andsi3 (operands[0],
15357 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15361 ;; Block operation instructions
15364 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15367 [(set_attr "length" "1")
15368 (set_attr "length_immediate" "0")
15369 (set_attr "modrm" "0")])
15371 (define_expand "movmem<mode>"
15372 [(use (match_operand:BLK 0 "memory_operand" ""))
15373 (use (match_operand:BLK 1 "memory_operand" ""))
15374 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15375 (use (match_operand:SWI48 3 "const_int_operand" ""))
15376 (use (match_operand:SI 4 "const_int_operand" ""))
15377 (use (match_operand:SI 5 "const_int_operand" ""))]
15380 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15381 operands[4], operands[5]))
15387 ;; Most CPUs don't like single string operations
15388 ;; Handle this case here to simplify previous expander.
15390 (define_expand "strmov"
15391 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15392 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15393 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15394 (clobber (reg:CC FLAGS_REG))])
15395 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15396 (clobber (reg:CC FLAGS_REG))])]
15399 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15401 /* If .md ever supports :P for Pmode, these can be directly
15402 in the pattern above. */
15403 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15404 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15406 /* Can't use this if the user has appropriated esi or edi. */
15407 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15408 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15410 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15411 operands[2], operands[3],
15412 operands[5], operands[6]));
15416 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15419 (define_expand "strmov_singleop"
15420 [(parallel [(set (match_operand 1 "memory_operand" "")
15421 (match_operand 3 "memory_operand" ""))
15422 (set (match_operand 0 "register_operand" "")
15423 (match_operand 4 "" ""))
15424 (set (match_operand 2 "register_operand" "")
15425 (match_operand 5 "" ""))])]
15427 "ix86_current_function_needs_cld = 1;")
15429 (define_insn "*strmovdi_rex_1"
15430 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15431 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15432 (set (match_operand:DI 0 "register_operand" "=D")
15433 (plus:DI (match_dup 2)
15435 (set (match_operand:DI 1 "register_operand" "=S")
15436 (plus:DI (match_dup 3)
15440 [(set_attr "type" "str")
15441 (set_attr "memory" "both")
15442 (set_attr "mode" "DI")])
15444 (define_insn "*strmovsi_1"
15445 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15446 (mem:SI (match_operand:P 3 "register_operand" "1")))
15447 (set (match_operand:P 0 "register_operand" "=D")
15448 (plus:P (match_dup 2)
15450 (set (match_operand:P 1 "register_operand" "=S")
15451 (plus:P (match_dup 3)
15455 [(set_attr "type" "str")
15456 (set_attr "memory" "both")
15457 (set_attr "mode" "SI")])
15459 (define_insn "*strmovhi_1"
15460 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15461 (mem:HI (match_operand:P 3 "register_operand" "1")))
15462 (set (match_operand:P 0 "register_operand" "=D")
15463 (plus:P (match_dup 2)
15465 (set (match_operand:P 1 "register_operand" "=S")
15466 (plus:P (match_dup 3)
15470 [(set_attr "type" "str")
15471 (set_attr "memory" "both")
15472 (set_attr "mode" "HI")])
15474 (define_insn "*strmovqi_1"
15475 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15476 (mem:QI (match_operand:P 3 "register_operand" "1")))
15477 (set (match_operand:P 0 "register_operand" "=D")
15478 (plus:P (match_dup 2)
15480 (set (match_operand:P 1 "register_operand" "=S")
15481 (plus:P (match_dup 3)
15485 [(set_attr "type" "str")
15486 (set_attr "memory" "both")
15487 (set (attr "prefix_rex")
15489 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15491 (const_string "*")))
15492 (set_attr "mode" "QI")])
15494 (define_expand "rep_mov"
15495 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15496 (set (match_operand 0 "register_operand" "")
15497 (match_operand 5 "" ""))
15498 (set (match_operand 2 "register_operand" "")
15499 (match_operand 6 "" ""))
15500 (set (match_operand 1 "memory_operand" "")
15501 (match_operand 3 "memory_operand" ""))
15502 (use (match_dup 4))])]
15504 "ix86_current_function_needs_cld = 1;")
15506 (define_insn "*rep_movdi_rex64"
15507 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15508 (set (match_operand:DI 0 "register_operand" "=D")
15509 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15511 (match_operand:DI 3 "register_operand" "0")))
15512 (set (match_operand:DI 1 "register_operand" "=S")
15513 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15514 (match_operand:DI 4 "register_operand" "1")))
15515 (set (mem:BLK (match_dup 3))
15516 (mem:BLK (match_dup 4)))
15517 (use (match_dup 5))]
15520 [(set_attr "type" "str")
15521 (set_attr "prefix_rep" "1")
15522 (set_attr "memory" "both")
15523 (set_attr "mode" "DI")])
15525 (define_insn "*rep_movsi"
15526 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15527 (set (match_operand:P 0 "register_operand" "=D")
15528 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15530 (match_operand:P 3 "register_operand" "0")))
15531 (set (match_operand:P 1 "register_operand" "=S")
15532 (plus:P (ashift:P (match_dup 5) (const_int 2))
15533 (match_operand:P 4 "register_operand" "1")))
15534 (set (mem:BLK (match_dup 3))
15535 (mem:BLK (match_dup 4)))
15536 (use (match_dup 5))]
15538 "rep{%;} movs{l|d}"
15539 [(set_attr "type" "str")
15540 (set_attr "prefix_rep" "1")
15541 (set_attr "memory" "both")
15542 (set_attr "mode" "SI")])
15544 (define_insn "*rep_movqi"
15545 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15546 (set (match_operand:P 0 "register_operand" "=D")
15547 (plus:P (match_operand:P 3 "register_operand" "0")
15548 (match_operand:P 5 "register_operand" "2")))
15549 (set (match_operand:P 1 "register_operand" "=S")
15550 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15551 (set (mem:BLK (match_dup 3))
15552 (mem:BLK (match_dup 4)))
15553 (use (match_dup 5))]
15556 [(set_attr "type" "str")
15557 (set_attr "prefix_rep" "1")
15558 (set_attr "memory" "both")
15559 (set_attr "mode" "QI")])
15561 (define_expand "setmem<mode>"
15562 [(use (match_operand:BLK 0 "memory_operand" ""))
15563 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15564 (use (match_operand 2 "const_int_operand" ""))
15565 (use (match_operand 3 "const_int_operand" ""))
15566 (use (match_operand:SI 4 "const_int_operand" ""))
15567 (use (match_operand:SI 5 "const_int_operand" ""))]
15570 if (ix86_expand_setmem (operands[0], operands[1],
15571 operands[2], operands[3],
15572 operands[4], operands[5]))
15578 ;; Most CPUs don't like single string operations
15579 ;; Handle this case here to simplify previous expander.
15581 (define_expand "strset"
15582 [(set (match_operand 1 "memory_operand" "")
15583 (match_operand 2 "register_operand" ""))
15584 (parallel [(set (match_operand 0 "register_operand" "")
15586 (clobber (reg:CC FLAGS_REG))])]
15589 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15590 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15592 /* If .md ever supports :P for Pmode, this can be directly
15593 in the pattern above. */
15594 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15595 GEN_INT (GET_MODE_SIZE (GET_MODE
15597 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15599 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15605 (define_expand "strset_singleop"
15606 [(parallel [(set (match_operand 1 "memory_operand" "")
15607 (match_operand 2 "register_operand" ""))
15608 (set (match_operand 0 "register_operand" "")
15609 (match_operand 3 "" ""))])]
15611 "ix86_current_function_needs_cld = 1;")
15613 (define_insn "*strsetdi_rex_1"
15614 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15615 (match_operand:DI 2 "register_operand" "a"))
15616 (set (match_operand:DI 0 "register_operand" "=D")
15617 (plus:DI (match_dup 1)
15621 [(set_attr "type" "str")
15622 (set_attr "memory" "store")
15623 (set_attr "mode" "DI")])
15625 (define_insn "*strsetsi_1"
15626 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15627 (match_operand:SI 2 "register_operand" "a"))
15628 (set (match_operand:P 0 "register_operand" "=D")
15629 (plus:P (match_dup 1)
15633 [(set_attr "type" "str")
15634 (set_attr "memory" "store")
15635 (set_attr "mode" "SI")])
15637 (define_insn "*strsethi_1"
15638 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15639 (match_operand:HI 2 "register_operand" "a"))
15640 (set (match_operand:P 0 "register_operand" "=D")
15641 (plus:P (match_dup 1)
15645 [(set_attr "type" "str")
15646 (set_attr "memory" "store")
15647 (set_attr "mode" "HI")])
15649 (define_insn "*strsetqi_1"
15650 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15651 (match_operand:QI 2 "register_operand" "a"))
15652 (set (match_operand:P 0 "register_operand" "=D")
15653 (plus:P (match_dup 1)
15657 [(set_attr "type" "str")
15658 (set_attr "memory" "store")
15659 (set (attr "prefix_rex")
15661 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15663 (const_string "*")))
15664 (set_attr "mode" "QI")])
15666 (define_expand "rep_stos"
15667 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15668 (set (match_operand 0 "register_operand" "")
15669 (match_operand 4 "" ""))
15670 (set (match_operand 2 "memory_operand" "") (const_int 0))
15671 (use (match_operand 3 "register_operand" ""))
15672 (use (match_dup 1))])]
15674 "ix86_current_function_needs_cld = 1;")
15676 (define_insn "*rep_stosdi_rex64"
15677 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15678 (set (match_operand:DI 0 "register_operand" "=D")
15679 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15681 (match_operand:DI 3 "register_operand" "0")))
15682 (set (mem:BLK (match_dup 3))
15684 (use (match_operand:DI 2 "register_operand" "a"))
15685 (use (match_dup 4))]
15688 [(set_attr "type" "str")
15689 (set_attr "prefix_rep" "1")
15690 (set_attr "memory" "store")
15691 (set_attr "mode" "DI")])
15693 (define_insn "*rep_stossi"
15694 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15695 (set (match_operand:P 0 "register_operand" "=D")
15696 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15698 (match_operand:P 3 "register_operand" "0")))
15699 (set (mem:BLK (match_dup 3))
15701 (use (match_operand:SI 2 "register_operand" "a"))
15702 (use (match_dup 4))]
15704 "rep{%;} stos{l|d}"
15705 [(set_attr "type" "str")
15706 (set_attr "prefix_rep" "1")
15707 (set_attr "memory" "store")
15708 (set_attr "mode" "SI")])
15710 (define_insn "*rep_stosqi"
15711 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15712 (set (match_operand:P 0 "register_operand" "=D")
15713 (plus:P (match_operand:P 3 "register_operand" "0")
15714 (match_operand:P 4 "register_operand" "1")))
15715 (set (mem:BLK (match_dup 3))
15717 (use (match_operand:QI 2 "register_operand" "a"))
15718 (use (match_dup 4))]
15721 [(set_attr "type" "str")
15722 (set_attr "prefix_rep" "1")
15723 (set_attr "memory" "store")
15724 (set (attr "prefix_rex")
15726 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15728 (const_string "*")))
15729 (set_attr "mode" "QI")])
15731 (define_expand "cmpstrnsi"
15732 [(set (match_operand:SI 0 "register_operand" "")
15733 (compare:SI (match_operand:BLK 1 "general_operand" "")
15734 (match_operand:BLK 2 "general_operand" "")))
15735 (use (match_operand 3 "general_operand" ""))
15736 (use (match_operand 4 "immediate_operand" ""))]
15739 rtx addr1, addr2, out, outlow, count, countreg, align;
15741 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15744 /* Can't use this if the user has appropriated esi or edi. */
15745 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15750 out = gen_reg_rtx (SImode);
15752 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15753 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15754 if (addr1 != XEXP (operands[1], 0))
15755 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15756 if (addr2 != XEXP (operands[2], 0))
15757 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15759 count = operands[3];
15760 countreg = ix86_zero_extend_to_Pmode (count);
15762 /* %%% Iff we are testing strict equality, we can use known alignment
15763 to good advantage. This may be possible with combine, particularly
15764 once cc0 is dead. */
15765 align = operands[4];
15767 if (CONST_INT_P (count))
15769 if (INTVAL (count) == 0)
15771 emit_move_insn (operands[0], const0_rtx);
15774 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15775 operands[1], operands[2]));
15779 rtx (*gen_cmp) (rtx, rtx);
15781 gen_cmp = (TARGET_64BIT
15782 ? gen_cmpdi_1 : gen_cmpsi_1);
15784 emit_insn (gen_cmp (countreg, countreg));
15785 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15786 operands[1], operands[2]));
15789 outlow = gen_lowpart (QImode, out);
15790 emit_insn (gen_cmpintqi (outlow));
15791 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15793 if (operands[0] != out)
15794 emit_move_insn (operands[0], out);
15799 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15801 (define_expand "cmpintqi"
15802 [(set (match_dup 1)
15803 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15805 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15806 (parallel [(set (match_operand:QI 0 "register_operand" "")
15807 (minus:QI (match_dup 1)
15809 (clobber (reg:CC FLAGS_REG))])]
15812 operands[1] = gen_reg_rtx (QImode);
15813 operands[2] = gen_reg_rtx (QImode);
15816 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15817 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15819 (define_expand "cmpstrnqi_nz_1"
15820 [(parallel [(set (reg:CC FLAGS_REG)
15821 (compare:CC (match_operand 4 "memory_operand" "")
15822 (match_operand 5 "memory_operand" "")))
15823 (use (match_operand 2 "register_operand" ""))
15824 (use (match_operand:SI 3 "immediate_operand" ""))
15825 (clobber (match_operand 0 "register_operand" ""))
15826 (clobber (match_operand 1 "register_operand" ""))
15827 (clobber (match_dup 2))])]
15829 "ix86_current_function_needs_cld = 1;")
15831 (define_insn "*cmpstrnqi_nz_1"
15832 [(set (reg:CC FLAGS_REG)
15833 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15834 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15835 (use (match_operand:P 6 "register_operand" "2"))
15836 (use (match_operand:SI 3 "immediate_operand" "i"))
15837 (clobber (match_operand:P 0 "register_operand" "=S"))
15838 (clobber (match_operand:P 1 "register_operand" "=D"))
15839 (clobber (match_operand:P 2 "register_operand" "=c"))]
15842 [(set_attr "type" "str")
15843 (set_attr "mode" "QI")
15844 (set (attr "prefix_rex")
15846 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15848 (const_string "*")))
15849 (set_attr "prefix_rep" "1")])
15851 ;; The same, but the count is not known to not be zero.
15853 (define_expand "cmpstrnqi_1"
15854 [(parallel [(set (reg:CC FLAGS_REG)
15855 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15857 (compare:CC (match_operand 4 "memory_operand" "")
15858 (match_operand 5 "memory_operand" ""))
15860 (use (match_operand:SI 3 "immediate_operand" ""))
15861 (use (reg:CC FLAGS_REG))
15862 (clobber (match_operand 0 "register_operand" ""))
15863 (clobber (match_operand 1 "register_operand" ""))
15864 (clobber (match_dup 2))])]
15866 "ix86_current_function_needs_cld = 1;")
15868 (define_insn "*cmpstrnqi_1"
15869 [(set (reg:CC FLAGS_REG)
15870 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15872 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15873 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15875 (use (match_operand:SI 3 "immediate_operand" "i"))
15876 (use (reg:CC FLAGS_REG))
15877 (clobber (match_operand:P 0 "register_operand" "=S"))
15878 (clobber (match_operand:P 1 "register_operand" "=D"))
15879 (clobber (match_operand:P 2 "register_operand" "=c"))]
15882 [(set_attr "type" "str")
15883 (set_attr "mode" "QI")
15884 (set (attr "prefix_rex")
15886 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15888 (const_string "*")))
15889 (set_attr "prefix_rep" "1")])
15891 (define_expand "strlen<mode>"
15892 [(set (match_operand:SWI48x 0 "register_operand" "")
15893 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15894 (match_operand:QI 2 "immediate_operand" "")
15895 (match_operand 3 "immediate_operand" "")]
15899 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15905 (define_expand "strlenqi_1"
15906 [(parallel [(set (match_operand 0 "register_operand" "")
15907 (match_operand 2 "" ""))
15908 (clobber (match_operand 1 "register_operand" ""))
15909 (clobber (reg:CC FLAGS_REG))])]
15911 "ix86_current_function_needs_cld = 1;")
15913 (define_insn "*strlenqi_1"
15914 [(set (match_operand:P 0 "register_operand" "=&c")
15915 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15916 (match_operand:QI 2 "register_operand" "a")
15917 (match_operand:P 3 "immediate_operand" "i")
15918 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15919 (clobber (match_operand:P 1 "register_operand" "=D"))
15920 (clobber (reg:CC FLAGS_REG))]
15923 [(set_attr "type" "str")
15924 (set_attr "mode" "QI")
15925 (set (attr "prefix_rex")
15927 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15929 (const_string "*")))
15930 (set_attr "prefix_rep" "1")])
15932 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15933 ;; handled in combine, but it is not currently up to the task.
15934 ;; When used for their truth value, the cmpstrn* expanders generate
15943 ;; The intermediate three instructions are unnecessary.
15945 ;; This one handles cmpstrn*_nz_1...
15948 (set (reg:CC FLAGS_REG)
15949 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15950 (mem:BLK (match_operand 5 "register_operand" ""))))
15951 (use (match_operand 6 "register_operand" ""))
15952 (use (match_operand:SI 3 "immediate_operand" ""))
15953 (clobber (match_operand 0 "register_operand" ""))
15954 (clobber (match_operand 1 "register_operand" ""))
15955 (clobber (match_operand 2 "register_operand" ""))])
15956 (set (match_operand:QI 7 "register_operand" "")
15957 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15958 (set (match_operand:QI 8 "register_operand" "")
15959 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15960 (set (reg FLAGS_REG)
15961 (compare (match_dup 7) (match_dup 8)))
15963 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15965 (set (reg:CC FLAGS_REG)
15966 (compare:CC (mem:BLK (match_dup 4))
15967 (mem:BLK (match_dup 5))))
15968 (use (match_dup 6))
15969 (use (match_dup 3))
15970 (clobber (match_dup 0))
15971 (clobber (match_dup 1))
15972 (clobber (match_dup 2))])])
15974 ;; ...and this one handles cmpstrn*_1.
15977 (set (reg:CC FLAGS_REG)
15978 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15980 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15981 (mem:BLK (match_operand 5 "register_operand" "")))
15983 (use (match_operand:SI 3 "immediate_operand" ""))
15984 (use (reg:CC FLAGS_REG))
15985 (clobber (match_operand 0 "register_operand" ""))
15986 (clobber (match_operand 1 "register_operand" ""))
15987 (clobber (match_operand 2 "register_operand" ""))])
15988 (set (match_operand:QI 7 "register_operand" "")
15989 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15990 (set (match_operand:QI 8 "register_operand" "")
15991 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15992 (set (reg FLAGS_REG)
15993 (compare (match_dup 7) (match_dup 8)))
15995 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15997 (set (reg:CC FLAGS_REG)
15998 (if_then_else:CC (ne (match_dup 6)
16000 (compare:CC (mem:BLK (match_dup 4))
16001 (mem:BLK (match_dup 5)))
16003 (use (match_dup 3))
16004 (use (reg:CC FLAGS_REG))
16005 (clobber (match_dup 0))
16006 (clobber (match_dup 1))
16007 (clobber (match_dup 2))])])
16009 ;; Conditional move instructions.
16011 (define_expand "mov<mode>cc"
16012 [(set (match_operand:SWIM 0 "register_operand" "")
16013 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16014 (match_operand:SWIM 2 "general_operand" "")
16015 (match_operand:SWIM 3 "general_operand" "")))]
16017 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16019 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16020 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16021 ;; So just document what we're doing explicitly.
16023 (define_expand "x86_mov<mode>cc_0_m1"
16025 [(set (match_operand:SWI48 0 "register_operand" "")
16026 (if_then_else:SWI48
16027 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16028 [(match_operand 1 "flags_reg_operand" "")
16032 (clobber (reg:CC FLAGS_REG))])])
16034 (define_insn "*x86_mov<mode>cc_0_m1"
16035 [(set (match_operand:SWI48 0 "register_operand" "=r")
16036 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16037 [(reg FLAGS_REG) (const_int 0)])
16040 (clobber (reg:CC FLAGS_REG))]
16042 "sbb{<imodesuffix>}\t%0, %0"
16043 ; Since we don't have the proper number of operands for an alu insn,
16044 ; fill in all the blanks.
16045 [(set_attr "type" "alu")
16046 (set_attr "use_carry" "1")
16047 (set_attr "pent_pair" "pu")
16048 (set_attr "memory" "none")
16049 (set_attr "imm_disp" "false")
16050 (set_attr "mode" "<MODE>")
16051 (set_attr "length_immediate" "0")])
16053 (define_insn "*x86_mov<mode>cc_0_m1_se"
16054 [(set (match_operand:SWI48 0 "register_operand" "=r")
16055 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16056 [(reg FLAGS_REG) (const_int 0)])
16059 (clobber (reg:CC FLAGS_REG))]
16061 "sbb{<imodesuffix>}\t%0, %0"
16062 [(set_attr "type" "alu")
16063 (set_attr "use_carry" "1")
16064 (set_attr "pent_pair" "pu")
16065 (set_attr "memory" "none")
16066 (set_attr "imm_disp" "false")
16067 (set_attr "mode" "<MODE>")
16068 (set_attr "length_immediate" "0")])
16070 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16071 [(set (match_operand:SWI48 0 "register_operand" "=r")
16072 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16073 [(reg FLAGS_REG) (const_int 0)])))]
16075 "sbb{<imodesuffix>}\t%0, %0"
16076 [(set_attr "type" "alu")
16077 (set_attr "use_carry" "1")
16078 (set_attr "pent_pair" "pu")
16079 (set_attr "memory" "none")
16080 (set_attr "imm_disp" "false")
16081 (set_attr "mode" "<MODE>")
16082 (set_attr "length_immediate" "0")])
16084 (define_insn "*mov<mode>cc_noc"
16085 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16086 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16087 [(reg FLAGS_REG) (const_int 0)])
16088 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16089 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16090 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16092 cmov%O2%C1\t{%2, %0|%0, %2}
16093 cmov%O2%c1\t{%3, %0|%0, %3}"
16094 [(set_attr "type" "icmov")
16095 (set_attr "mode" "<MODE>")])
16097 (define_insn_and_split "*movqicc_noc"
16098 [(set (match_operand:QI 0 "register_operand" "=r,r")
16099 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16100 [(match_operand 4 "flags_reg_operand" "")
16102 (match_operand:QI 2 "register_operand" "r,0")
16103 (match_operand:QI 3 "register_operand" "0,r")))]
16104 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16106 "&& reload_completed"
16107 [(set (match_dup 0)
16108 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16111 "operands[0] = gen_lowpart (SImode, operands[0]);
16112 operands[2] = gen_lowpart (SImode, operands[2]);
16113 operands[3] = gen_lowpart (SImode, operands[3]);"
16114 [(set_attr "type" "icmov")
16115 (set_attr "mode" "SI")])
16117 (define_expand "mov<mode>cc"
16118 [(set (match_operand:X87MODEF 0 "register_operand" "")
16119 (if_then_else:X87MODEF
16120 (match_operand 1 "ix86_fp_comparison_operator" "")
16121 (match_operand:X87MODEF 2 "register_operand" "")
16122 (match_operand:X87MODEF 3 "register_operand" "")))]
16123 "(TARGET_80387 && TARGET_CMOVE)
16124 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16125 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16127 (define_insn "*movxfcc_1"
16128 [(set (match_operand:XF 0 "register_operand" "=f,f")
16129 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16130 [(reg FLAGS_REG) (const_int 0)])
16131 (match_operand:XF 2 "register_operand" "f,0")
16132 (match_operand:XF 3 "register_operand" "0,f")))]
16133 "TARGET_80387 && TARGET_CMOVE"
16135 fcmov%F1\t{%2, %0|%0, %2}
16136 fcmov%f1\t{%3, %0|%0, %3}"
16137 [(set_attr "type" "fcmov")
16138 (set_attr "mode" "XF")])
16140 (define_insn "*movdfcc_1_rex64"
16141 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16142 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16143 [(reg FLAGS_REG) (const_int 0)])
16144 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16145 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16146 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16147 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16149 fcmov%F1\t{%2, %0|%0, %2}
16150 fcmov%f1\t{%3, %0|%0, %3}
16151 cmov%O2%C1\t{%2, %0|%0, %2}
16152 cmov%O2%c1\t{%3, %0|%0, %3}"
16153 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16154 (set_attr "mode" "DF,DF,DI,DI")])
16156 (define_insn "*movdfcc_1"
16157 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16158 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16159 [(reg FLAGS_REG) (const_int 0)])
16160 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16161 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16162 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16163 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16165 fcmov%F1\t{%2, %0|%0, %2}
16166 fcmov%f1\t{%3, %0|%0, %3}
16169 [(set_attr "type" "fcmov,fcmov,multi,multi")
16170 (set_attr "mode" "DF,DF,DI,DI")])
16173 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16174 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16175 [(match_operand 4 "flags_reg_operand" "")
16177 (match_operand:DF 2 "nonimmediate_operand" "")
16178 (match_operand:DF 3 "nonimmediate_operand" "")))]
16179 "!TARGET_64BIT && reload_completed"
16180 [(set (match_dup 2)
16181 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16185 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16189 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16190 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16193 (define_insn "*movsfcc_1_387"
16194 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16195 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16196 [(reg FLAGS_REG) (const_int 0)])
16197 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16198 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16199 "TARGET_80387 && TARGET_CMOVE
16200 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16202 fcmov%F1\t{%2, %0|%0, %2}
16203 fcmov%f1\t{%3, %0|%0, %3}
16204 cmov%O2%C1\t{%2, %0|%0, %2}
16205 cmov%O2%c1\t{%3, %0|%0, %3}"
16206 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16207 (set_attr "mode" "SF,SF,SI,SI")])
16209 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16210 ;; the scalar versions to have only XMM registers as operands.
16212 ;; XOP conditional move
16213 (define_insn "*xop_pcmov_<mode>"
16214 [(set (match_operand:MODEF 0 "register_operand" "=x")
16215 (if_then_else:MODEF
16216 (match_operand:MODEF 1 "register_operand" "x")
16217 (match_operand:MODEF 2 "register_operand" "x")
16218 (match_operand:MODEF 3 "register_operand" "x")))]
16220 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16221 [(set_attr "type" "sse4arg")])
16223 ;; These versions of the min/max patterns are intentionally ignorant of
16224 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16225 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16226 ;; are undefined in this condition, we're certain this is correct.
16228 (define_insn "*avx_<code><mode>3"
16229 [(set (match_operand:MODEF 0 "register_operand" "=x")
16231 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16232 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16233 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16234 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16235 [(set_attr "type" "sseadd")
16236 (set_attr "prefix" "vex")
16237 (set_attr "mode" "<MODE>")])
16239 (define_insn "<code><mode>3"
16240 [(set (match_operand:MODEF 0 "register_operand" "=x")
16242 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16243 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16244 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16245 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16246 [(set_attr "type" "sseadd")
16247 (set_attr "mode" "<MODE>")])
16249 ;; These versions of the min/max patterns implement exactly the operations
16250 ;; min = (op1 < op2 ? op1 : op2)
16251 ;; max = (!(op1 < op2) ? op1 : op2)
16252 ;; Their operands are not commutative, and thus they may be used in the
16253 ;; presence of -0.0 and NaN.
16255 (define_insn "*avx_ieee_smin<mode>3"
16256 [(set (match_operand:MODEF 0 "register_operand" "=x")
16258 [(match_operand:MODEF 1 "register_operand" "x")
16259 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16261 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16262 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16263 [(set_attr "type" "sseadd")
16264 (set_attr "prefix" "vex")
16265 (set_attr "mode" "<MODE>")])
16267 (define_insn "*ieee_smin<mode>3"
16268 [(set (match_operand:MODEF 0 "register_operand" "=x")
16270 [(match_operand:MODEF 1 "register_operand" "0")
16271 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16273 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16274 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16275 [(set_attr "type" "sseadd")
16276 (set_attr "mode" "<MODE>")])
16278 (define_insn "*avx_ieee_smax<mode>3"
16279 [(set (match_operand:MODEF 0 "register_operand" "=x")
16281 [(match_operand:MODEF 1 "register_operand" "0")
16282 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16284 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16285 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16286 [(set_attr "type" "sseadd")
16287 (set_attr "prefix" "vex")
16288 (set_attr "mode" "<MODE>")])
16290 (define_insn "*ieee_smax<mode>3"
16291 [(set (match_operand:MODEF 0 "register_operand" "=x")
16293 [(match_operand:MODEF 1 "register_operand" "0")
16294 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16296 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16297 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16298 [(set_attr "type" "sseadd")
16299 (set_attr "mode" "<MODE>")])
16301 ;; Make two stack loads independent:
16303 ;; fld %st(0) -> fld bb
16304 ;; fmul bb fmul %st(1), %st
16306 ;; Actually we only match the last two instructions for simplicity.
16308 [(set (match_operand 0 "fp_register_operand" "")
16309 (match_operand 1 "fp_register_operand" ""))
16311 (match_operator 2 "binary_fp_operator"
16313 (match_operand 3 "memory_operand" "")]))]
16314 "REGNO (operands[0]) != REGNO (operands[1])"
16315 [(set (match_dup 0) (match_dup 3))
16316 (set (match_dup 0) (match_dup 4))]
16318 ;; The % modifier is not operational anymore in peephole2's, so we have to
16319 ;; swap the operands manually in the case of addition and multiplication.
16320 "if (COMMUTATIVE_ARITH_P (operands[2]))
16321 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16322 GET_MODE (operands[2]),
16323 operands[0], operands[1]);
16325 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16326 GET_MODE (operands[2]),
16327 operands[1], operands[0]);")
16329 ;; Conditional addition patterns
16330 (define_expand "add<mode>cc"
16331 [(match_operand:SWI 0 "register_operand" "")
16332 (match_operand 1 "ordered_comparison_operator" "")
16333 (match_operand:SWI 2 "register_operand" "")
16334 (match_operand:SWI 3 "const_int_operand" "")]
16336 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16338 ;; Misc patterns (?)
16340 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16341 ;; Otherwise there will be nothing to keep
16343 ;; [(set (reg ebp) (reg esp))]
16344 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16345 ;; (clobber (eflags)]
16346 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16348 ;; in proper program order.
16350 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16351 [(set (match_operand:P 0 "register_operand" "=r,r")
16352 (plus:P (match_operand:P 1 "register_operand" "0,r")
16353 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16354 (clobber (reg:CC FLAGS_REG))
16355 (clobber (mem:BLK (scratch)))]
16358 switch (get_attr_type (insn))
16361 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16364 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16365 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16366 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16368 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16371 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16372 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16375 [(set (attr "type")
16376 (cond [(and (eq_attr "alternative" "0")
16377 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16378 (const_string "alu")
16379 (match_operand:<MODE> 2 "const0_operand" "")
16380 (const_string "imov")
16382 (const_string "lea")))
16383 (set (attr "length_immediate")
16384 (cond [(eq_attr "type" "imov")
16386 (and (eq_attr "type" "alu")
16387 (match_operand 2 "const128_operand" ""))
16390 (const_string "*")))
16391 (set_attr "mode" "<MODE>")])
16393 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16394 [(set (match_operand:P 0 "register_operand" "=r")
16395 (minus:P (match_operand:P 1 "register_operand" "0")
16396 (match_operand:P 2 "register_operand" "r")))
16397 (clobber (reg:CC FLAGS_REG))
16398 (clobber (mem:BLK (scratch)))]
16400 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16401 [(set_attr "type" "alu")
16402 (set_attr "mode" "<MODE>")])
16404 (define_insn "allocate_stack_worker_probe_<mode>"
16405 [(set (match_operand:P 0 "register_operand" "=a")
16406 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16407 UNSPECV_STACK_PROBE))
16408 (clobber (reg:CC FLAGS_REG))]
16409 "ix86_target_stack_probe ()"
16410 "call\t___chkstk_ms"
16411 [(set_attr "type" "multi")
16412 (set_attr "length" "5")])
16414 (define_expand "allocate_stack"
16415 [(match_operand 0 "register_operand" "")
16416 (match_operand 1 "general_operand" "")]
16417 "ix86_target_stack_probe ()"
16421 #ifndef CHECK_STACK_LIMIT
16422 #define CHECK_STACK_LIMIT 0
16425 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16426 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16428 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16429 stack_pointer_rtx, 0, OPTAB_DIRECT);
16430 if (x != stack_pointer_rtx)
16431 emit_move_insn (stack_pointer_rtx, x);
16435 x = copy_to_mode_reg (Pmode, operands[1]);
16437 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16439 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16440 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16441 stack_pointer_rtx, 0, OPTAB_DIRECT);
16442 if (x != stack_pointer_rtx)
16443 emit_move_insn (stack_pointer_rtx, x);
16446 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16450 ;; Use IOR for stack probes, this is shorter.
16451 (define_expand "probe_stack"
16452 [(match_operand 0 "memory_operand" "")]
16455 rtx (*gen_ior3) (rtx, rtx, rtx);
16457 gen_ior3 = (GET_MODE (operands[0]) == DImode
16458 ? gen_iordi3 : gen_iorsi3);
16460 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16464 (define_insn "adjust_stack_and_probe<mode>"
16465 [(set (match_operand:P 0 "register_operand" "=r")
16466 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16467 UNSPECV_PROBE_STACK_RANGE))
16468 (set (reg:P SP_REG)
16469 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16470 (clobber (reg:CC FLAGS_REG))
16471 (clobber (mem:BLK (scratch)))]
16473 "* return output_adjust_stack_and_probe (operands[0]);"
16474 [(set_attr "type" "multi")])
16476 (define_insn "probe_stack_range<mode>"
16477 [(set (match_operand:P 0 "register_operand" "=r")
16478 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16479 (match_operand:P 2 "const_int_operand" "n")]
16480 UNSPECV_PROBE_STACK_RANGE))
16481 (clobber (reg:CC FLAGS_REG))]
16483 "* return output_probe_stack_range (operands[0], operands[2]);"
16484 [(set_attr "type" "multi")])
16486 (define_expand "builtin_setjmp_receiver"
16487 [(label_ref (match_operand 0 "" ""))]
16488 "!TARGET_64BIT && flag_pic"
16494 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16495 rtx label_rtx = gen_label_rtx ();
16496 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16497 xops[0] = xops[1] = picreg;
16498 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16499 ix86_expand_binary_operator (MINUS, SImode, xops);
16503 emit_insn (gen_set_got (pic_offset_table_rtx));
16507 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16510 [(set (match_operand 0 "register_operand" "")
16511 (match_operator 3 "promotable_binary_operator"
16512 [(match_operand 1 "register_operand" "")
16513 (match_operand 2 "aligned_operand" "")]))
16514 (clobber (reg:CC FLAGS_REG))]
16515 "! TARGET_PARTIAL_REG_STALL && reload_completed
16516 && ((GET_MODE (operands[0]) == HImode
16517 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16518 /* ??? next two lines just !satisfies_constraint_K (...) */
16519 || !CONST_INT_P (operands[2])
16520 || satisfies_constraint_K (operands[2])))
16521 || (GET_MODE (operands[0]) == QImode
16522 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16523 [(parallel [(set (match_dup 0)
16524 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16525 (clobber (reg:CC FLAGS_REG))])]
16526 "operands[0] = gen_lowpart (SImode, operands[0]);
16527 operands[1] = gen_lowpart (SImode, operands[1]);
16528 if (GET_CODE (operands[3]) != ASHIFT)
16529 operands[2] = gen_lowpart (SImode, operands[2]);
16530 PUT_MODE (operands[3], SImode);")
16532 ; Promote the QImode tests, as i386 has encoding of the AND
16533 ; instruction with 32-bit sign-extended immediate and thus the
16534 ; instruction size is unchanged, except in the %eax case for
16535 ; which it is increased by one byte, hence the ! optimize_size.
16537 [(set (match_operand 0 "flags_reg_operand" "")
16538 (match_operator 2 "compare_operator"
16539 [(and (match_operand 3 "aligned_operand" "")
16540 (match_operand 4 "const_int_operand" ""))
16542 (set (match_operand 1 "register_operand" "")
16543 (and (match_dup 3) (match_dup 4)))]
16544 "! TARGET_PARTIAL_REG_STALL && reload_completed
16545 && optimize_insn_for_speed_p ()
16546 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16547 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16548 /* Ensure that the operand will remain sign-extended immediate. */
16549 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16550 [(parallel [(set (match_dup 0)
16551 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16554 (and:SI (match_dup 3) (match_dup 4)))])]
16557 = gen_int_mode (INTVAL (operands[4])
16558 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16559 operands[1] = gen_lowpart (SImode, operands[1]);
16560 operands[3] = gen_lowpart (SImode, operands[3]);
16563 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16564 ; the TEST instruction with 32-bit sign-extended immediate and thus
16565 ; the instruction size would at least double, which is not what we
16566 ; want even with ! optimize_size.
16568 [(set (match_operand 0 "flags_reg_operand" "")
16569 (match_operator 1 "compare_operator"
16570 [(and (match_operand:HI 2 "aligned_operand" "")
16571 (match_operand:HI 3 "const_int_operand" ""))
16573 "! TARGET_PARTIAL_REG_STALL && reload_completed
16574 && ! TARGET_FAST_PREFIX
16575 && optimize_insn_for_speed_p ()
16576 /* Ensure that the operand will remain sign-extended immediate. */
16577 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16578 [(set (match_dup 0)
16579 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16583 = gen_int_mode (INTVAL (operands[3])
16584 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16585 operands[2] = gen_lowpart (SImode, operands[2]);
16589 [(set (match_operand 0 "register_operand" "")
16590 (neg (match_operand 1 "register_operand" "")))
16591 (clobber (reg:CC FLAGS_REG))]
16592 "! TARGET_PARTIAL_REG_STALL && reload_completed
16593 && (GET_MODE (operands[0]) == HImode
16594 || (GET_MODE (operands[0]) == QImode
16595 && (TARGET_PROMOTE_QImode
16596 || optimize_insn_for_size_p ())))"
16597 [(parallel [(set (match_dup 0)
16598 (neg:SI (match_dup 1)))
16599 (clobber (reg:CC FLAGS_REG))])]
16600 "operands[0] = gen_lowpart (SImode, operands[0]);
16601 operands[1] = gen_lowpart (SImode, operands[1]);")
16604 [(set (match_operand 0 "register_operand" "")
16605 (not (match_operand 1 "register_operand" "")))]
16606 "! TARGET_PARTIAL_REG_STALL && reload_completed
16607 && (GET_MODE (operands[0]) == HImode
16608 || (GET_MODE (operands[0]) == QImode
16609 && (TARGET_PROMOTE_QImode
16610 || optimize_insn_for_size_p ())))"
16611 [(set (match_dup 0)
16612 (not:SI (match_dup 1)))]
16613 "operands[0] = gen_lowpart (SImode, operands[0]);
16614 operands[1] = gen_lowpart (SImode, operands[1]);")
16617 [(set (match_operand 0 "register_operand" "")
16618 (if_then_else (match_operator 1 "ordered_comparison_operator"
16619 [(reg FLAGS_REG) (const_int 0)])
16620 (match_operand 2 "register_operand" "")
16621 (match_operand 3 "register_operand" "")))]
16622 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16623 && (GET_MODE (operands[0]) == HImode
16624 || (GET_MODE (operands[0]) == QImode
16625 && (TARGET_PROMOTE_QImode
16626 || optimize_insn_for_size_p ())))"
16627 [(set (match_dup 0)
16628 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16629 "operands[0] = gen_lowpart (SImode, operands[0]);
16630 operands[2] = gen_lowpart (SImode, operands[2]);
16631 operands[3] = gen_lowpart (SImode, operands[3]);")
16633 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16634 ;; transform a complex memory operation into two memory to register operations.
16636 ;; Don't push memory operands
16638 [(set (match_operand:SWI 0 "push_operand" "")
16639 (match_operand:SWI 1 "memory_operand" ""))
16640 (match_scratch:SWI 2 "<r>")]
16641 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16642 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16643 [(set (match_dup 2) (match_dup 1))
16644 (set (match_dup 0) (match_dup 2))])
16646 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16649 [(set (match_operand:SF 0 "push_operand" "")
16650 (match_operand:SF 1 "memory_operand" ""))
16651 (match_scratch:SF 2 "r")]
16652 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16653 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16654 [(set (match_dup 2) (match_dup 1))
16655 (set (match_dup 0) (match_dup 2))])
16657 ;; Don't move an immediate directly to memory when the instruction
16660 [(match_scratch:SWI124 1 "<r>")
16661 (set (match_operand:SWI124 0 "memory_operand" "")
16663 "optimize_insn_for_speed_p ()
16664 && !TARGET_USE_MOV0
16665 && TARGET_SPLIT_LONG_MOVES
16666 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16667 && peep2_regno_dead_p (0, FLAGS_REG)"
16668 [(parallel [(set (match_dup 2) (const_int 0))
16669 (clobber (reg:CC FLAGS_REG))])
16670 (set (match_dup 0) (match_dup 1))]
16671 "operands[2] = gen_lowpart (SImode, operands[1]);")
16674 [(match_scratch:SWI124 2 "<r>")
16675 (set (match_operand:SWI124 0 "memory_operand" "")
16676 (match_operand:SWI124 1 "immediate_operand" ""))]
16677 "optimize_insn_for_speed_p ()
16678 && TARGET_SPLIT_LONG_MOVES
16679 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16680 [(set (match_dup 2) (match_dup 1))
16681 (set (match_dup 0) (match_dup 2))])
16683 ;; Don't compare memory with zero, load and use a test instead.
16685 [(set (match_operand 0 "flags_reg_operand" "")
16686 (match_operator 1 "compare_operator"
16687 [(match_operand:SI 2 "memory_operand" "")
16689 (match_scratch:SI 3 "r")]
16690 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16691 [(set (match_dup 3) (match_dup 2))
16692 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16694 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16695 ;; Don't split NOTs with a displacement operand, because resulting XOR
16696 ;; will not be pairable anyway.
16698 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16699 ;; represented using a modRM byte. The XOR replacement is long decoded,
16700 ;; so this split helps here as well.
16702 ;; Note: Can't do this as a regular split because we can't get proper
16703 ;; lifetime information then.
16706 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16707 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16708 "optimize_insn_for_speed_p ()
16709 && ((TARGET_NOT_UNPAIRABLE
16710 && (!MEM_P (operands[0])
16711 || !memory_displacement_operand (operands[0], <MODE>mode)))
16712 || (TARGET_NOT_VECTORMODE
16713 && long_memory_operand (operands[0], <MODE>mode)))
16714 && peep2_regno_dead_p (0, FLAGS_REG)"
16715 [(parallel [(set (match_dup 0)
16716 (xor:SWI124 (match_dup 1) (const_int -1)))
16717 (clobber (reg:CC FLAGS_REG))])])
16719 ;; Non pairable "test imm, reg" instructions can be translated to
16720 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16721 ;; byte opcode instead of two, have a short form for byte operands),
16722 ;; so do it for other CPUs as well. Given that the value was dead,
16723 ;; this should not create any new dependencies. Pass on the sub-word
16724 ;; versions if we're concerned about partial register stalls.
16727 [(set (match_operand 0 "flags_reg_operand" "")
16728 (match_operator 1 "compare_operator"
16729 [(and:SI (match_operand:SI 2 "register_operand" "")
16730 (match_operand:SI 3 "immediate_operand" ""))
16732 "ix86_match_ccmode (insn, CCNOmode)
16733 && (true_regnum (operands[2]) != AX_REG
16734 || satisfies_constraint_K (operands[3]))
16735 && peep2_reg_dead_p (1, operands[2])"
16737 [(set (match_dup 0)
16738 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16741 (and:SI (match_dup 2) (match_dup 3)))])])
16743 ;; We don't need to handle HImode case, because it will be promoted to SImode
16744 ;; on ! TARGET_PARTIAL_REG_STALL
16747 [(set (match_operand 0 "flags_reg_operand" "")
16748 (match_operator 1 "compare_operator"
16749 [(and:QI (match_operand:QI 2 "register_operand" "")
16750 (match_operand:QI 3 "immediate_operand" ""))
16752 "! TARGET_PARTIAL_REG_STALL
16753 && ix86_match_ccmode (insn, CCNOmode)
16754 && true_regnum (operands[2]) != AX_REG
16755 && peep2_reg_dead_p (1, operands[2])"
16757 [(set (match_dup 0)
16758 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16761 (and:QI (match_dup 2) (match_dup 3)))])])
16764 [(set (match_operand 0 "flags_reg_operand" "")
16765 (match_operator 1 "compare_operator"
16768 (match_operand 2 "ext_register_operand" "")
16771 (match_operand 3 "const_int_operand" ""))
16773 "! TARGET_PARTIAL_REG_STALL
16774 && ix86_match_ccmode (insn, CCNOmode)
16775 && true_regnum (operands[2]) != AX_REG
16776 && peep2_reg_dead_p (1, operands[2])"
16777 [(parallel [(set (match_dup 0)
16786 (set (zero_extract:SI (match_dup 2)
16794 (match_dup 3)))])])
16796 ;; Don't do logical operations with memory inputs.
16798 [(match_scratch:SI 2 "r")
16799 (parallel [(set (match_operand:SI 0 "register_operand" "")
16800 (match_operator:SI 3 "arith_or_logical_operator"
16802 (match_operand:SI 1 "memory_operand" "")]))
16803 (clobber (reg:CC FLAGS_REG))])]
16804 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16805 [(set (match_dup 2) (match_dup 1))
16806 (parallel [(set (match_dup 0)
16807 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16808 (clobber (reg:CC FLAGS_REG))])])
16811 [(match_scratch:SI 2 "r")
16812 (parallel [(set (match_operand:SI 0 "register_operand" "")
16813 (match_operator:SI 3 "arith_or_logical_operator"
16814 [(match_operand:SI 1 "memory_operand" "")
16816 (clobber (reg:CC FLAGS_REG))])]
16817 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16818 [(set (match_dup 2) (match_dup 1))
16819 (parallel [(set (match_dup 0)
16820 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16821 (clobber (reg:CC FLAGS_REG))])])
16823 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16824 ;; refers to the destination of the load!
16827 [(set (match_operand:SI 0 "register_operand" "")
16828 (match_operand:SI 1 "register_operand" ""))
16829 (parallel [(set (match_dup 0)
16830 (match_operator:SI 3 "commutative_operator"
16832 (match_operand:SI 2 "memory_operand" "")]))
16833 (clobber (reg:CC FLAGS_REG))])]
16834 "REGNO (operands[0]) != REGNO (operands[1])
16835 && GENERAL_REGNO_P (REGNO (operands[0]))
16836 && GENERAL_REGNO_P (REGNO (operands[1]))"
16837 [(set (match_dup 0) (match_dup 4))
16838 (parallel [(set (match_dup 0)
16839 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16840 (clobber (reg:CC FLAGS_REG))])]
16841 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16844 [(set (match_operand 0 "register_operand" "")
16845 (match_operand 1 "register_operand" ""))
16847 (match_operator 3 "commutative_operator"
16849 (match_operand 2 "memory_operand" "")]))]
16850 "REGNO (operands[0]) != REGNO (operands[1])
16851 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16852 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16853 [(set (match_dup 0) (match_dup 2))
16855 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16857 ; Don't do logical operations with memory outputs
16859 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16860 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16861 ; the same decoder scheduling characteristics as the original.
16864 [(match_scratch:SI 2 "r")
16865 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16866 (match_operator:SI 3 "arith_or_logical_operator"
16868 (match_operand:SI 1 "nonmemory_operand" "")]))
16869 (clobber (reg:CC FLAGS_REG))])]
16870 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16871 /* Do not split stack checking probes. */
16872 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16873 [(set (match_dup 2) (match_dup 0))
16874 (parallel [(set (match_dup 2)
16875 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16876 (clobber (reg:CC FLAGS_REG))])
16877 (set (match_dup 0) (match_dup 2))])
16880 [(match_scratch:SI 2 "r")
16881 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16882 (match_operator:SI 3 "arith_or_logical_operator"
16883 [(match_operand:SI 1 "nonmemory_operand" "")
16885 (clobber (reg:CC FLAGS_REG))])]
16886 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16887 /* Do not split stack checking probes. */
16888 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16889 [(set (match_dup 2) (match_dup 0))
16890 (parallel [(set (match_dup 2)
16891 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16892 (clobber (reg:CC FLAGS_REG))])
16893 (set (match_dup 0) (match_dup 2))])
16895 ;; Attempt to always use XOR for zeroing registers.
16897 [(set (match_operand 0 "register_operand" "")
16898 (match_operand 1 "const0_operand" ""))]
16899 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16900 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16901 && GENERAL_REG_P (operands[0])
16902 && peep2_regno_dead_p (0, FLAGS_REG)"
16903 [(parallel [(set (match_dup 0) (const_int 0))
16904 (clobber (reg:CC FLAGS_REG))])]
16905 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16908 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16910 "(GET_MODE (operands[0]) == QImode
16911 || GET_MODE (operands[0]) == HImode)
16912 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16913 && peep2_regno_dead_p (0, FLAGS_REG)"
16914 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16915 (clobber (reg:CC FLAGS_REG))])])
16917 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16919 [(set (match_operand:SWI248 0 "register_operand" "")
16921 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16922 && peep2_regno_dead_p (0, FLAGS_REG)"
16923 [(parallel [(set (match_dup 0) (const_int -1))
16924 (clobber (reg:CC FLAGS_REG))])]
16926 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16927 operands[0] = gen_lowpart (SImode, operands[0]);
16930 ;; Attempt to convert simple lea to add/shift.
16931 ;; These can be created by move expanders.
16934 [(set (match_operand:SWI48 0 "register_operand" "")
16935 (plus:SWI48 (match_dup 0)
16936 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16937 "peep2_regno_dead_p (0, FLAGS_REG)"
16938 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16939 (clobber (reg:CC FLAGS_REG))])])
16942 [(set (match_operand:SI 0 "register_operand" "")
16943 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16944 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16946 && peep2_regno_dead_p (0, FLAGS_REG)
16947 && REGNO (operands[0]) == REGNO (operands[1])"
16948 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16949 (clobber (reg:CC FLAGS_REG))])]
16950 "operands[2] = gen_lowpart (SImode, operands[2]);")
16953 [(set (match_operand:SWI48 0 "register_operand" "")
16954 (mult:SWI48 (match_dup 0)
16955 (match_operand:SWI48 1 "const_int_operand" "")))]
16956 "exact_log2 (INTVAL (operands[1])) >= 0
16957 && peep2_regno_dead_p (0, FLAGS_REG)"
16958 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16959 (clobber (reg:CC FLAGS_REG))])]
16960 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16963 [(set (match_operand:SI 0 "register_operand" "")
16964 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16965 (match_operand:DI 2 "const_int_operand" "")) 0))]
16967 && exact_log2 (INTVAL (operands[2])) >= 0
16968 && REGNO (operands[0]) == REGNO (operands[1])
16969 && peep2_regno_dead_p (0, FLAGS_REG)"
16970 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16971 (clobber (reg:CC FLAGS_REG))])]
16972 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16974 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16975 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16976 ;; On many CPUs it is also faster, since special hardware to avoid esp
16977 ;; dependencies is present.
16979 ;; While some of these conversions may be done using splitters, we use
16980 ;; peepholes in order to allow combine_stack_adjustments pass to see
16981 ;; nonobfuscated RTL.
16983 ;; Convert prologue esp subtractions to push.
16984 ;; We need register to push. In order to keep verify_flow_info happy we have
16986 ;; - use scratch and clobber it in order to avoid dependencies
16987 ;; - use already live register
16988 ;; We can't use the second way right now, since there is no reliable way how to
16989 ;; verify that given register is live. First choice will also most likely in
16990 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16991 ;; call clobbered registers are dead. We may want to use base pointer as an
16992 ;; alternative when no register is available later.
16995 [(match_scratch:P 1 "r")
16996 (parallel [(set (reg:P SP_REG)
16997 (plus:P (reg:P SP_REG)
16998 (match_operand:P 0 "const_int_operand" "")))
16999 (clobber (reg:CC FLAGS_REG))
17000 (clobber (mem:BLK (scratch)))])]
17001 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17002 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17003 [(clobber (match_dup 1))
17004 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17005 (clobber (mem:BLK (scratch)))])])
17008 [(match_scratch:P 1 "r")
17009 (parallel [(set (reg:P SP_REG)
17010 (plus:P (reg:P SP_REG)
17011 (match_operand:P 0 "const_int_operand" "")))
17012 (clobber (reg:CC FLAGS_REG))
17013 (clobber (mem:BLK (scratch)))])]
17014 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17015 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17016 [(clobber (match_dup 1))
17017 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17018 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17019 (clobber (mem:BLK (scratch)))])])
17021 ;; Convert esp subtractions to push.
17023 [(match_scratch:P 1 "r")
17024 (parallel [(set (reg:P SP_REG)
17025 (plus:P (reg:P SP_REG)
17026 (match_operand:P 0 "const_int_operand" "")))
17027 (clobber (reg:CC FLAGS_REG))])]
17028 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17029 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17030 [(clobber (match_dup 1))
17031 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17034 [(match_scratch:P 1 "r")
17035 (parallel [(set (reg:P SP_REG)
17036 (plus:P (reg:P SP_REG)
17037 (match_operand:P 0 "const_int_operand" "")))
17038 (clobber (reg:CC FLAGS_REG))])]
17039 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17040 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17041 [(clobber (match_dup 1))
17042 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17043 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17045 ;; Convert epilogue deallocator to pop.
17047 [(match_scratch:P 1 "r")
17048 (parallel [(set (reg:P SP_REG)
17049 (plus:P (reg:P SP_REG)
17050 (match_operand:P 0 "const_int_operand" "")))
17051 (clobber (reg:CC FLAGS_REG))
17052 (clobber (mem:BLK (scratch)))])]
17053 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17054 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17055 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17056 (clobber (mem:BLK (scratch)))])])
17058 ;; Two pops case is tricky, since pop causes dependency
17059 ;; on destination register. We use two registers if available.
17061 [(match_scratch:P 1 "r")
17062 (match_scratch:P 2 "r")
17063 (parallel [(set (reg:P SP_REG)
17064 (plus:P (reg:P SP_REG)
17065 (match_operand:P 0 "const_int_operand" "")))
17066 (clobber (reg:CC FLAGS_REG))
17067 (clobber (mem:BLK (scratch)))])]
17068 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17069 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17070 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17071 (clobber (mem:BLK (scratch)))])
17072 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17075 [(match_scratch:P 1 "r")
17076 (parallel [(set (reg:P SP_REG)
17077 (plus:P (reg:P SP_REG)
17078 (match_operand:P 0 "const_int_operand" "")))
17079 (clobber (reg:CC FLAGS_REG))
17080 (clobber (mem:BLK (scratch)))])]
17081 "optimize_insn_for_size_p ()
17082 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17083 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17084 (clobber (mem:BLK (scratch)))])
17085 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17087 ;; Convert esp additions to pop.
17089 [(match_scratch:P 1 "r")
17090 (parallel [(set (reg:P SP_REG)
17091 (plus:P (reg:P SP_REG)
17092 (match_operand:P 0 "const_int_operand" "")))
17093 (clobber (reg:CC FLAGS_REG))])]
17094 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17095 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17097 ;; Two pops case is tricky, since pop causes dependency
17098 ;; on destination register. We use two registers if available.
17100 [(match_scratch:P 1 "r")
17101 (match_scratch:P 2 "r")
17102 (parallel [(set (reg:P SP_REG)
17103 (plus:P (reg:P SP_REG)
17104 (match_operand:P 0 "const_int_operand" "")))
17105 (clobber (reg:CC FLAGS_REG))])]
17106 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17107 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17108 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17111 [(match_scratch:P 1 "r")
17112 (parallel [(set (reg:P SP_REG)
17113 (plus:P (reg:P SP_REG)
17114 (match_operand:P 0 "const_int_operand" "")))
17115 (clobber (reg:CC FLAGS_REG))])]
17116 "optimize_insn_for_size_p ()
17117 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17118 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17119 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17121 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17122 ;; required and register dies. Similarly for 128 to -128.
17124 [(set (match_operand 0 "flags_reg_operand" "")
17125 (match_operator 1 "compare_operator"
17126 [(match_operand 2 "register_operand" "")
17127 (match_operand 3 "const_int_operand" "")]))]
17128 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17129 && incdec_operand (operands[3], GET_MODE (operands[3])))
17130 || (!TARGET_FUSE_CMP_AND_BRANCH
17131 && INTVAL (operands[3]) == 128))
17132 && ix86_match_ccmode (insn, CCGCmode)
17133 && peep2_reg_dead_p (1, operands[2])"
17134 [(parallel [(set (match_dup 0)
17135 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17136 (clobber (match_dup 2))])])
17138 ;; Convert imul by three, five and nine into lea
17141 [(set (match_operand:SWI48 0 "register_operand" "")
17142 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17143 (match_operand:SWI48 2 "const_int_operand" "")))
17144 (clobber (reg:CC FLAGS_REG))])]
17145 "INTVAL (operands[2]) == 3
17146 || INTVAL (operands[2]) == 5
17147 || INTVAL (operands[2]) == 9"
17148 [(set (match_dup 0)
17149 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17151 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17155 [(set (match_operand:SWI48 0 "register_operand" "")
17156 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17157 (match_operand:SWI48 2 "const_int_operand" "")))
17158 (clobber (reg:CC FLAGS_REG))])]
17159 "optimize_insn_for_speed_p ()
17160 && (INTVAL (operands[2]) == 3
17161 || INTVAL (operands[2]) == 5
17162 || INTVAL (operands[2]) == 9)"
17163 [(set (match_dup 0) (match_dup 1))
17165 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17167 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17169 ;; imul $32bit_imm, mem, reg is vector decoded, while
17170 ;; imul $32bit_imm, reg, reg is direct decoded.
17172 [(match_scratch:SWI48 3 "r")
17173 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17174 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17175 (match_operand:SWI48 2 "immediate_operand" "")))
17176 (clobber (reg:CC FLAGS_REG))])]
17177 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17178 && !satisfies_constraint_K (operands[2])"
17179 [(set (match_dup 3) (match_dup 1))
17180 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17181 (clobber (reg:CC FLAGS_REG))])])
17184 [(match_scratch:SI 3 "r")
17185 (parallel [(set (match_operand:DI 0 "register_operand" "")
17187 (mult:SI (match_operand:SI 1 "memory_operand" "")
17188 (match_operand:SI 2 "immediate_operand" ""))))
17189 (clobber (reg:CC FLAGS_REG))])]
17191 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17192 && !satisfies_constraint_K (operands[2])"
17193 [(set (match_dup 3) (match_dup 1))
17194 (parallel [(set (match_dup 0)
17195 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17196 (clobber (reg:CC FLAGS_REG))])])
17198 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17199 ;; Convert it into imul reg, reg
17200 ;; It would be better to force assembler to encode instruction using long
17201 ;; immediate, but there is apparently no way to do so.
17203 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17205 (match_operand:SWI248 1 "nonimmediate_operand" "")
17206 (match_operand:SWI248 2 "const_int_operand" "")))
17207 (clobber (reg:CC FLAGS_REG))])
17208 (match_scratch:SWI248 3 "r")]
17209 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17210 && satisfies_constraint_K (operands[2])"
17211 [(set (match_dup 3) (match_dup 2))
17212 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17213 (clobber (reg:CC FLAGS_REG))])]
17215 if (!rtx_equal_p (operands[0], operands[1]))
17216 emit_move_insn (operands[0], operands[1]);
17219 ;; After splitting up read-modify operations, array accesses with memory
17220 ;; operands might end up in form:
17222 ;; movl 4(%esp), %edx
17224 ;; instead of pre-splitting:
17226 ;; addl 4(%esp), %eax
17228 ;; movl 4(%esp), %edx
17229 ;; leal (%edx,%eax,4), %eax
17232 [(match_scratch:P 5 "r")
17233 (parallel [(set (match_operand 0 "register_operand" "")
17234 (ashift (match_operand 1 "register_operand" "")
17235 (match_operand 2 "const_int_operand" "")))
17236 (clobber (reg:CC FLAGS_REG))])
17237 (parallel [(set (match_operand 3 "register_operand" "")
17238 (plus (match_dup 0)
17239 (match_operand 4 "x86_64_general_operand" "")))
17240 (clobber (reg:CC FLAGS_REG))])]
17241 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17242 /* Validate MODE for lea. */
17243 && ((!TARGET_PARTIAL_REG_STALL
17244 && (GET_MODE (operands[0]) == QImode
17245 || GET_MODE (operands[0]) == HImode))
17246 || GET_MODE (operands[0]) == SImode
17247 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17248 && (rtx_equal_p (operands[0], operands[3])
17249 || peep2_reg_dead_p (2, operands[0]))
17250 /* We reorder load and the shift. */
17251 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17252 [(set (match_dup 5) (match_dup 4))
17253 (set (match_dup 0) (match_dup 1))]
17255 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17256 int scale = 1 << INTVAL (operands[2]);
17257 rtx index = gen_lowpart (Pmode, operands[1]);
17258 rtx base = gen_lowpart (Pmode, operands[5]);
17259 rtx dest = gen_lowpart (mode, operands[3]);
17261 operands[1] = gen_rtx_PLUS (Pmode, base,
17262 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17263 operands[5] = base;
17266 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17267 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17269 operands[0] = dest;
17272 ;; Call-value patterns last so that the wildcard operand does not
17273 ;; disrupt insn-recog's switch tables.
17275 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17277 [(set (match_operand 0 "" "")
17278 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17279 (match_operand:SI 2 "" "")))
17280 (set (reg:SI SP_REG)
17281 (plus:SI (reg:SI SP_REG)
17282 (match_operand:SI 3 "immediate_operand" "")))])
17283 (unspec [(match_operand 4 "const_int_operand" "")]
17284 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17285 "TARGET_VZEROUPPER && !TARGET_64BIT"
17287 "&& reload_completed"
17289 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17290 [(set_attr "type" "callv")])
17292 (define_insn "*call_value_pop_0"
17293 [(set (match_operand 0 "" "")
17294 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17295 (match_operand:SI 2 "" "")))
17296 (set (reg:SI SP_REG)
17297 (plus:SI (reg:SI SP_REG)
17298 (match_operand:SI 3 "immediate_operand" "")))]
17300 { return ix86_output_call_insn (insn, operands[1], 1); }
17301 [(set_attr "type" "callv")])
17303 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17305 [(set (match_operand 0 "" "")
17306 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17307 (match_operand:SI 2 "" "")))
17308 (set (reg:SI SP_REG)
17309 (plus:SI (reg:SI SP_REG)
17310 (match_operand:SI 3 "immediate_operand" "i")))])
17311 (unspec [(match_operand 4 "const_int_operand" "")]
17312 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17313 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17315 "&& reload_completed"
17317 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17318 [(set_attr "type" "callv")])
17320 (define_insn "*call_value_pop_1"
17321 [(set (match_operand 0 "" "")
17322 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17323 (match_operand:SI 2 "" "")))
17324 (set (reg:SI SP_REG)
17325 (plus:SI (reg:SI SP_REG)
17326 (match_operand:SI 3 "immediate_operand" "i")))]
17327 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17328 { return ix86_output_call_insn (insn, operands[1], 1); }
17329 [(set_attr "type" "callv")])
17331 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17333 [(set (match_operand 0 "" "")
17334 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17335 (match_operand:SI 2 "" "")))
17336 (set (reg:SI SP_REG)
17337 (plus:SI (reg:SI SP_REG)
17338 (match_operand:SI 3 "immediate_operand" "i,i")))])
17339 (unspec [(match_operand 4 "const_int_operand" "")]
17340 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17341 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17343 "&& reload_completed"
17345 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17346 [(set_attr "type" "callv")])
17348 (define_insn "*sibcall_value_pop_1"
17349 [(set (match_operand 0 "" "")
17350 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17351 (match_operand:SI 2 "" "")))
17352 (set (reg:SI SP_REG)
17353 (plus:SI (reg:SI SP_REG)
17354 (match_operand:SI 3 "immediate_operand" "i,i")))]
17355 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17356 { return ix86_output_call_insn (insn, operands[1], 1); }
17357 [(set_attr "type" "callv")])
17359 (define_insn_and_split "*call_value_0_vzeroupper"
17360 [(set (match_operand 0 "" "")
17361 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17362 (match_operand:SI 2 "" "")))
17363 (unspec [(match_operand 3 "const_int_operand" "")]
17364 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17365 "TARGET_VZEROUPPER && !TARGET_64BIT"
17367 "&& reload_completed"
17369 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17370 [(set_attr "type" "callv")])
17372 (define_insn "*call_value_0"
17373 [(set (match_operand 0 "" "")
17374 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17375 (match_operand:SI 2 "" "")))]
17377 { return ix86_output_call_insn (insn, operands[1], 1); }
17378 [(set_attr "type" "callv")])
17380 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17381 [(set (match_operand 0 "" "")
17382 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17383 (match_operand:DI 2 "const_int_operand" "")))
17384 (unspec [(match_operand 3 "const_int_operand" "")]
17385 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17386 "TARGET_VZEROUPPER && TARGET_64BIT"
17388 "&& reload_completed"
17390 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17391 [(set_attr "type" "callv")])
17393 (define_insn "*call_value_0_rex64"
17394 [(set (match_operand 0 "" "")
17395 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17396 (match_operand:DI 2 "const_int_operand" "")))]
17398 { return ix86_output_call_insn (insn, operands[1], 1); }
17399 [(set_attr "type" "callv")])
17401 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17403 [(set (match_operand 0 "" "")
17404 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17405 (match_operand:DI 2 "const_int_operand" "")))
17406 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17407 (clobber (reg:TI XMM6_REG))
17408 (clobber (reg:TI XMM7_REG))
17409 (clobber (reg:TI XMM8_REG))
17410 (clobber (reg:TI XMM9_REG))
17411 (clobber (reg:TI XMM10_REG))
17412 (clobber (reg:TI XMM11_REG))
17413 (clobber (reg:TI XMM12_REG))
17414 (clobber (reg:TI XMM13_REG))
17415 (clobber (reg:TI XMM14_REG))
17416 (clobber (reg:TI XMM15_REG))
17417 (clobber (reg:DI SI_REG))
17418 (clobber (reg:DI DI_REG))])
17419 (unspec [(match_operand 3 "const_int_operand" "")]
17420 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17421 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17423 "&& reload_completed"
17425 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17426 [(set_attr "type" "callv")])
17428 (define_insn "*call_value_0_rex64_ms_sysv"
17429 [(set (match_operand 0 "" "")
17430 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17431 (match_operand:DI 2 "const_int_operand" "")))
17432 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17433 (clobber (reg:TI XMM6_REG))
17434 (clobber (reg:TI XMM7_REG))
17435 (clobber (reg:TI XMM8_REG))
17436 (clobber (reg:TI XMM9_REG))
17437 (clobber (reg:TI XMM10_REG))
17438 (clobber (reg:TI XMM11_REG))
17439 (clobber (reg:TI XMM12_REG))
17440 (clobber (reg:TI XMM13_REG))
17441 (clobber (reg:TI XMM14_REG))
17442 (clobber (reg:TI XMM15_REG))
17443 (clobber (reg:DI SI_REG))
17444 (clobber (reg:DI DI_REG))]
17445 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17446 { return ix86_output_call_insn (insn, operands[1], 1); }
17447 [(set_attr "type" "callv")])
17449 (define_insn_and_split "*call_value_1_vzeroupper"
17450 [(set (match_operand 0 "" "")
17451 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17452 (match_operand:SI 2 "" "")))
17453 (unspec [(match_operand 3 "const_int_operand" "")]
17454 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17455 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17457 "&& reload_completed"
17459 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17460 [(set_attr "type" "callv")])
17462 (define_insn "*call_value_1"
17463 [(set (match_operand 0 "" "")
17464 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17465 (match_operand:SI 2 "" "")))]
17466 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17467 { return ix86_output_call_insn (insn, operands[1], 1); }
17468 [(set_attr "type" "callv")])
17470 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17471 [(set (match_operand 0 "" "")
17472 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17473 (match_operand:SI 2 "" "")))
17474 (unspec [(match_operand 3 "const_int_operand" "")]
17475 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17476 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17478 "&& reload_completed"
17480 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17481 [(set_attr "type" "callv")])
17483 (define_insn "*sibcall_value_1"
17484 [(set (match_operand 0 "" "")
17485 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17486 (match_operand:SI 2 "" "")))]
17487 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17488 { return ix86_output_call_insn (insn, operands[1], 1); }
17489 [(set_attr "type" "callv")])
17491 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17492 [(set (match_operand 0 "" "")
17493 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17494 (match_operand:DI 2 "" "")))
17495 (unspec [(match_operand 3 "const_int_operand" "")]
17496 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17497 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17498 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17500 "&& reload_completed"
17502 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17503 [(set_attr "type" "callv")])
17505 (define_insn "*call_value_1_rex64"
17506 [(set (match_operand 0 "" "")
17507 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17508 (match_operand:DI 2 "" "")))]
17509 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17510 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17511 { return ix86_output_call_insn (insn, operands[1], 1); }
17512 [(set_attr "type" "callv")])
17514 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17516 [(set (match_operand 0 "" "")
17517 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17518 (match_operand:DI 2 "" "")))
17519 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17520 (clobber (reg:TI XMM6_REG))
17521 (clobber (reg:TI XMM7_REG))
17522 (clobber (reg:TI XMM8_REG))
17523 (clobber (reg:TI XMM9_REG))
17524 (clobber (reg:TI XMM10_REG))
17525 (clobber (reg:TI XMM11_REG))
17526 (clobber (reg:TI XMM12_REG))
17527 (clobber (reg:TI XMM13_REG))
17528 (clobber (reg:TI XMM14_REG))
17529 (clobber (reg:TI XMM15_REG))
17530 (clobber (reg:DI SI_REG))
17531 (clobber (reg:DI DI_REG))])
17532 (unspec [(match_operand 3 "const_int_operand" "")]
17533 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17534 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17536 "&& reload_completed"
17538 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17539 [(set_attr "type" "callv")])
17541 (define_insn "*call_value_1_rex64_ms_sysv"
17542 [(set (match_operand 0 "" "")
17543 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17544 (match_operand:DI 2 "" "")))
17545 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17546 (clobber (reg:TI XMM6_REG))
17547 (clobber (reg:TI XMM7_REG))
17548 (clobber (reg:TI XMM8_REG))
17549 (clobber (reg:TI XMM9_REG))
17550 (clobber (reg:TI XMM10_REG))
17551 (clobber (reg:TI XMM11_REG))
17552 (clobber (reg:TI XMM12_REG))
17553 (clobber (reg:TI XMM13_REG))
17554 (clobber (reg:TI XMM14_REG))
17555 (clobber (reg:TI XMM15_REG))
17556 (clobber (reg:DI SI_REG))
17557 (clobber (reg:DI DI_REG))]
17558 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17559 { return ix86_output_call_insn (insn, operands[1], 1); }
17560 [(set_attr "type" "callv")])
17562 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17563 [(set (match_operand 0 "" "")
17564 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17565 (match_operand:DI 2 "" "")))
17566 (unspec [(match_operand 3 "const_int_operand" "")]
17567 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17568 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17570 "&& reload_completed"
17572 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17573 [(set_attr "type" "callv")])
17575 (define_insn "*call_value_1_rex64_large"
17576 [(set (match_operand 0 "" "")
17577 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17578 (match_operand:DI 2 "" "")))]
17579 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17580 { return ix86_output_call_insn (insn, operands[1], 1); }
17581 [(set_attr "type" "callv")])
17583 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17584 [(set (match_operand 0 "" "")
17585 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17586 (match_operand:DI 2 "" "")))
17587 (unspec [(match_operand 3 "const_int_operand" "")]
17588 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17589 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17591 "&& reload_completed"
17593 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17594 [(set_attr "type" "callv")])
17596 (define_insn "*sibcall_value_1_rex64"
17597 [(set (match_operand 0 "" "")
17598 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17599 (match_operand:DI 2 "" "")))]
17600 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17601 { return ix86_output_call_insn (insn, operands[1], 1); }
17602 [(set_attr "type" "callv")])
17604 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17605 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17606 ;; caught for use by garbage collectors and the like. Using an insn that
17607 ;; maps to SIGILL makes it more likely the program will rightfully die.
17608 ;; Keeping with tradition, "6" is in honor of #UD.
17609 (define_insn "trap"
17610 [(trap_if (const_int 1) (const_int 6))]
17612 { return ASM_SHORT "0x0b0f"; }
17613 [(set_attr "length" "2")])
17615 (define_expand "prefetch"
17616 [(prefetch (match_operand 0 "address_operand" "")
17617 (match_operand:SI 1 "const_int_operand" "")
17618 (match_operand:SI 2 "const_int_operand" ""))]
17619 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17621 int rw = INTVAL (operands[1]);
17622 int locality = INTVAL (operands[2]);
17624 gcc_assert (rw == 0 || rw == 1);
17625 gcc_assert (locality >= 0 && locality <= 3);
17626 gcc_assert (GET_MODE (operands[0]) == Pmode
17627 || GET_MODE (operands[0]) == VOIDmode);
17629 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17630 supported by SSE counterpart or the SSE prefetch is not available
17631 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17633 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17634 operands[2] = GEN_INT (3);
17636 operands[1] = const0_rtx;
17639 (define_insn "*prefetch_sse_<mode>"
17640 [(prefetch (match_operand:P 0 "address_operand" "p")
17642 (match_operand:SI 1 "const_int_operand" ""))]
17643 "TARGET_PREFETCH_SSE"
17645 static const char * const patterns[4] = {
17646 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17649 int locality = INTVAL (operands[1]);
17650 gcc_assert (locality >= 0 && locality <= 3);
17652 return patterns[locality];
17654 [(set_attr "type" "sse")
17655 (set_attr "atom_sse_attr" "prefetch")
17656 (set (attr "length_address")
17657 (symbol_ref "memory_address_length (operands[0])"))
17658 (set_attr "memory" "none")])
17660 (define_insn "*prefetch_3dnow_<mode>"
17661 [(prefetch (match_operand:P 0 "address_operand" "p")
17662 (match_operand:SI 1 "const_int_operand" "n")
17666 if (INTVAL (operands[1]) == 0)
17667 return "prefetch\t%a0";
17669 return "prefetchw\t%a0";
17671 [(set_attr "type" "mmx")
17672 (set (attr "length_address")
17673 (symbol_ref "memory_address_length (operands[0])"))
17674 (set_attr "memory" "none")])
17676 (define_expand "stack_protect_set"
17677 [(match_operand 0 "memory_operand" "")
17678 (match_operand 1 "memory_operand" "")]
17681 rtx (*insn)(rtx, rtx);
17683 #ifdef TARGET_THREAD_SSP_OFFSET
17684 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17685 insn = (TARGET_64BIT
17686 ? gen_stack_tls_protect_set_di
17687 : gen_stack_tls_protect_set_si);
17689 insn = (TARGET_64BIT
17690 ? gen_stack_protect_set_di
17691 : gen_stack_protect_set_si);
17694 emit_insn (insn (operands[0], operands[1]));
17698 (define_insn "stack_protect_set_<mode>"
17699 [(set (match_operand:P 0 "memory_operand" "=m")
17700 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17701 (set (match_scratch:P 2 "=&r") (const_int 0))
17702 (clobber (reg:CC FLAGS_REG))]
17704 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17705 [(set_attr "type" "multi")])
17707 (define_insn "stack_tls_protect_set_<mode>"
17708 [(set (match_operand:P 0 "memory_operand" "=m")
17709 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17710 UNSPEC_SP_TLS_SET))
17711 (set (match_scratch:P 2 "=&r") (const_int 0))
17712 (clobber (reg:CC FLAGS_REG))]
17714 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17715 [(set_attr "type" "multi")])
17717 (define_expand "stack_protect_test"
17718 [(match_operand 0 "memory_operand" "")
17719 (match_operand 1 "memory_operand" "")
17720 (match_operand 2 "" "")]
17723 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17725 rtx (*insn)(rtx, rtx, rtx);
17727 #ifdef TARGET_THREAD_SSP_OFFSET
17728 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17729 insn = (TARGET_64BIT
17730 ? gen_stack_tls_protect_test_di
17731 : gen_stack_tls_protect_test_si);
17733 insn = (TARGET_64BIT
17734 ? gen_stack_protect_test_di
17735 : gen_stack_protect_test_si);
17738 emit_insn (insn (flags, operands[0], operands[1]));
17740 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17741 flags, const0_rtx, operands[2]));
17745 (define_insn "stack_protect_test_<mode>"
17746 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17747 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17748 (match_operand:P 2 "memory_operand" "m")]
17750 (clobber (match_scratch:P 3 "=&r"))]
17752 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17753 [(set_attr "type" "multi")])
17755 (define_insn "stack_tls_protect_test_<mode>"
17756 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17757 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17758 (match_operand:P 2 "const_int_operand" "i")]
17759 UNSPEC_SP_TLS_TEST))
17760 (clobber (match_scratch:P 3 "=r"))]
17762 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17763 [(set_attr "type" "multi")])
17765 (define_insn "sse4_2_crc32<mode>"
17766 [(set (match_operand:SI 0 "register_operand" "=r")
17768 [(match_operand:SI 1 "register_operand" "0")
17769 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17771 "TARGET_SSE4_2 || TARGET_CRC32"
17772 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17773 [(set_attr "type" "sselog1")
17774 (set_attr "prefix_rep" "1")
17775 (set_attr "prefix_extra" "1")
17776 (set (attr "prefix_data16")
17777 (if_then_else (match_operand:HI 2 "" "")
17779 (const_string "*")))
17780 (set (attr "prefix_rex")
17781 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17783 (const_string "*")))
17784 (set_attr "mode" "SI")])
17786 (define_insn "sse4_2_crc32di"
17787 [(set (match_operand:DI 0 "register_operand" "=r")
17789 [(match_operand:DI 1 "register_operand" "0")
17790 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17792 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17793 "crc32{q}\t{%2, %0|%0, %2}"
17794 [(set_attr "type" "sselog1")
17795 (set_attr "prefix_rep" "1")
17796 (set_attr "prefix_extra" "1")
17797 (set_attr "mode" "DI")])
17799 (define_expand "rdpmc"
17800 [(match_operand:DI 0 "register_operand" "")
17801 (match_operand:SI 1 "register_operand" "")]
17804 rtx reg = gen_reg_rtx (DImode);
17807 /* Force operand 1 into ECX. */
17808 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17809 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17810 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17815 rtvec vec = rtvec_alloc (2);
17816 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17817 rtx upper = gen_reg_rtx (DImode);
17818 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17819 gen_rtvec (1, const0_rtx),
17821 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17822 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17824 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17825 NULL, 1, OPTAB_DIRECT);
17826 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17830 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17831 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17835 (define_insn "*rdpmc"
17836 [(set (match_operand:DI 0 "register_operand" "=A")
17837 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17841 [(set_attr "type" "other")
17842 (set_attr "length" "2")])
17844 (define_insn "*rdpmc_rex64"
17845 [(set (match_operand:DI 0 "register_operand" "=a")
17846 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17848 (set (match_operand:DI 1 "register_operand" "=d")
17849 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17852 [(set_attr "type" "other")
17853 (set_attr "length" "2")])
17855 (define_expand "rdtsc"
17856 [(set (match_operand:DI 0 "register_operand" "")
17857 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17862 rtvec vec = rtvec_alloc (2);
17863 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17864 rtx upper = gen_reg_rtx (DImode);
17865 rtx lower = gen_reg_rtx (DImode);
17866 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17867 gen_rtvec (1, const0_rtx),
17869 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17870 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17872 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17873 NULL, 1, OPTAB_DIRECT);
17874 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17876 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17881 (define_insn "*rdtsc"
17882 [(set (match_operand:DI 0 "register_operand" "=A")
17883 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17886 [(set_attr "type" "other")
17887 (set_attr "length" "2")])
17889 (define_insn "*rdtsc_rex64"
17890 [(set (match_operand:DI 0 "register_operand" "=a")
17891 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17892 (set (match_operand:DI 1 "register_operand" "=d")
17893 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17896 [(set_attr "type" "other")
17897 (set_attr "length" "2")])
17899 (define_expand "rdtscp"
17900 [(match_operand:DI 0 "register_operand" "")
17901 (match_operand:SI 1 "memory_operand" "")]
17904 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17905 gen_rtvec (1, const0_rtx),
17907 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17908 gen_rtvec (1, const0_rtx),
17910 rtx reg = gen_reg_rtx (DImode);
17911 rtx tmp = gen_reg_rtx (SImode);
17915 rtvec vec = rtvec_alloc (3);
17916 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17917 rtx upper = gen_reg_rtx (DImode);
17918 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17919 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17920 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17922 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17923 NULL, 1, OPTAB_DIRECT);
17924 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17929 rtvec vec = rtvec_alloc (2);
17930 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17931 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17932 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17935 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17936 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17940 (define_insn "*rdtscp"
17941 [(set (match_operand:DI 0 "register_operand" "=A")
17942 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17943 (set (match_operand:SI 1 "register_operand" "=c")
17944 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17947 [(set_attr "type" "other")
17948 (set_attr "length" "3")])
17950 (define_insn "*rdtscp_rex64"
17951 [(set (match_operand:DI 0 "register_operand" "=a")
17952 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17953 (set (match_operand:DI 1 "register_operand" "=d")
17954 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17955 (set (match_operand:SI 2 "register_operand" "=c")
17956 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17959 [(set_attr "type" "other")
17960 (set_attr "length" "3")])
17962 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17964 ;; LWP instructions
17966 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17968 (define_expand "lwp_llwpcb"
17969 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17970 UNSPECV_LLWP_INTRINSIC)]
17973 (define_insn "*lwp_llwpcb<mode>1"
17974 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17975 UNSPECV_LLWP_INTRINSIC)]
17978 [(set_attr "type" "lwp")
17979 (set_attr "mode" "<MODE>")
17980 (set_attr "length" "5")])
17982 (define_expand "lwp_slwpcb"
17983 [(set (match_operand 0 "register_operand" "=r")
17984 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17988 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17990 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17994 (define_insn "lwp_slwpcb<mode>"
17995 [(set (match_operand:P 0 "register_operand" "=r")
17996 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17999 [(set_attr "type" "lwp")
18000 (set_attr "mode" "<MODE>")
18001 (set_attr "length" "5")])
18003 (define_expand "lwp_lwpval<mode>3"
18004 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18005 (match_operand:SI 2 "nonimmediate_operand" "rm")
18006 (match_operand:SI 3 "const_int_operand" "i")]
18007 UNSPECV_LWPVAL_INTRINSIC)]
18009 "/* Avoid unused variable warning. */
18012 (define_insn "*lwp_lwpval<mode>3_1"
18013 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18014 (match_operand:SI 1 "nonimmediate_operand" "rm")
18015 (match_operand:SI 2 "const_int_operand" "i")]
18016 UNSPECV_LWPVAL_INTRINSIC)]
18018 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18019 [(set_attr "type" "lwp")
18020 (set_attr "mode" "<MODE>")
18021 (set (attr "length")
18022 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18024 (define_expand "lwp_lwpins<mode>3"
18025 [(set (reg:CCC FLAGS_REG)
18026 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18027 (match_operand:SI 2 "nonimmediate_operand" "rm")
18028 (match_operand:SI 3 "const_int_operand" "i")]
18029 UNSPECV_LWPINS_INTRINSIC))
18030 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18031 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18034 (define_insn "*lwp_lwpins<mode>3_1"
18035 [(set (reg:CCC FLAGS_REG)
18036 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18037 (match_operand:SI 1 "nonimmediate_operand" "rm")
18038 (match_operand:SI 2 "const_int_operand" "i")]
18039 UNSPECV_LWPINS_INTRINSIC))]
18041 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18042 [(set_attr "type" "lwp")
18043 (set_attr "mode" "<MODE>")
18044 (set (attr "length")
18045 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18047 (define_insn "rdfsbase<mode>"
18048 [(set (match_operand:SWI48 0 "register_operand" "=r")
18049 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18050 "TARGET_64BIT && TARGET_FSGSBASE"
18052 [(set_attr "type" "other")
18053 (set_attr "prefix_extra" "2")])
18055 (define_insn "rdgsbase<mode>"
18056 [(set (match_operand:SWI48 0 "register_operand" "=r")
18057 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18058 "TARGET_64BIT && TARGET_FSGSBASE"
18060 [(set_attr "type" "other")
18061 (set_attr "prefix_extra" "2")])
18063 (define_insn "wrfsbase<mode>"
18064 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18066 "TARGET_64BIT && TARGET_FSGSBASE"
18068 [(set_attr "type" "other")
18069 (set_attr "prefix_extra" "2")])
18071 (define_insn "wrgsbase<mode>"
18072 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18074 "TARGET_64BIT && TARGET_FSGSBASE"
18076 [(set_attr "type" "other")
18077 (set_attr "prefix_extra" "2")])
18079 (define_expand "rdrand<mode>"
18080 [(set (match_operand:SWI248 0 "register_operand" "=r")
18081 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18084 rtx retry_label, insn, ccc;
18086 retry_label = gen_label_rtx ();
18088 emit_label (retry_label);
18090 /* Generate rdrand. */
18091 emit_insn (gen_rdrand<mode>_1 (operands[0]));
18093 /* Retry if the carry flag isn't valid. */
18094 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
18095 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
18096 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
18097 gen_rtx_LABEL_REF (VOIDmode, retry_label));
18098 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
18099 JUMP_LABEL (insn) = retry_label;
18104 (define_insn "rdrand<mode>_1"
18105 [(set (match_operand:SWI248 0 "register_operand" "=r")
18106 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18109 [(set_attr "type" "other")
18110 (set_attr "prefix_extra" "1")])
18114 (include "sync.md")