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
236 ;; For RDRAND support
240 (define_c_enum "unspecv" [
243 UNSPECV_PROBE_STACK_RANGE
263 UNSPECV_LLWP_INTRINSIC
264 UNSPECV_SLWP_INTRINSIC
265 UNSPECV_LWPVAL_INTRINSIC
266 UNSPECV_LWPINS_INTRINSIC
271 UNSPECV_SPLIT_STACK_RETURN
274 ;; Constants to represent pcomtrue/pcomfalse variants
284 ;; Constants used in the XOP pperm instruction
286 [(PPERM_SRC 0x00) /* copy source */
287 (PPERM_INVERT 0x20) /* invert source */
288 (PPERM_REVERSE 0x40) /* bit reverse source */
289 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
290 (PPERM_ZERO 0x80) /* all 0's */
291 (PPERM_ONES 0xa0) /* all 1's */
292 (PPERM_SIGN 0xc0) /* propagate sign bit */
293 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
294 (PPERM_SRC1 0x00) /* use first source byte */
295 (PPERM_SRC2 0x10) /* use second source byte */
298 ;; Registers by name.
351 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
354 ;; In C guard expressions, put expressions which may be compile-time
355 ;; constants first. This allows for better optimization. For
356 ;; example, write "TARGET_64BIT && reload_completed", not
357 ;; "reload_completed && TARGET_64BIT".
361 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
362 atom,generic64,amdfam10,bdver1"
363 (const (symbol_ref "ix86_schedule")))
365 ;; A basic instruction type. Refinements due to arguments to be
366 ;; provided in other attributes.
369 alu,alu1,negnot,imov,imovx,lea,
370 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
371 icmp,test,ibr,setcc,icmov,
372 push,pop,call,callv,leave,
374 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
375 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
376 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
377 ssemuladd,sse4arg,lwp,
378 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
379 (const_string "other"))
381 ;; Main data type used by the insn
383 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
384 (const_string "unknown"))
386 ;; The CPU unit operations uses.
387 (define_attr "unit" "integer,i387,sse,mmx,unknown"
388 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
389 (const_string "i387")
390 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
391 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
392 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
394 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
396 (eq_attr "type" "other")
397 (const_string "unknown")]
398 (const_string "integer")))
400 ;; The (bounding maximum) length of an instruction immediate.
401 (define_attr "length_immediate" ""
402 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
405 (eq_attr "unit" "i387,sse,mmx")
407 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
409 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
410 (eq_attr "type" "imov,test")
411 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
412 (eq_attr "type" "call")
413 (if_then_else (match_operand 0 "constant_call_address_operand" "")
416 (eq_attr "type" "callv")
417 (if_then_else (match_operand 1 "constant_call_address_operand" "")
420 ;; We don't know the size before shorten_branches. Expect
421 ;; the instruction to fit for better scheduling.
422 (eq_attr "type" "ibr")
425 (symbol_ref "/* Update immediate_length and other attributes! */
426 gcc_unreachable (),1")))
428 ;; The (bounding maximum) length of an instruction address.
429 (define_attr "length_address" ""
430 (cond [(eq_attr "type" "str,other,multi,fxch")
432 (and (eq_attr "type" "call")
433 (match_operand 0 "constant_call_address_operand" ""))
435 (and (eq_attr "type" "callv")
436 (match_operand 1 "constant_call_address_operand" ""))
439 (symbol_ref "ix86_attr_length_address_default (insn)")))
441 ;; Set when length prefix is used.
442 (define_attr "prefix_data16" ""
443 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
445 (eq_attr "mode" "HI")
447 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
452 ;; Set when string REP prefix is used.
453 (define_attr "prefix_rep" ""
454 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
456 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
461 ;; Set when 0f opcode prefix is used.
462 (define_attr "prefix_0f" ""
464 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
465 (eq_attr "unit" "sse,mmx"))
469 ;; Set when REX opcode prefix is used.
470 (define_attr "prefix_rex" ""
471 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
473 (and (eq_attr "mode" "DI")
474 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
475 (eq_attr "unit" "!mmx")))
477 (and (eq_attr "mode" "QI")
478 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
481 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
484 (and (eq_attr "type" "imovx")
485 (match_operand:QI 1 "ext_QIreg_operand" ""))
490 ;; There are also additional prefixes in 3DNOW, SSSE3.
491 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
492 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
493 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
494 (define_attr "prefix_extra" ""
495 (cond [(eq_attr "type" "ssemuladd,sse4arg")
497 (eq_attr "type" "sseiadd1,ssecvt1")
502 ;; Prefix used: original, VEX or maybe VEX.
503 (define_attr "prefix" "orig,vex,maybe_vex"
504 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
506 (const_string "orig")))
508 ;; VEX W bit is used.
509 (define_attr "prefix_vex_w" "" (const_int 0))
511 ;; The length of VEX prefix
512 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
513 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
514 ;; still prefix_0f 1, with prefix_extra 1.
515 (define_attr "length_vex" ""
516 (if_then_else (and (eq_attr "prefix_0f" "1")
517 (eq_attr "prefix_extra" "0"))
518 (if_then_else (eq_attr "prefix_vex_w" "1")
519 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
520 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
521 (if_then_else (eq_attr "prefix_vex_w" "1")
522 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
523 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
525 ;; Set when modrm byte is used.
526 (define_attr "modrm" ""
527 (cond [(eq_attr "type" "str,leave")
529 (eq_attr "unit" "i387")
531 (and (eq_attr "type" "incdec")
532 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
533 (ior (match_operand:SI 1 "register_operand" "")
534 (match_operand:HI 1 "register_operand" ""))))
536 (and (eq_attr "type" "push")
537 (not (match_operand 1 "memory_operand" "")))
539 (and (eq_attr "type" "pop")
540 (not (match_operand 0 "memory_operand" "")))
542 (and (eq_attr "type" "imov")
543 (and (not (eq_attr "mode" "DI"))
544 (ior (and (match_operand 0 "register_operand" "")
545 (match_operand 1 "immediate_operand" ""))
546 (ior (and (match_operand 0 "ax_reg_operand" "")
547 (match_operand 1 "memory_displacement_only_operand" ""))
548 (and (match_operand 0 "memory_displacement_only_operand" "")
549 (match_operand 1 "ax_reg_operand" ""))))))
551 (and (eq_attr "type" "call")
552 (match_operand 0 "constant_call_address_operand" ""))
554 (and (eq_attr "type" "callv")
555 (match_operand 1 "constant_call_address_operand" ""))
557 (and (eq_attr "type" "alu,alu1,icmp,test")
558 (match_operand 0 "ax_reg_operand" ""))
559 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
563 ;; The (bounding maximum) length of an instruction in bytes.
564 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
565 ;; Later we may want to split them and compute proper length as for
567 (define_attr "length" ""
568 (cond [(eq_attr "type" "other,multi,fistp,frndint")
570 (eq_attr "type" "fcmp")
572 (eq_attr "unit" "i387")
574 (plus (attr "prefix_data16")
575 (attr "length_address")))
576 (ior (eq_attr "prefix" "vex")
577 (and (eq_attr "prefix" "maybe_vex")
578 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
579 (plus (attr "length_vex")
580 (plus (attr "length_immediate")
582 (attr "length_address"))))]
583 (plus (plus (attr "modrm")
584 (plus (attr "prefix_0f")
585 (plus (attr "prefix_rex")
586 (plus (attr "prefix_extra")
588 (plus (attr "prefix_rep")
589 (plus (attr "prefix_data16")
590 (plus (attr "length_immediate")
591 (attr "length_address")))))))
593 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
594 ;; `store' if there is a simple memory reference therein, or `unknown'
595 ;; if the instruction is complex.
597 (define_attr "memory" "none,load,store,both,unknown"
598 (cond [(eq_attr "type" "other,multi,str,lwp")
599 (const_string "unknown")
600 (eq_attr "type" "lea,fcmov,fpspc")
601 (const_string "none")
602 (eq_attr "type" "fistp,leave")
603 (const_string "both")
604 (eq_attr "type" "frndint")
605 (const_string "load")
606 (eq_attr "type" "push")
607 (if_then_else (match_operand 1 "memory_operand" "")
608 (const_string "both")
609 (const_string "store"))
610 (eq_attr "type" "pop")
611 (if_then_else (match_operand 0 "memory_operand" "")
612 (const_string "both")
613 (const_string "load"))
614 (eq_attr "type" "setcc")
615 (if_then_else (match_operand 0 "memory_operand" "")
616 (const_string "store")
617 (const_string "none"))
618 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
619 (if_then_else (ior (match_operand 0 "memory_operand" "")
620 (match_operand 1 "memory_operand" ""))
621 (const_string "load")
622 (const_string "none"))
623 (eq_attr "type" "ibr")
624 (if_then_else (match_operand 0 "memory_operand" "")
625 (const_string "load")
626 (const_string "none"))
627 (eq_attr "type" "call")
628 (if_then_else (match_operand 0 "constant_call_address_operand" "")
629 (const_string "none")
630 (const_string "load"))
631 (eq_attr "type" "callv")
632 (if_then_else (match_operand 1 "constant_call_address_operand" "")
633 (const_string "none")
634 (const_string "load"))
635 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
636 (match_operand 1 "memory_operand" ""))
637 (const_string "both")
638 (and (match_operand 0 "memory_operand" "")
639 (match_operand 1 "memory_operand" ""))
640 (const_string "both")
641 (match_operand 0 "memory_operand" "")
642 (const_string "store")
643 (match_operand 1 "memory_operand" "")
644 (const_string "load")
646 "!alu1,negnot,ishift1,
647 imov,imovx,icmp,test,bitmanip,
649 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
650 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
651 (match_operand 2 "memory_operand" ""))
652 (const_string "load")
653 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
654 (match_operand 3 "memory_operand" ""))
655 (const_string "load")
657 (const_string "none")))
659 ;; Indicates if an instruction has both an immediate and a displacement.
661 (define_attr "imm_disp" "false,true,unknown"
662 (cond [(eq_attr "type" "other,multi")
663 (const_string "unknown")
664 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
665 (and (match_operand 0 "memory_displacement_operand" "")
666 (match_operand 1 "immediate_operand" "")))
667 (const_string "true")
668 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
669 (and (match_operand 0 "memory_displacement_operand" "")
670 (match_operand 2 "immediate_operand" "")))
671 (const_string "true")
673 (const_string "false")))
675 ;; Indicates if an FP operation has an integer source.
677 (define_attr "fp_int_src" "false,true"
678 (const_string "false"))
680 ;; Defines rounding mode of an FP operation.
682 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
683 (const_string "any"))
685 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
686 (define_attr "use_carry" "0,1" (const_string "0"))
688 ;; Define attribute to indicate unaligned ssemov insns
689 (define_attr "movu" "0,1" (const_string "0"))
691 ;; Describe a user's asm statement.
692 (define_asm_attributes
693 [(set_attr "length" "128")
694 (set_attr "type" "multi")])
696 (define_code_iterator plusminus [plus minus])
698 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
700 ;; Base name for define_insn
701 (define_code_attr plusminus_insn
702 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
703 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
705 ;; Base name for insn mnemonic.
706 (define_code_attr plusminus_mnemonic
707 [(plus "add") (ss_plus "adds") (us_plus "addus")
708 (minus "sub") (ss_minus "subs") (us_minus "subus")])
709 (define_code_attr plusminus_carry_mnemonic
710 [(plus "adc") (minus "sbb")])
712 ;; Mark commutative operators as such in constraints.
713 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
714 (minus "") (ss_minus "") (us_minus "")])
716 ;; Mapping of signed max and min
717 (define_code_iterator smaxmin [smax smin])
719 ;; Mapping of unsigned max and min
720 (define_code_iterator umaxmin [umax umin])
722 ;; Base name for integer and FP insn mnemonic
723 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
724 (umax "maxu") (umin "minu")])
725 (define_code_attr maxmin_float [(smax "max") (smin "min")])
727 ;; Mapping of logic operators
728 (define_code_iterator any_logic [and ior xor])
729 (define_code_iterator any_or [ior xor])
731 ;; Base name for insn mnemonic.
732 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
734 ;; Mapping of shift-right operators
735 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
737 ;; Base name for define_insn
738 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
740 ;; Base name for insn mnemonic.
741 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
743 ;; Mapping of rotate operators
744 (define_code_iterator any_rotate [rotate rotatert])
746 ;; Base name for define_insn
747 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
749 ;; Base name for insn mnemonic.
750 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
752 ;; Mapping of abs neg operators
753 (define_code_iterator absneg [abs neg])
755 ;; Base name for x87 insn mnemonic.
756 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
758 ;; Used in signed and unsigned widening multiplications.
759 (define_code_iterator any_extend [sign_extend zero_extend])
761 ;; Various insn prefixes for signed and unsigned operations.
762 (define_code_attr u [(sign_extend "") (zero_extend "u")
763 (div "") (udiv "u")])
764 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
766 ;; Used in signed and unsigned divisions.
767 (define_code_iterator any_div [div udiv])
769 ;; Instruction prefix for signed and unsigned operations.
770 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
771 (div "i") (udiv "")])
773 ;; 64bit single word integer modes.
774 (define_mode_iterator SWI1248x [QI HI SI DI])
776 ;; 64bit single word integer modes without QImode and HImode.
777 (define_mode_iterator SWI48x [SI DI])
779 ;; Single word integer modes.
780 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
782 ;; Single word integer modes without SImode and DImode.
783 (define_mode_iterator SWI12 [QI HI])
785 ;; Single word integer modes without DImode.
786 (define_mode_iterator SWI124 [QI HI SI])
788 ;; Single word integer modes without QImode and DImode.
789 (define_mode_iterator SWI24 [HI SI])
791 ;; Single word integer modes without QImode.
792 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
794 ;; Single word integer modes without QImode and HImode.
795 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
797 ;; All math-dependant single and double word integer modes.
798 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
799 (HI "TARGET_HIMODE_MATH")
800 SI DI (TI "TARGET_64BIT")])
802 ;; Math-dependant single word integer modes.
803 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
804 (HI "TARGET_HIMODE_MATH")
805 SI (DI "TARGET_64BIT")])
807 ;; Math-dependant single word integer modes without DImode.
808 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
809 (HI "TARGET_HIMODE_MATH")
812 ;; Math-dependant single word integer modes without QImode.
813 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
814 SI (DI "TARGET_64BIT")])
816 ;; Double word integer modes.
817 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
818 (TI "TARGET_64BIT")])
820 ;; Double word integer modes as mode attribute.
821 (define_mode_attr DWI [(SI "DI") (DI "TI")])
822 (define_mode_attr dwi [(SI "di") (DI "ti")])
824 ;; Half mode for double word integer modes.
825 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
826 (DI "TARGET_64BIT")])
828 ;; Instruction suffix for integer modes.
829 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
831 ;; Pointer size prefix for integer modes (Intel asm dialect)
832 (define_mode_attr iptrsize [(QI "BYTE")
837 ;; Register class for integer modes.
838 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
840 ;; Immediate operand constraint for integer modes.
841 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
843 ;; General operand constraint for word modes.
844 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
846 ;; Immediate operand constraint for double integer modes.
847 (define_mode_attr di [(SI "iF") (DI "e")])
849 ;; Immediate operand constraint for shifts.
850 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
852 ;; General operand predicate for integer modes.
853 (define_mode_attr general_operand
854 [(QI "general_operand")
855 (HI "general_operand")
856 (SI "general_operand")
857 (DI "x86_64_general_operand")
858 (TI "x86_64_general_operand")])
860 ;; General sign/zero extend operand predicate for integer modes.
861 (define_mode_attr general_szext_operand
862 [(QI "general_operand")
863 (HI "general_operand")
864 (SI "general_operand")
865 (DI "x86_64_szext_general_operand")])
867 ;; Immediate operand predicate for integer modes.
868 (define_mode_attr immediate_operand
869 [(QI "immediate_operand")
870 (HI "immediate_operand")
871 (SI "immediate_operand")
872 (DI "x86_64_immediate_operand")])
874 ;; Nonmemory operand predicate for integer modes.
875 (define_mode_attr nonmemory_operand
876 [(QI "nonmemory_operand")
877 (HI "nonmemory_operand")
878 (SI "nonmemory_operand")
879 (DI "x86_64_nonmemory_operand")])
881 ;; Operand predicate for shifts.
882 (define_mode_attr shift_operand
883 [(QI "nonimmediate_operand")
884 (HI "nonimmediate_operand")
885 (SI "nonimmediate_operand")
886 (DI "shiftdi_operand")
887 (TI "register_operand")])
889 ;; Operand predicate for shift argument.
890 (define_mode_attr shift_immediate_operand
891 [(QI "const_1_to_31_operand")
892 (HI "const_1_to_31_operand")
893 (SI "const_1_to_31_operand")
894 (DI "const_1_to_63_operand")])
896 ;; Input operand predicate for arithmetic left shifts.
897 (define_mode_attr ashl_input_operand
898 [(QI "nonimmediate_operand")
899 (HI "nonimmediate_operand")
900 (SI "nonimmediate_operand")
901 (DI "ashldi_input_operand")
902 (TI "reg_or_pm1_operand")])
904 ;; SSE and x87 SFmode and DFmode floating point modes
905 (define_mode_iterator MODEF [SF DF])
907 ;; All x87 floating point modes
908 (define_mode_iterator X87MODEF [SF DF XF])
910 ;; All integer modes handled by x87 fisttp operator.
911 (define_mode_iterator X87MODEI [HI SI DI])
913 ;; All integer modes handled by integer x87 operators.
914 (define_mode_iterator X87MODEI12 [HI SI])
916 ;; All integer modes handled by SSE cvtts?2si* operators.
917 (define_mode_iterator SSEMODEI24 [SI DI])
919 ;; SSE asm suffix for floating point modes
920 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
922 ;; SSE vector mode corresponding to a scalar mode
923 (define_mode_attr ssevecmode
924 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
926 ;; Instruction suffix for REX 64bit operators.
927 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
929 ;; This mode iterator allows :P to be used for patterns that operate on
930 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
931 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
933 ;; Scheduling descriptions
935 (include "pentium.md")
938 (include "athlon.md")
939 (include "bdver1.md")
945 ;; Operand and operator predicates and constraints
947 (include "predicates.md")
948 (include "constraints.md")
951 ;; Compare and branch/compare and store instructions.
953 (define_expand "cbranch<mode>4"
954 [(set (reg:CC FLAGS_REG)
955 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
956 (match_operand:SDWIM 2 "<general_operand>" "")))
957 (set (pc) (if_then_else
958 (match_operator 0 "ordered_comparison_operator"
959 [(reg:CC FLAGS_REG) (const_int 0)])
960 (label_ref (match_operand 3 "" ""))
964 if (MEM_P (operands[1]) && MEM_P (operands[2]))
965 operands[1] = force_reg (<MODE>mode, operands[1]);
966 ix86_expand_branch (GET_CODE (operands[0]),
967 operands[1], operands[2], operands[3]);
971 (define_expand "cstore<mode>4"
972 [(set (reg:CC FLAGS_REG)
973 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
974 (match_operand:SWIM 3 "<general_operand>" "")))
975 (set (match_operand:QI 0 "register_operand" "")
976 (match_operator 1 "ordered_comparison_operator"
977 [(reg:CC FLAGS_REG) (const_int 0)]))]
980 if (MEM_P (operands[2]) && MEM_P (operands[3]))
981 operands[2] = force_reg (<MODE>mode, operands[2]);
982 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
983 operands[2], operands[3]);
987 (define_expand "cmp<mode>_1"
988 [(set (reg:CC FLAGS_REG)
989 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
990 (match_operand:SWI48 1 "<general_operand>" "")))])
992 (define_insn "*cmp<mode>_ccno_1"
993 [(set (reg FLAGS_REG)
994 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
995 (match_operand:SWI 1 "const0_operand" "")))]
996 "ix86_match_ccmode (insn, CCNOmode)"
998 test{<imodesuffix>}\t%0, %0
999 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1000 [(set_attr "type" "test,icmp")
1001 (set_attr "length_immediate" "0,1")
1002 (set_attr "mode" "<MODE>")])
1004 (define_insn "*cmp<mode>_1"
1005 [(set (reg FLAGS_REG)
1006 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1007 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1008 "ix86_match_ccmode (insn, CCmode)"
1009 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1010 [(set_attr "type" "icmp")
1011 (set_attr "mode" "<MODE>")])
1013 (define_insn "*cmp<mode>_minus_1"
1014 [(set (reg FLAGS_REG)
1016 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1017 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1019 "ix86_match_ccmode (insn, CCGOCmode)"
1020 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1021 [(set_attr "type" "icmp")
1022 (set_attr "mode" "<MODE>")])
1024 (define_insn "*cmpqi_ext_1"
1025 [(set (reg FLAGS_REG)
1027 (match_operand:QI 0 "general_operand" "Qm")
1030 (match_operand 1 "ext_register_operand" "Q")
1032 (const_int 8)) 0)))]
1033 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1034 "cmp{b}\t{%h1, %0|%0, %h1}"
1035 [(set_attr "type" "icmp")
1036 (set_attr "mode" "QI")])
1038 (define_insn "*cmpqi_ext_1_rex64"
1039 [(set (reg FLAGS_REG)
1041 (match_operand:QI 0 "register_operand" "Q")
1044 (match_operand 1 "ext_register_operand" "Q")
1046 (const_int 8)) 0)))]
1047 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1048 "cmp{b}\t{%h1, %0|%0, %h1}"
1049 [(set_attr "type" "icmp")
1050 (set_attr "mode" "QI")])
1052 (define_insn "*cmpqi_ext_2"
1053 [(set (reg FLAGS_REG)
1057 (match_operand 0 "ext_register_operand" "Q")
1060 (match_operand:QI 1 "const0_operand" "")))]
1061 "ix86_match_ccmode (insn, CCNOmode)"
1063 [(set_attr "type" "test")
1064 (set_attr "length_immediate" "0")
1065 (set_attr "mode" "QI")])
1067 (define_expand "cmpqi_ext_3"
1068 [(set (reg:CC FLAGS_REG)
1072 (match_operand 0 "ext_register_operand" "")
1075 (match_operand:QI 1 "immediate_operand" "")))])
1077 (define_insn "*cmpqi_ext_3_insn"
1078 [(set (reg FLAGS_REG)
1082 (match_operand 0 "ext_register_operand" "Q")
1085 (match_operand:QI 1 "general_operand" "Qmn")))]
1086 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1087 "cmp{b}\t{%1, %h0|%h0, %1}"
1088 [(set_attr "type" "icmp")
1089 (set_attr "modrm" "1")
1090 (set_attr "mode" "QI")])
1092 (define_insn "*cmpqi_ext_3_insn_rex64"
1093 [(set (reg FLAGS_REG)
1097 (match_operand 0 "ext_register_operand" "Q")
1100 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1101 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1102 "cmp{b}\t{%1, %h0|%h0, %1}"
1103 [(set_attr "type" "icmp")
1104 (set_attr "modrm" "1")
1105 (set_attr "mode" "QI")])
1107 (define_insn "*cmpqi_ext_4"
1108 [(set (reg FLAGS_REG)
1112 (match_operand 0 "ext_register_operand" "Q")
1117 (match_operand 1 "ext_register_operand" "Q")
1119 (const_int 8)) 0)))]
1120 "ix86_match_ccmode (insn, CCmode)"
1121 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1122 [(set_attr "type" "icmp")
1123 (set_attr "mode" "QI")])
1125 ;; These implement float point compares.
1126 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1127 ;; which would allow mix and match FP modes on the compares. Which is what
1128 ;; the old patterns did, but with many more of them.
1130 (define_expand "cbranchxf4"
1131 [(set (reg:CC FLAGS_REG)
1132 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1133 (match_operand:XF 2 "nonmemory_operand" "")))
1134 (set (pc) (if_then_else
1135 (match_operator 0 "ix86_fp_comparison_operator"
1138 (label_ref (match_operand 3 "" ""))
1142 ix86_expand_branch (GET_CODE (operands[0]),
1143 operands[1], operands[2], operands[3]);
1147 (define_expand "cstorexf4"
1148 [(set (reg:CC FLAGS_REG)
1149 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1150 (match_operand:XF 3 "nonmemory_operand" "")))
1151 (set (match_operand:QI 0 "register_operand" "")
1152 (match_operator 1 "ix86_fp_comparison_operator"
1157 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1158 operands[2], operands[3]);
1162 (define_expand "cbranch<mode>4"
1163 [(set (reg:CC FLAGS_REG)
1164 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1165 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1166 (set (pc) (if_then_else
1167 (match_operator 0 "ix86_fp_comparison_operator"
1170 (label_ref (match_operand 3 "" ""))
1172 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1174 ix86_expand_branch (GET_CODE (operands[0]),
1175 operands[1], operands[2], operands[3]);
1179 (define_expand "cstore<mode>4"
1180 [(set (reg:CC FLAGS_REG)
1181 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1182 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1183 (set (match_operand:QI 0 "register_operand" "")
1184 (match_operator 1 "ix86_fp_comparison_operator"
1187 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1189 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1190 operands[2], operands[3]);
1194 (define_expand "cbranchcc4"
1195 [(set (pc) (if_then_else
1196 (match_operator 0 "comparison_operator"
1197 [(match_operand 1 "flags_reg_operand" "")
1198 (match_operand 2 "const0_operand" "")])
1199 (label_ref (match_operand 3 "" ""))
1203 ix86_expand_branch (GET_CODE (operands[0]),
1204 operands[1], operands[2], operands[3]);
1208 (define_expand "cstorecc4"
1209 [(set (match_operand:QI 0 "register_operand" "")
1210 (match_operator 1 "comparison_operator"
1211 [(match_operand 2 "flags_reg_operand" "")
1212 (match_operand 3 "const0_operand" "")]))]
1215 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1216 operands[2], operands[3]);
1221 ;; FP compares, step 1:
1222 ;; Set the FP condition codes.
1224 ;; CCFPmode compare with exceptions
1225 ;; CCFPUmode compare with no exceptions
1227 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1228 ;; used to manage the reg stack popping would not be preserved.
1230 (define_insn "*cmpfp_0"
1231 [(set (match_operand:HI 0 "register_operand" "=a")
1234 (match_operand 1 "register_operand" "f")
1235 (match_operand 2 "const0_operand" ""))]
1237 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1238 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1239 "* return output_fp_compare (insn, operands, 0, 0);"
1240 [(set_attr "type" "multi")
1241 (set_attr "unit" "i387")
1243 (cond [(match_operand:SF 1 "" "")
1245 (match_operand:DF 1 "" "")
1248 (const_string "XF")))])
1250 (define_insn_and_split "*cmpfp_0_cc"
1251 [(set (reg:CCFP FLAGS_REG)
1253 (match_operand 1 "register_operand" "f")
1254 (match_operand 2 "const0_operand" "")))
1255 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1256 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1257 && TARGET_SAHF && !TARGET_CMOVE
1258 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1260 "&& reload_completed"
1263 [(compare:CCFP (match_dup 1)(match_dup 2))]
1265 (set (reg:CC FLAGS_REG)
1266 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1268 [(set_attr "type" "multi")
1269 (set_attr "unit" "i387")
1271 (cond [(match_operand:SF 1 "" "")
1273 (match_operand:DF 1 "" "")
1276 (const_string "XF")))])
1278 (define_insn "*cmpfp_xf"
1279 [(set (match_operand:HI 0 "register_operand" "=a")
1282 (match_operand:XF 1 "register_operand" "f")
1283 (match_operand:XF 2 "register_operand" "f"))]
1286 "* return output_fp_compare (insn, operands, 0, 0);"
1287 [(set_attr "type" "multi")
1288 (set_attr "unit" "i387")
1289 (set_attr "mode" "XF")])
1291 (define_insn_and_split "*cmpfp_xf_cc"
1292 [(set (reg:CCFP FLAGS_REG)
1294 (match_operand:XF 1 "register_operand" "f")
1295 (match_operand:XF 2 "register_operand" "f")))
1296 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1298 && TARGET_SAHF && !TARGET_CMOVE"
1300 "&& reload_completed"
1303 [(compare:CCFP (match_dup 1)(match_dup 2))]
1305 (set (reg:CC FLAGS_REG)
1306 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1308 [(set_attr "type" "multi")
1309 (set_attr "unit" "i387")
1310 (set_attr "mode" "XF")])
1312 (define_insn "*cmpfp_<mode>"
1313 [(set (match_operand:HI 0 "register_operand" "=a")
1316 (match_operand:MODEF 1 "register_operand" "f")
1317 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1320 "* return output_fp_compare (insn, operands, 0, 0);"
1321 [(set_attr "type" "multi")
1322 (set_attr "unit" "i387")
1323 (set_attr "mode" "<MODE>")])
1325 (define_insn_and_split "*cmpfp_<mode>_cc"
1326 [(set (reg:CCFP FLAGS_REG)
1328 (match_operand:MODEF 1 "register_operand" "f")
1329 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1330 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1332 && TARGET_SAHF && !TARGET_CMOVE"
1334 "&& reload_completed"
1337 [(compare:CCFP (match_dup 1)(match_dup 2))]
1339 (set (reg:CC FLAGS_REG)
1340 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1342 [(set_attr "type" "multi")
1343 (set_attr "unit" "i387")
1344 (set_attr "mode" "<MODE>")])
1346 (define_insn "*cmpfp_u"
1347 [(set (match_operand:HI 0 "register_operand" "=a")
1350 (match_operand 1 "register_operand" "f")
1351 (match_operand 2 "register_operand" "f"))]
1353 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1354 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1355 "* return output_fp_compare (insn, operands, 0, 1);"
1356 [(set_attr "type" "multi")
1357 (set_attr "unit" "i387")
1359 (cond [(match_operand:SF 1 "" "")
1361 (match_operand:DF 1 "" "")
1364 (const_string "XF")))])
1366 (define_insn_and_split "*cmpfp_u_cc"
1367 [(set (reg:CCFPU FLAGS_REG)
1369 (match_operand 1 "register_operand" "f")
1370 (match_operand 2 "register_operand" "f")))
1371 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1372 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1373 && TARGET_SAHF && !TARGET_CMOVE
1374 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1376 "&& reload_completed"
1379 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1381 (set (reg:CC FLAGS_REG)
1382 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1384 [(set_attr "type" "multi")
1385 (set_attr "unit" "i387")
1387 (cond [(match_operand:SF 1 "" "")
1389 (match_operand:DF 1 "" "")
1392 (const_string "XF")))])
1394 (define_insn "*cmpfp_<mode>"
1395 [(set (match_operand:HI 0 "register_operand" "=a")
1398 (match_operand 1 "register_operand" "f")
1399 (match_operator 3 "float_operator"
1400 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1402 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1403 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1404 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1405 "* return output_fp_compare (insn, operands, 0, 0);"
1406 [(set_attr "type" "multi")
1407 (set_attr "unit" "i387")
1408 (set_attr "fp_int_src" "true")
1409 (set_attr "mode" "<MODE>")])
1411 (define_insn_and_split "*cmpfp_<mode>_cc"
1412 [(set (reg:CCFP FLAGS_REG)
1414 (match_operand 1 "register_operand" "f")
1415 (match_operator 3 "float_operator"
1416 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1417 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1418 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1419 && TARGET_SAHF && !TARGET_CMOVE
1420 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1421 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1423 "&& reload_completed"
1428 (match_op_dup 3 [(match_dup 2)]))]
1430 (set (reg:CC FLAGS_REG)
1431 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1433 [(set_attr "type" "multi")
1434 (set_attr "unit" "i387")
1435 (set_attr "fp_int_src" "true")
1436 (set_attr "mode" "<MODE>")])
1438 ;; FP compares, step 2
1439 ;; Move the fpsw to ax.
1441 (define_insn "x86_fnstsw_1"
1442 [(set (match_operand:HI 0 "register_operand" "=a")
1443 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1446 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1447 (set_attr "mode" "SI")
1448 (set_attr "unit" "i387")])
1450 ;; FP compares, step 3
1451 ;; Get ax into flags, general case.
1453 (define_insn "x86_sahf_1"
1454 [(set (reg:CC FLAGS_REG)
1455 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1459 #ifndef HAVE_AS_IX86_SAHF
1461 return ASM_BYTE "0x9e";
1466 [(set_attr "length" "1")
1467 (set_attr "athlon_decode" "vector")
1468 (set_attr "amdfam10_decode" "direct")
1469 (set_attr "bdver1_decode" "direct")
1470 (set_attr "mode" "SI")])
1472 ;; Pentium Pro can do steps 1 through 3 in one go.
1473 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1474 (define_insn "*cmpfp_i_mixed"
1475 [(set (reg:CCFP FLAGS_REG)
1476 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1477 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1478 "TARGET_MIX_SSE_I387
1479 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1480 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1481 "* return output_fp_compare (insn, operands, 1, 0);"
1482 [(set_attr "type" "fcmp,ssecomi")
1483 (set_attr "prefix" "orig,maybe_vex")
1485 (if_then_else (match_operand:SF 1 "" "")
1487 (const_string "DF")))
1488 (set (attr "prefix_rep")
1489 (if_then_else (eq_attr "type" "ssecomi")
1491 (const_string "*")))
1492 (set (attr "prefix_data16")
1493 (cond [(eq_attr "type" "fcmp")
1495 (eq_attr "mode" "DF")
1498 (const_string "0")))
1499 (set_attr "athlon_decode" "vector")
1500 (set_attr "amdfam10_decode" "direct")
1501 (set_attr "bdver1_decode" "double")])
1503 (define_insn "*cmpfp_i_sse"
1504 [(set (reg:CCFP FLAGS_REG)
1505 (compare:CCFP (match_operand 0 "register_operand" "x")
1506 (match_operand 1 "nonimmediate_operand" "xm")))]
1508 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1509 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1510 "* return output_fp_compare (insn, operands, 1, 0);"
1511 [(set_attr "type" "ssecomi")
1512 (set_attr "prefix" "maybe_vex")
1514 (if_then_else (match_operand:SF 1 "" "")
1516 (const_string "DF")))
1517 (set_attr "prefix_rep" "0")
1518 (set (attr "prefix_data16")
1519 (if_then_else (eq_attr "mode" "DF")
1521 (const_string "0")))
1522 (set_attr "athlon_decode" "vector")
1523 (set_attr "amdfam10_decode" "direct")
1524 (set_attr "bdver1_decode" "double")])
1526 (define_insn "*cmpfp_i_i387"
1527 [(set (reg:CCFP FLAGS_REG)
1528 (compare:CCFP (match_operand 0 "register_operand" "f")
1529 (match_operand 1 "register_operand" "f")))]
1530 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1532 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1533 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1534 "* return output_fp_compare (insn, operands, 1, 0);"
1535 [(set_attr "type" "fcmp")
1537 (cond [(match_operand:SF 1 "" "")
1539 (match_operand:DF 1 "" "")
1542 (const_string "XF")))
1543 (set_attr "athlon_decode" "vector")
1544 (set_attr "amdfam10_decode" "direct")
1545 (set_attr "bdver1_decode" "double")])
1547 (define_insn "*cmpfp_iu_mixed"
1548 [(set (reg:CCFPU FLAGS_REG)
1549 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1550 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1551 "TARGET_MIX_SSE_I387
1552 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1553 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1554 "* return output_fp_compare (insn, operands, 1, 1);"
1555 [(set_attr "type" "fcmp,ssecomi")
1556 (set_attr "prefix" "orig,maybe_vex")
1558 (if_then_else (match_operand:SF 1 "" "")
1560 (const_string "DF")))
1561 (set (attr "prefix_rep")
1562 (if_then_else (eq_attr "type" "ssecomi")
1564 (const_string "*")))
1565 (set (attr "prefix_data16")
1566 (cond [(eq_attr "type" "fcmp")
1568 (eq_attr "mode" "DF")
1571 (const_string "0")))
1572 (set_attr "athlon_decode" "vector")
1573 (set_attr "amdfam10_decode" "direct")
1574 (set_attr "bdver1_decode" "double")])
1576 (define_insn "*cmpfp_iu_sse"
1577 [(set (reg:CCFPU FLAGS_REG)
1578 (compare:CCFPU (match_operand 0 "register_operand" "x")
1579 (match_operand 1 "nonimmediate_operand" "xm")))]
1581 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1582 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1583 "* return output_fp_compare (insn, operands, 1, 1);"
1584 [(set_attr "type" "ssecomi")
1585 (set_attr "prefix" "maybe_vex")
1587 (if_then_else (match_operand:SF 1 "" "")
1589 (const_string "DF")))
1590 (set_attr "prefix_rep" "0")
1591 (set (attr "prefix_data16")
1592 (if_then_else (eq_attr "mode" "DF")
1594 (const_string "0")))
1595 (set_attr "athlon_decode" "vector")
1596 (set_attr "amdfam10_decode" "direct")
1597 (set_attr "bdver1_decode" "double")])
1599 (define_insn "*cmpfp_iu_387"
1600 [(set (reg:CCFPU FLAGS_REG)
1601 (compare:CCFPU (match_operand 0 "register_operand" "f")
1602 (match_operand 1 "register_operand" "f")))]
1603 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1605 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1606 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1607 "* return output_fp_compare (insn, operands, 1, 1);"
1608 [(set_attr "type" "fcmp")
1610 (cond [(match_operand:SF 1 "" "")
1612 (match_operand:DF 1 "" "")
1615 (const_string "XF")))
1616 (set_attr "athlon_decode" "vector")
1617 (set_attr "amdfam10_decode" "direct")
1618 (set_attr "bdver1_decode" "direct")])
1620 ;; Push/pop instructions.
1622 (define_insn "*push<mode>2"
1623 [(set (match_operand:DWI 0 "push_operand" "=<")
1624 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1629 [(set (match_operand:TI 0 "push_operand" "")
1630 (match_operand:TI 1 "general_operand" ""))]
1631 "TARGET_64BIT && reload_completed
1632 && !SSE_REG_P (operands[1])"
1634 "ix86_split_long_move (operands); DONE;")
1636 (define_insn "*pushdi2_rex64"
1637 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1638 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1643 [(set_attr "type" "push,multi")
1644 (set_attr "mode" "DI")])
1646 ;; Convert impossible pushes of immediate to existing instructions.
1647 ;; First try to get scratch register and go through it. In case this
1648 ;; fails, push sign extended lower part first and then overwrite
1649 ;; upper part by 32bit move.
1651 [(match_scratch:DI 2 "r")
1652 (set (match_operand:DI 0 "push_operand" "")
1653 (match_operand:DI 1 "immediate_operand" ""))]
1654 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1655 && !x86_64_immediate_operand (operands[1], DImode)"
1656 [(set (match_dup 2) (match_dup 1))
1657 (set (match_dup 0) (match_dup 2))])
1659 ;; We need to define this as both peepholer and splitter for case
1660 ;; peephole2 pass is not run.
1661 ;; "&& 1" is needed to keep it from matching the previous pattern.
1663 [(set (match_operand:DI 0 "push_operand" "")
1664 (match_operand:DI 1 "immediate_operand" ""))]
1665 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1666 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1667 [(set (match_dup 0) (match_dup 1))
1668 (set (match_dup 2) (match_dup 3))]
1670 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1672 operands[1] = gen_lowpart (DImode, operands[2]);
1673 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1678 [(set (match_operand:DI 0 "push_operand" "")
1679 (match_operand:DI 1 "immediate_operand" ""))]
1680 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1681 ? epilogue_completed : reload_completed)
1682 && !symbolic_operand (operands[1], DImode)
1683 && !x86_64_immediate_operand (operands[1], DImode)"
1684 [(set (match_dup 0) (match_dup 1))
1685 (set (match_dup 2) (match_dup 3))]
1687 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1689 operands[1] = gen_lowpart (DImode, operands[2]);
1690 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1695 [(set (match_operand:DI 0 "push_operand" "")
1696 (match_operand:DI 1 "general_operand" ""))]
1697 "!TARGET_64BIT && reload_completed
1698 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1700 "ix86_split_long_move (operands); DONE;")
1702 (define_insn "*pushsi2"
1703 [(set (match_operand:SI 0 "push_operand" "=<")
1704 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1707 [(set_attr "type" "push")
1708 (set_attr "mode" "SI")])
1710 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1711 ;; "push a byte/word". But actually we use pushl, which has the effect
1712 ;; of rounding the amount pushed up to a word.
1714 ;; For TARGET_64BIT we always round up to 8 bytes.
1715 (define_insn "*push<mode>2_rex64"
1716 [(set (match_operand:SWI124 0 "push_operand" "=X")
1717 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1720 [(set_attr "type" "push")
1721 (set_attr "mode" "DI")])
1723 (define_insn "*push<mode>2"
1724 [(set (match_operand:SWI12 0 "push_operand" "=X")
1725 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1728 [(set_attr "type" "push")
1729 (set_attr "mode" "SI")])
1731 (define_insn "*push<mode>2_prologue"
1732 [(set (match_operand:P 0 "push_operand" "=<")
1733 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1734 (clobber (mem:BLK (scratch)))]
1736 "push{<imodesuffix>}\t%1"
1737 [(set_attr "type" "push")
1738 (set_attr "mode" "<MODE>")])
1740 (define_insn "*pop<mode>1"
1741 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1742 (match_operand:P 1 "pop_operand" ">"))]
1744 "pop{<imodesuffix>}\t%0"
1745 [(set_attr "type" "pop")
1746 (set_attr "mode" "<MODE>")])
1748 (define_insn "*pop<mode>1_epilogue"
1749 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1750 (match_operand:P 1 "pop_operand" ">"))
1751 (clobber (mem:BLK (scratch)))]
1753 "pop{<imodesuffix>}\t%0"
1754 [(set_attr "type" "pop")
1755 (set_attr "mode" "<MODE>")])
1757 ;; Move instructions.
1759 (define_expand "movoi"
1760 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1761 (match_operand:OI 1 "general_operand" ""))]
1763 "ix86_expand_move (OImode, operands); DONE;")
1765 (define_expand "movti"
1766 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1767 (match_operand:TI 1 "nonimmediate_operand" ""))]
1768 "TARGET_64BIT || TARGET_SSE"
1771 ix86_expand_move (TImode, operands);
1772 else if (push_operand (operands[0], TImode))
1773 ix86_expand_push (TImode, operands[1]);
1775 ix86_expand_vector_move (TImode, operands);
1779 ;; This expands to what emit_move_complex would generate if we didn't
1780 ;; have a movti pattern. Having this avoids problems with reload on
1781 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1782 ;; to have around all the time.
1783 (define_expand "movcdi"
1784 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1785 (match_operand:CDI 1 "general_operand" ""))]
1788 if (push_operand (operands[0], CDImode))
1789 emit_move_complex_push (CDImode, operands[0], operands[1]);
1791 emit_move_complex_parts (operands[0], operands[1]);
1795 (define_expand "mov<mode>"
1796 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1797 (match_operand:SWI1248x 1 "general_operand" ""))]
1799 "ix86_expand_move (<MODE>mode, operands); DONE;")
1801 (define_insn "*mov<mode>_xor"
1802 [(set (match_operand:SWI48 0 "register_operand" "=r")
1803 (match_operand:SWI48 1 "const0_operand" ""))
1804 (clobber (reg:CC FLAGS_REG))]
1807 [(set_attr "type" "alu1")
1808 (set_attr "mode" "SI")
1809 (set_attr "length_immediate" "0")])
1811 (define_insn "*mov<mode>_or"
1812 [(set (match_operand:SWI48 0 "register_operand" "=r")
1813 (match_operand:SWI48 1 "const_int_operand" ""))
1814 (clobber (reg:CC FLAGS_REG))]
1816 && operands[1] == constm1_rtx"
1817 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1818 [(set_attr "type" "alu1")
1819 (set_attr "mode" "<MODE>")
1820 (set_attr "length_immediate" "1")])
1822 (define_insn "*movoi_internal_avx"
1823 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1824 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1825 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1827 switch (which_alternative)
1830 return "vxorps\t%0, %0, %0";
1833 if (misaligned_operand (operands[0], OImode)
1834 || misaligned_operand (operands[1], OImode))
1835 return "vmovdqu\t{%1, %0|%0, %1}";
1837 return "vmovdqa\t{%1, %0|%0, %1}";
1842 [(set_attr "type" "sselog1,ssemov,ssemov")
1843 (set_attr "prefix" "vex")
1844 (set_attr "mode" "OI")])
1846 (define_insn "*movti_internal_rex64"
1847 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1848 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1849 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1851 switch (which_alternative)
1857 if (get_attr_mode (insn) == MODE_V4SF)
1858 return "%vxorps\t%0, %d0";
1860 return "%vpxor\t%0, %d0";
1863 /* TDmode values are passed as TImode on the stack. Moving them
1864 to stack may result in unaligned memory access. */
1865 if (misaligned_operand (operands[0], TImode)
1866 || misaligned_operand (operands[1], TImode))
1868 if (get_attr_mode (insn) == MODE_V4SF)
1869 return "%vmovups\t{%1, %0|%0, %1}";
1871 return "%vmovdqu\t{%1, %0|%0, %1}";
1875 if (get_attr_mode (insn) == MODE_V4SF)
1876 return "%vmovaps\t{%1, %0|%0, %1}";
1878 return "%vmovdqa\t{%1, %0|%0, %1}";
1884 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1885 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1887 (cond [(eq_attr "alternative" "2,3")
1889 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1891 (const_string "V4SF")
1892 (const_string "TI"))
1893 (eq_attr "alternative" "4")
1895 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1897 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1899 (const_string "V4SF")
1900 (const_string "TI"))]
1901 (const_string "DI")))])
1904 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1905 (match_operand:TI 1 "general_operand" ""))]
1907 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1909 "ix86_split_long_move (operands); DONE;")
1911 (define_insn "*movti_internal_sse"
1912 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1913 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1914 "TARGET_SSE && !TARGET_64BIT
1915 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1917 switch (which_alternative)
1920 if (get_attr_mode (insn) == MODE_V4SF)
1921 return "%vxorps\t%0, %d0";
1923 return "%vpxor\t%0, %d0";
1926 /* TDmode values are passed as TImode on the stack. Moving them
1927 to stack may result in unaligned memory access. */
1928 if (misaligned_operand (operands[0], TImode)
1929 || misaligned_operand (operands[1], TImode))
1931 if (get_attr_mode (insn) == MODE_V4SF)
1932 return "%vmovups\t{%1, %0|%0, %1}";
1934 return "%vmovdqu\t{%1, %0|%0, %1}";
1938 if (get_attr_mode (insn) == MODE_V4SF)
1939 return "%vmovaps\t{%1, %0|%0, %1}";
1941 return "%vmovdqa\t{%1, %0|%0, %1}";
1947 [(set_attr "type" "sselog1,ssemov,ssemov")
1948 (set_attr "prefix" "maybe_vex")
1950 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1951 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1953 (const_string "V4SF")
1954 (and (eq_attr "alternative" "2")
1955 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1957 (const_string "V4SF")]
1958 (const_string "TI")))])
1960 (define_insn "*movdi_internal_rex64"
1961 [(set (match_operand:DI 0 "nonimmediate_operand"
1962 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1963 (match_operand:DI 1 "general_operand"
1964 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1965 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1967 switch (get_attr_type (insn))
1970 if (SSE_REG_P (operands[0]))
1971 return "movq2dq\t{%1, %0|%0, %1}";
1973 return "movdq2q\t{%1, %0|%0, %1}";
1978 if (get_attr_mode (insn) == MODE_TI)
1979 return "vmovdqa\t{%1, %0|%0, %1}";
1981 return "vmovq\t{%1, %0|%0, %1}";
1984 if (get_attr_mode (insn) == MODE_TI)
1985 return "movdqa\t{%1, %0|%0, %1}";
1989 /* Moves from and into integer register is done using movd
1990 opcode with REX prefix. */
1991 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1992 return "movd\t{%1, %0|%0, %1}";
1993 return "movq\t{%1, %0|%0, %1}";
1996 return "%vpxor\t%0, %d0";
1999 return "pxor\t%0, %0";
2005 return "lea{q}\t{%a1, %0|%0, %a1}";
2008 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2009 if (get_attr_mode (insn) == MODE_SI)
2010 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2011 else if (which_alternative == 2)
2012 return "movabs{q}\t{%1, %0|%0, %1}";
2014 return "mov{q}\t{%1, %0|%0, %1}";
2018 (cond [(eq_attr "alternative" "5")
2019 (const_string "mmx")
2020 (eq_attr "alternative" "6,7,8,9,10")
2021 (const_string "mmxmov")
2022 (eq_attr "alternative" "11")
2023 (const_string "sselog1")
2024 (eq_attr "alternative" "12,13,14,15,16")
2025 (const_string "ssemov")
2026 (eq_attr "alternative" "17,18")
2027 (const_string "ssecvt")
2028 (eq_attr "alternative" "4")
2029 (const_string "multi")
2030 (match_operand:DI 1 "pic_32bit_operand" "")
2031 (const_string "lea")
2033 (const_string "imov")))
2036 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2038 (const_string "*")))
2039 (set (attr "length_immediate")
2041 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2043 (const_string "*")))
2044 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2045 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2046 (set (attr "prefix")
2047 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2048 (const_string "maybe_vex")
2049 (const_string "orig")))
2050 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2052 ;; Convert impossible stores of immediate to existing instructions.
2053 ;; First try to get scratch register and go through it. In case this
2054 ;; fails, move by 32bit parts.
2056 [(match_scratch:DI 2 "r")
2057 (set (match_operand:DI 0 "memory_operand" "")
2058 (match_operand:DI 1 "immediate_operand" ""))]
2059 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2060 && !x86_64_immediate_operand (operands[1], DImode)"
2061 [(set (match_dup 2) (match_dup 1))
2062 (set (match_dup 0) (match_dup 2))])
2064 ;; We need to define this as both peepholer and splitter for case
2065 ;; peephole2 pass is not run.
2066 ;; "&& 1" is needed to keep it from matching the previous pattern.
2068 [(set (match_operand:DI 0 "memory_operand" "")
2069 (match_operand:DI 1 "immediate_operand" ""))]
2070 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2071 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2072 [(set (match_dup 2) (match_dup 3))
2073 (set (match_dup 4) (match_dup 5))]
2074 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2077 [(set (match_operand:DI 0 "memory_operand" "")
2078 (match_operand:DI 1 "immediate_operand" ""))]
2079 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2080 ? epilogue_completed : reload_completed)
2081 && !symbolic_operand (operands[1], DImode)
2082 && !x86_64_immediate_operand (operands[1], DImode)"
2083 [(set (match_dup 2) (match_dup 3))
2084 (set (match_dup 4) (match_dup 5))]
2085 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2087 (define_insn "*movdi_internal"
2088 [(set (match_operand:DI 0 "nonimmediate_operand"
2089 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2090 (match_operand:DI 1 "general_operand"
2091 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2092 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2097 movq\t{%1, %0|%0, %1}
2098 movq\t{%1, %0|%0, %1}
2100 %vmovq\t{%1, %0|%0, %1}
2101 %vmovdqa\t{%1, %0|%0, %1}
2102 %vmovq\t{%1, %0|%0, %1}
2104 movlps\t{%1, %0|%0, %1}
2105 movaps\t{%1, %0|%0, %1}
2106 movlps\t{%1, %0|%0, %1}"
2107 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2108 (set (attr "prefix")
2109 (if_then_else (eq_attr "alternative" "5,6,7,8")
2110 (const_string "vex")
2111 (const_string "orig")))
2112 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2115 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2116 (match_operand:DI 1 "general_operand" ""))]
2117 "!TARGET_64BIT && reload_completed
2118 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2119 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2121 "ix86_split_long_move (operands); DONE;")
2123 (define_insn "*movsi_internal"
2124 [(set (match_operand:SI 0 "nonimmediate_operand"
2125 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2126 (match_operand:SI 1 "general_operand"
2127 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2128 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2130 switch (get_attr_type (insn))
2133 if (get_attr_mode (insn) == MODE_TI)
2134 return "%vpxor\t%0, %d0";
2135 return "%vxorps\t%0, %d0";
2138 switch (get_attr_mode (insn))
2141 return "%vmovdqa\t{%1, %0|%0, %1}";
2143 return "%vmovaps\t{%1, %0|%0, %1}";
2145 return "%vmovd\t{%1, %0|%0, %1}";
2147 return "%vmovss\t{%1, %0|%0, %1}";
2153 return "pxor\t%0, %0";
2156 if (get_attr_mode (insn) == MODE_DI)
2157 return "movq\t{%1, %0|%0, %1}";
2158 return "movd\t{%1, %0|%0, %1}";
2161 return "lea{l}\t{%a1, %0|%0, %a1}";
2164 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2165 return "mov{l}\t{%1, %0|%0, %1}";
2169 (cond [(eq_attr "alternative" "2")
2170 (const_string "mmx")
2171 (eq_attr "alternative" "3,4,5")
2172 (const_string "mmxmov")
2173 (eq_attr "alternative" "6")
2174 (const_string "sselog1")
2175 (eq_attr "alternative" "7,8,9,10,11")
2176 (const_string "ssemov")
2177 (match_operand:DI 1 "pic_32bit_operand" "")
2178 (const_string "lea")
2180 (const_string "imov")))
2181 (set (attr "prefix")
2182 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2183 (const_string "orig")
2184 (const_string "maybe_vex")))
2185 (set (attr "prefix_data16")
2186 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2188 (const_string "*")))
2190 (cond [(eq_attr "alternative" "2,3")
2192 (eq_attr "alternative" "6,7")
2194 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2195 (const_string "V4SF")
2196 (const_string "TI"))
2197 (and (eq_attr "alternative" "8,9,10,11")
2198 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2201 (const_string "SI")))])
2203 (define_insn "*movhi_internal"
2204 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2205 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2206 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2208 switch (get_attr_type (insn))
2211 /* movzwl is faster than movw on p2 due to partial word stalls,
2212 though not as fast as an aligned movl. */
2213 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2215 if (get_attr_mode (insn) == MODE_SI)
2216 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2218 return "mov{w}\t{%1, %0|%0, %1}";
2222 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2224 (const_string "imov")
2225 (and (eq_attr "alternative" "0")
2226 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2228 (eq (symbol_ref "TARGET_HIMODE_MATH")
2230 (const_string "imov")
2231 (and (eq_attr "alternative" "1,2")
2232 (match_operand:HI 1 "aligned_operand" ""))
2233 (const_string "imov")
2234 (and (ne (symbol_ref "TARGET_MOVX")
2236 (eq_attr "alternative" "0,2"))
2237 (const_string "imovx")
2239 (const_string "imov")))
2241 (cond [(eq_attr "type" "imovx")
2243 (and (eq_attr "alternative" "1,2")
2244 (match_operand:HI 1 "aligned_operand" ""))
2246 (and (eq_attr "alternative" "0")
2247 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2249 (eq (symbol_ref "TARGET_HIMODE_MATH")
2253 (const_string "HI")))])
2255 ;; Situation is quite tricky about when to choose full sized (SImode) move
2256 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2257 ;; partial register dependency machines (such as AMD Athlon), where QImode
2258 ;; moves issue extra dependency and for partial register stalls machines
2259 ;; that don't use QImode patterns (and QImode move cause stall on the next
2262 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2263 ;; register stall machines with, where we use QImode instructions, since
2264 ;; partial register stall can be caused there. Then we use movzx.
2265 (define_insn "*movqi_internal"
2266 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2267 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2268 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2270 switch (get_attr_type (insn))
2273 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2274 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2276 if (get_attr_mode (insn) == MODE_SI)
2277 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2279 return "mov{b}\t{%1, %0|%0, %1}";
2283 (cond [(and (eq_attr "alternative" "5")
2284 (not (match_operand:QI 1 "aligned_operand" "")))
2285 (const_string "imovx")
2286 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2288 (const_string "imov")
2289 (and (eq_attr "alternative" "3")
2290 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2292 (eq (symbol_ref "TARGET_QIMODE_MATH")
2294 (const_string "imov")
2295 (eq_attr "alternative" "3,5")
2296 (const_string "imovx")
2297 (and (ne (symbol_ref "TARGET_MOVX")
2299 (eq_attr "alternative" "2"))
2300 (const_string "imovx")
2302 (const_string "imov")))
2304 (cond [(eq_attr "alternative" "3,4,5")
2306 (eq_attr "alternative" "6")
2308 (eq_attr "type" "imovx")
2310 (and (eq_attr "type" "imov")
2311 (and (eq_attr "alternative" "0,1")
2312 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2314 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2316 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2319 ;; Avoid partial register stalls when not using QImode arithmetic
2320 (and (eq_attr "type" "imov")
2321 (and (eq_attr "alternative" "0,1")
2322 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2324 (eq (symbol_ref "TARGET_QIMODE_MATH")
2328 (const_string "QI")))])
2330 ;; Stores and loads of ax to arbitrary constant address.
2331 ;; We fake an second form of instruction to force reload to load address
2332 ;; into register when rax is not available
2333 (define_insn "*movabs<mode>_1"
2334 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2335 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2336 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2338 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2339 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2340 [(set_attr "type" "imov")
2341 (set_attr "modrm" "0,*")
2342 (set_attr "length_address" "8,0")
2343 (set_attr "length_immediate" "0,*")
2344 (set_attr "memory" "store")
2345 (set_attr "mode" "<MODE>")])
2347 (define_insn "*movabs<mode>_2"
2348 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2349 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2350 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2352 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2353 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2354 [(set_attr "type" "imov")
2355 (set_attr "modrm" "0,*")
2356 (set_attr "length_address" "8,0")
2357 (set_attr "length_immediate" "0")
2358 (set_attr "memory" "load")
2359 (set_attr "mode" "<MODE>")])
2361 (define_insn "*swap<mode>"
2362 [(set (match_operand:SWI48 0 "register_operand" "+r")
2363 (match_operand:SWI48 1 "register_operand" "+r"))
2367 "xchg{<imodesuffix>}\t%1, %0"
2368 [(set_attr "type" "imov")
2369 (set_attr "mode" "<MODE>")
2370 (set_attr "pent_pair" "np")
2371 (set_attr "athlon_decode" "vector")
2372 (set_attr "amdfam10_decode" "double")
2373 (set_attr "bdver1_decode" "double")])
2375 (define_insn "*swap<mode>_1"
2376 [(set (match_operand:SWI12 0 "register_operand" "+r")
2377 (match_operand:SWI12 1 "register_operand" "+r"))
2380 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2382 [(set_attr "type" "imov")
2383 (set_attr "mode" "SI")
2384 (set_attr "pent_pair" "np")
2385 (set_attr "athlon_decode" "vector")
2386 (set_attr "amdfam10_decode" "double")
2387 (set_attr "bdver1_decode" "double")])
2389 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2390 ;; is disabled for AMDFAM10
2391 (define_insn "*swap<mode>_2"
2392 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2393 (match_operand:SWI12 1 "register_operand" "+<r>"))
2396 "TARGET_PARTIAL_REG_STALL"
2397 "xchg{<imodesuffix>}\t%1, %0"
2398 [(set_attr "type" "imov")
2399 (set_attr "mode" "<MODE>")
2400 (set_attr "pent_pair" "np")
2401 (set_attr "athlon_decode" "vector")])
2403 (define_expand "movstrict<mode>"
2404 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2405 (match_operand:SWI12 1 "general_operand" ""))]
2408 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2410 /* Don't generate memory->memory moves, go through a register */
2411 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2412 operands[1] = force_reg (<MODE>mode, operands[1]);
2415 (define_insn "*movstrict<mode>_1"
2416 [(set (strict_low_part
2417 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2418 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2419 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2420 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2421 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2422 [(set_attr "type" "imov")
2423 (set_attr "mode" "<MODE>")])
2425 (define_insn "*movstrict<mode>_xor"
2426 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2427 (match_operand:SWI12 1 "const0_operand" ""))
2428 (clobber (reg:CC FLAGS_REG))]
2430 "xor{<imodesuffix>}\t%0, %0"
2431 [(set_attr "type" "alu1")
2432 (set_attr "mode" "<MODE>")
2433 (set_attr "length_immediate" "0")])
2435 (define_insn "*mov<mode>_extv_1"
2436 [(set (match_operand:SWI24 0 "register_operand" "=R")
2437 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2441 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2442 [(set_attr "type" "imovx")
2443 (set_attr "mode" "SI")])
2445 (define_insn "*movqi_extv_1_rex64"
2446 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2447 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2452 switch (get_attr_type (insn))
2455 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2457 return "mov{b}\t{%h1, %0|%0, %h1}";
2461 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2462 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2463 (ne (symbol_ref "TARGET_MOVX")
2465 (const_string "imovx")
2466 (const_string "imov")))
2468 (if_then_else (eq_attr "type" "imovx")
2470 (const_string "QI")))])
2472 (define_insn "*movqi_extv_1"
2473 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2474 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2479 switch (get_attr_type (insn))
2482 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2484 return "mov{b}\t{%h1, %0|%0, %h1}";
2488 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2489 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2490 (ne (symbol_ref "TARGET_MOVX")
2492 (const_string "imovx")
2493 (const_string "imov")))
2495 (if_then_else (eq_attr "type" "imovx")
2497 (const_string "QI")))])
2499 (define_insn "*mov<mode>_extzv_1"
2500 [(set (match_operand:SWI48 0 "register_operand" "=R")
2501 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2505 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2506 [(set_attr "type" "imovx")
2507 (set_attr "mode" "SI")])
2509 (define_insn "*movqi_extzv_2_rex64"
2510 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2512 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2517 switch (get_attr_type (insn))
2520 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2522 return "mov{b}\t{%h1, %0|%0, %h1}";
2526 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2527 (ne (symbol_ref "TARGET_MOVX")
2529 (const_string "imovx")
2530 (const_string "imov")))
2532 (if_then_else (eq_attr "type" "imovx")
2534 (const_string "QI")))])
2536 (define_insn "*movqi_extzv_2"
2537 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2539 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2544 switch (get_attr_type (insn))
2547 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2549 return "mov{b}\t{%h1, %0|%0, %h1}";
2553 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2554 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2555 (ne (symbol_ref "TARGET_MOVX")
2557 (const_string "imovx")
2558 (const_string "imov")))
2560 (if_then_else (eq_attr "type" "imovx")
2562 (const_string "QI")))])
2564 (define_expand "mov<mode>_insv_1"
2565 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2568 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2570 (define_insn "*mov<mode>_insv_1_rex64"
2571 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2574 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2576 "mov{b}\t{%b1, %h0|%h0, %b1}"
2577 [(set_attr "type" "imov")
2578 (set_attr "mode" "QI")])
2580 (define_insn "*movsi_insv_1"
2581 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2584 (match_operand:SI 1 "general_operand" "Qmn"))]
2586 "mov{b}\t{%b1, %h0|%h0, %b1}"
2587 [(set_attr "type" "imov")
2588 (set_attr "mode" "QI")])
2590 (define_insn "*movqi_insv_2"
2591 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2594 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2597 "mov{b}\t{%h1, %h0|%h0, %h1}"
2598 [(set_attr "type" "imov")
2599 (set_attr "mode" "QI")])
2601 ;; Floating point push instructions.
2603 (define_insn "*pushtf"
2604 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2605 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2608 /* This insn should be already split before reg-stack. */
2611 [(set_attr "type" "multi")
2612 (set_attr "unit" "sse,*,*")
2613 (set_attr "mode" "TF,SI,SI")])
2616 [(set (match_operand:TF 0 "push_operand" "")
2617 (match_operand:TF 1 "sse_reg_operand" ""))]
2618 "TARGET_SSE2 && reload_completed"
2619 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2620 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2623 [(set (match_operand:TF 0 "push_operand" "")
2624 (match_operand:TF 1 "general_operand" ""))]
2625 "TARGET_SSE2 && reload_completed
2626 && !SSE_REG_P (operands[1])"
2628 "ix86_split_long_move (operands); DONE;")
2630 (define_insn "*pushxf"
2631 [(set (match_operand:XF 0 "push_operand" "=<,<")
2632 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2633 "optimize_function_for_speed_p (cfun)"
2635 /* This insn should be already split before reg-stack. */
2638 [(set_attr "type" "multi")
2639 (set_attr "unit" "i387,*")
2640 (set_attr "mode" "XF,SI")])
2642 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2643 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2644 ;; Pushing using integer instructions is longer except for constants
2645 ;; and direct memory references (assuming that any given constant is pushed
2646 ;; only once, but this ought to be handled elsewhere).
2648 (define_insn "*pushxf_nointeger"
2649 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2650 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2651 "optimize_function_for_size_p (cfun)"
2653 /* This insn should be already split before reg-stack. */
2656 [(set_attr "type" "multi")
2657 (set_attr "unit" "i387,*,*")
2658 (set_attr "mode" "XF,SI,SI")])
2661 [(set (match_operand:XF 0 "push_operand" "")
2662 (match_operand:XF 1 "fp_register_operand" ""))]
2664 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2665 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2666 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2669 [(set (match_operand:XF 0 "push_operand" "")
2670 (match_operand:XF 1 "general_operand" ""))]
2672 && !FP_REG_P (operands[1])"
2674 "ix86_split_long_move (operands); DONE;")
2676 (define_insn "*pushdf"
2677 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2678 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2679 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2681 /* This insn should be already split before reg-stack. */
2684 [(set_attr "type" "multi")
2685 (set_attr "unit" "i387,*,*")
2686 (set_attr "mode" "DF,SI,DF")])
2688 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2689 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2690 ;; On the average, pushdf using integers can be still shorter. Allow this
2691 ;; pattern for optimize_size too.
2693 (define_insn "*pushdf_nointeger"
2694 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2695 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2696 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2698 /* This insn should be already split before reg-stack. */
2701 [(set_attr "type" "multi")
2702 (set_attr "unit" "i387,*,*,*")
2703 (set_attr "mode" "DF,SI,SI,DF")])
2705 ;; %%% Kill this when call knows how to work this out.
2707 [(set (match_operand:DF 0 "push_operand" "")
2708 (match_operand:DF 1 "any_fp_register_operand" ""))]
2710 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2711 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2714 [(set (match_operand:DF 0 "push_operand" "")
2715 (match_operand:DF 1 "general_operand" ""))]
2717 && !ANY_FP_REG_P (operands[1])"
2719 "ix86_split_long_move (operands); DONE;")
2721 (define_insn "*pushsf_rex64"
2722 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2723 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2726 /* Anything else should be already split before reg-stack. */
2727 gcc_assert (which_alternative == 1);
2728 return "push{q}\t%q1";
2730 [(set_attr "type" "multi,push,multi")
2731 (set_attr "unit" "i387,*,*")
2732 (set_attr "mode" "SF,DI,SF")])
2734 (define_insn "*pushsf"
2735 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2736 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2739 /* Anything else should be already split before reg-stack. */
2740 gcc_assert (which_alternative == 1);
2741 return "push{l}\t%1";
2743 [(set_attr "type" "multi,push,multi")
2744 (set_attr "unit" "i387,*,*")
2745 (set_attr "mode" "SF,SI,SF")])
2748 [(set (match_operand:SF 0 "push_operand" "")
2749 (match_operand:SF 1 "memory_operand" ""))]
2751 && MEM_P (operands[1])
2752 && (operands[2] = find_constant_src (insn))"
2756 ;; %%% Kill this when call knows how to work this out.
2758 [(set (match_operand:SF 0 "push_operand" "")
2759 (match_operand:SF 1 "any_fp_register_operand" ""))]
2761 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2762 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2763 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2765 ;; Floating point move instructions.
2767 (define_expand "movtf"
2768 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2769 (match_operand:TF 1 "nonimmediate_operand" ""))]
2772 ix86_expand_move (TFmode, operands);
2776 (define_expand "mov<mode>"
2777 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2778 (match_operand:X87MODEF 1 "general_operand" ""))]
2780 "ix86_expand_move (<MODE>mode, operands); DONE;")
2782 (define_insn "*movtf_internal"
2783 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2784 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2786 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2788 switch (which_alternative)
2792 if (get_attr_mode (insn) == MODE_V4SF)
2793 return "%vmovaps\t{%1, %0|%0, %1}";
2795 return "%vmovdqa\t{%1, %0|%0, %1}";
2797 if (get_attr_mode (insn) == MODE_V4SF)
2798 return "%vxorps\t%0, %d0";
2800 return "%vpxor\t%0, %d0";
2808 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2809 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2811 (cond [(eq_attr "alternative" "0,2")
2813 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2815 (const_string "V4SF")
2816 (const_string "TI"))
2817 (eq_attr "alternative" "1")
2819 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2821 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2823 (const_string "V4SF")
2824 (const_string "TI"))]
2825 (const_string "DI")))])
2828 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2829 (match_operand:TF 1 "general_operand" ""))]
2831 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2833 "ix86_split_long_move (operands); DONE;")
2835 (define_insn "*movxf_internal"
2836 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2837 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2838 "optimize_function_for_speed_p (cfun)
2839 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2840 && (reload_in_progress || reload_completed
2841 || GET_CODE (operands[1]) != CONST_DOUBLE
2842 || memory_operand (operands[0], XFmode))"
2844 switch (which_alternative)
2848 return output_387_reg_move (insn, operands);
2851 return standard_80387_constant_opcode (operands[1]);
2860 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2861 (set_attr "mode" "XF,XF,XF,SI,SI")])
2863 ;; Do not use integer registers when optimizing for size
2864 (define_insn "*movxf_internal_nointeger"
2865 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2866 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2867 "optimize_function_for_size_p (cfun)
2868 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2869 && (reload_in_progress || reload_completed
2870 || standard_80387_constant_p (operands[1])
2871 || GET_CODE (operands[1]) != CONST_DOUBLE
2872 || memory_operand (operands[0], XFmode))"
2874 switch (which_alternative)
2878 return output_387_reg_move (insn, operands);
2881 return standard_80387_constant_opcode (operands[1]);
2889 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2890 (set_attr "mode" "XF,XF,XF,SI,SI")])
2893 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2894 (match_operand:XF 1 "general_operand" ""))]
2896 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2897 && ! (FP_REG_P (operands[0]) ||
2898 (GET_CODE (operands[0]) == SUBREG
2899 && FP_REG_P (SUBREG_REG (operands[0]))))
2900 && ! (FP_REG_P (operands[1]) ||
2901 (GET_CODE (operands[1]) == SUBREG
2902 && FP_REG_P (SUBREG_REG (operands[1]))))"
2904 "ix86_split_long_move (operands); DONE;")
2906 (define_insn "*movdf_internal_rex64"
2907 [(set (match_operand:DF 0 "nonimmediate_operand"
2908 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2909 (match_operand:DF 1 "general_operand"
2910 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2911 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2912 && (reload_in_progress || reload_completed
2913 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2914 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2915 && optimize_function_for_size_p (cfun)
2916 && standard_80387_constant_p (operands[1]))
2917 || GET_CODE (operands[1]) != CONST_DOUBLE
2918 || memory_operand (operands[0], DFmode))"
2920 switch (which_alternative)
2924 return output_387_reg_move (insn, operands);
2927 return standard_80387_constant_opcode (operands[1]);
2934 switch (get_attr_mode (insn))
2937 return "%vxorps\t%0, %d0";
2939 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2940 return "%vxorps\t%0, %d0";
2942 return "%vxorpd\t%0, %d0";
2944 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2945 return "%vxorps\t%0, %d0";
2947 return "%vpxor\t%0, %d0";
2954 switch (get_attr_mode (insn))
2957 return "%vmovaps\t{%1, %0|%0, %1}";
2959 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2960 return "%vmovaps\t{%1, %0|%0, %1}";
2962 return "%vmovapd\t{%1, %0|%0, %1}";
2964 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2965 return "%vmovaps\t{%1, %0|%0, %1}";
2967 return "%vmovdqa\t{%1, %0|%0, %1}";
2969 return "%vmovq\t{%1, %0|%0, %1}";
2973 if (REG_P (operands[0]) && REG_P (operands[1]))
2974 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2976 return "vmovsd\t{%1, %0|%0, %1}";
2979 return "movsd\t{%1, %0|%0, %1}";
2981 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2983 return "%vmovlps\t{%1, %d0|%d0, %1}";
2990 return "%vmovd\t{%1, %0|%0, %1}";
2996 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2997 (set (attr "prefix")
2998 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2999 (const_string "orig")
3000 (const_string "maybe_vex")))
3001 (set (attr "prefix_data16")
3002 (if_then_else (eq_attr "mode" "V1DF")
3004 (const_string "*")))
3006 (cond [(eq_attr "alternative" "0,1,2")
3008 (eq_attr "alternative" "3,4,9,10")
3011 /* For SSE1, we have many fewer alternatives. */
3012 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3013 (cond [(eq_attr "alternative" "5,6")
3014 (const_string "V4SF")
3016 (const_string "V2SF"))
3018 /* xorps is one byte shorter. */
3019 (eq_attr "alternative" "5")
3020 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3022 (const_string "V4SF")
3023 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3027 (const_string "V2DF"))
3029 /* For architectures resolving dependencies on
3030 whole SSE registers use APD move to break dependency
3031 chains, otherwise use short move to avoid extra work.
3033 movaps encodes one byte shorter. */
3034 (eq_attr "alternative" "6")
3036 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3038 (const_string "V4SF")
3039 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3041 (const_string "V2DF")
3043 (const_string "DF"))
3044 /* For architectures resolving dependencies on register
3045 parts we may avoid extra work to zero out upper part
3047 (eq_attr "alternative" "7")
3049 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3051 (const_string "V1DF")
3052 (const_string "DF"))
3054 (const_string "DF")))])
3056 (define_insn "*movdf_internal"
3057 [(set (match_operand:DF 0 "nonimmediate_operand"
3058 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3059 (match_operand:DF 1 "general_operand"
3060 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3061 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3062 && optimize_function_for_speed_p (cfun)
3063 && TARGET_INTEGER_DFMODE_MOVES
3064 && (reload_in_progress || reload_completed
3065 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3066 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3067 && optimize_function_for_size_p (cfun)
3068 && standard_80387_constant_p (operands[1]))
3069 || GET_CODE (operands[1]) != CONST_DOUBLE
3070 || memory_operand (operands[0], DFmode))"
3072 switch (which_alternative)
3076 return output_387_reg_move (insn, operands);
3079 return standard_80387_constant_opcode (operands[1]);
3086 switch (get_attr_mode (insn))
3089 return "xorps\t%0, %0";
3091 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3092 return "xorps\t%0, %0";
3094 return "xorpd\t%0, %0";
3096 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3097 return "xorps\t%0, %0";
3099 return "pxor\t%0, %0";
3106 switch (get_attr_mode (insn))
3109 return "movaps\t{%1, %0|%0, %1}";
3111 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3112 return "movaps\t{%1, %0|%0, %1}";
3114 return "movapd\t{%1, %0|%0, %1}";
3116 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3117 return "movaps\t{%1, %0|%0, %1}";
3119 return "movdqa\t{%1, %0|%0, %1}";
3121 return "movq\t{%1, %0|%0, %1}";
3123 return "movsd\t{%1, %0|%0, %1}";
3125 return "movlpd\t{%1, %0|%0, %1}";
3127 return "movlps\t{%1, %0|%0, %1}";
3136 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3137 (set (attr "prefix_data16")
3138 (if_then_else (eq_attr "mode" "V1DF")
3140 (const_string "*")))
3142 (cond [(eq_attr "alternative" "0,1,2")
3144 (eq_attr "alternative" "3,4")
3147 /* For SSE1, we have many fewer alternatives. */
3148 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3149 (cond [(eq_attr "alternative" "5,6")
3150 (const_string "V4SF")
3152 (const_string "V2SF"))
3154 /* xorps is one byte shorter. */
3155 (eq_attr "alternative" "5")
3156 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3158 (const_string "V4SF")
3159 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3163 (const_string "V2DF"))
3165 /* For architectures resolving dependencies on
3166 whole SSE registers use APD move to break dependency
3167 chains, otherwise use short move to avoid extra work.
3169 movaps encodes one byte shorter. */
3170 (eq_attr "alternative" "6")
3172 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3174 (const_string "V4SF")
3175 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3177 (const_string "V2DF")
3179 (const_string "DF"))
3180 /* For architectures resolving dependencies on register
3181 parts we may avoid extra work to zero out upper part
3183 (eq_attr "alternative" "7")
3185 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3187 (const_string "V1DF")
3188 (const_string "DF"))
3190 (const_string "DF")))])
3192 ;; Moving is usually shorter when only FP registers are used. This separate
3193 ;; movdf pattern avoids the use of integer registers for FP operations
3194 ;; when optimizing for size.
3196 (define_insn "*movdf_internal_nointeger"
3197 [(set (match_operand:DF 0 "nonimmediate_operand"
3198 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3199 (match_operand:DF 1 "general_operand"
3200 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3201 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3202 && ((optimize_function_for_size_p (cfun)
3203 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3204 && (reload_in_progress || reload_completed
3205 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3206 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3207 && optimize_function_for_size_p (cfun)
3208 && !memory_operand (operands[0], DFmode)
3209 && standard_80387_constant_p (operands[1]))
3210 || GET_CODE (operands[1]) != CONST_DOUBLE
3211 || ((optimize_function_for_size_p (cfun)
3212 || !TARGET_MEMORY_MISMATCH_STALL
3213 || reload_in_progress || reload_completed)
3214 && memory_operand (operands[0], DFmode)))"
3216 switch (which_alternative)
3220 return output_387_reg_move (insn, operands);
3223 return standard_80387_constant_opcode (operands[1]);
3230 switch (get_attr_mode (insn))
3233 return "%vxorps\t%0, %d0";
3235 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3236 return "%vxorps\t%0, %d0";
3238 return "%vxorpd\t%0, %d0";
3240 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3241 return "%vxorps\t%0, %d0";
3243 return "%vpxor\t%0, %d0";
3250 switch (get_attr_mode (insn))
3253 return "%vmovaps\t{%1, %0|%0, %1}";
3255 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3256 return "%vmovaps\t{%1, %0|%0, %1}";
3258 return "%vmovapd\t{%1, %0|%0, %1}";
3260 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3261 return "%vmovaps\t{%1, %0|%0, %1}";
3263 return "%vmovdqa\t{%1, %0|%0, %1}";
3265 return "%vmovq\t{%1, %0|%0, %1}";
3269 if (REG_P (operands[0]) && REG_P (operands[1]))
3270 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3272 return "vmovsd\t{%1, %0|%0, %1}";
3275 return "movsd\t{%1, %0|%0, %1}";
3279 if (REG_P (operands[0]))
3280 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3282 return "vmovlpd\t{%1, %0|%0, %1}";
3285 return "movlpd\t{%1, %0|%0, %1}";
3289 if (REG_P (operands[0]))
3290 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3292 return "vmovlps\t{%1, %0|%0, %1}";
3295 return "movlps\t{%1, %0|%0, %1}";
3304 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3305 (set (attr "prefix")
3306 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3307 (const_string "orig")
3308 (const_string "maybe_vex")))
3309 (set (attr "prefix_data16")
3310 (if_then_else (eq_attr "mode" "V1DF")
3312 (const_string "*")))
3314 (cond [(eq_attr "alternative" "0,1,2")
3316 (eq_attr "alternative" "3,4")
3319 /* For SSE1, we have many fewer alternatives. */
3320 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3321 (cond [(eq_attr "alternative" "5,6")
3322 (const_string "V4SF")
3324 (const_string "V2SF"))
3326 /* xorps is one byte shorter. */
3327 (eq_attr "alternative" "5")
3328 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3330 (const_string "V4SF")
3331 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3335 (const_string "V2DF"))
3337 /* For architectures resolving dependencies on
3338 whole SSE registers use APD move to break dependency
3339 chains, otherwise use short move to avoid extra work.
3341 movaps encodes one byte shorter. */
3342 (eq_attr "alternative" "6")
3344 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3346 (const_string "V4SF")
3347 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3349 (const_string "V2DF")
3351 (const_string "DF"))
3352 /* For architectures resolving dependencies on register
3353 parts we may avoid extra work to zero out upper part
3355 (eq_attr "alternative" "7")
3357 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3359 (const_string "V1DF")
3360 (const_string "DF"))
3362 (const_string "DF")))])
3365 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3366 (match_operand:DF 1 "general_operand" ""))]
3368 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3369 && ! (ANY_FP_REG_P (operands[0]) ||
3370 (GET_CODE (operands[0]) == SUBREG
3371 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3372 && ! (ANY_FP_REG_P (operands[1]) ||
3373 (GET_CODE (operands[1]) == SUBREG
3374 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3376 "ix86_split_long_move (operands); DONE;")
3378 (define_insn "*movsf_internal"
3379 [(set (match_operand:SF 0 "nonimmediate_operand"
3380 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3381 (match_operand:SF 1 "general_operand"
3382 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3383 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3384 && (reload_in_progress || reload_completed
3385 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3386 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3387 && standard_80387_constant_p (operands[1]))
3388 || GET_CODE (operands[1]) != CONST_DOUBLE
3389 || memory_operand (operands[0], SFmode))"
3391 switch (which_alternative)
3395 return output_387_reg_move (insn, operands);
3398 return standard_80387_constant_opcode (operands[1]);
3402 return "mov{l}\t{%1, %0|%0, %1}";
3404 if (get_attr_mode (insn) == MODE_TI)
3405 return "%vpxor\t%0, %d0";
3407 return "%vxorps\t%0, %d0";
3409 if (get_attr_mode (insn) == MODE_V4SF)
3410 return "%vmovaps\t{%1, %0|%0, %1}";
3412 return "%vmovss\t{%1, %d0|%d0, %1}";
3415 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3416 : "vmovss\t{%1, %0|%0, %1}";
3418 return "movss\t{%1, %0|%0, %1}";
3420 return "%vmovss\t{%1, %0|%0, %1}";
3422 case 9: case 10: case 14: case 15:
3423 return "movd\t{%1, %0|%0, %1}";
3425 return "%vmovd\t{%1, %0|%0, %1}";
3428 return "movq\t{%1, %0|%0, %1}";
3434 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3435 (set (attr "prefix")
3436 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3437 (const_string "maybe_vex")
3438 (const_string "orig")))
3440 (cond [(eq_attr "alternative" "3,4,9,10")
3442 (eq_attr "alternative" "5")
3444 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3446 (ne (symbol_ref "TARGET_SSE2")
3448 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3451 (const_string "V4SF"))
3452 /* For architectures resolving dependencies on
3453 whole SSE registers use APS move to break dependency
3454 chains, otherwise use short move to avoid extra work.
3456 Do the same for architectures resolving dependencies on
3457 the parts. While in DF mode it is better to always handle
3458 just register parts, the SF mode is different due to lack
3459 of instructions to load just part of the register. It is
3460 better to maintain the whole registers in single format
3461 to avoid problems on using packed logical operations. */
3462 (eq_attr "alternative" "6")
3464 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3466 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3468 (const_string "V4SF")
3469 (const_string "SF"))
3470 (eq_attr "alternative" "11")
3471 (const_string "DI")]
3472 (const_string "SF")))])
3475 [(set (match_operand 0 "register_operand" "")
3476 (match_operand 1 "memory_operand" ""))]
3478 && MEM_P (operands[1])
3479 && (GET_MODE (operands[0]) == TFmode
3480 || GET_MODE (operands[0]) == XFmode
3481 || GET_MODE (operands[0]) == DFmode
3482 || GET_MODE (operands[0]) == SFmode)
3483 && (operands[2] = find_constant_src (insn))"
3484 [(set (match_dup 0) (match_dup 2))]
3486 rtx c = operands[2];
3487 rtx r = operands[0];
3489 if (GET_CODE (r) == SUBREG)
3494 if (!standard_sse_constant_p (c))
3497 else if (FP_REG_P (r))
3499 if (!standard_80387_constant_p (c))
3502 else if (MMX_REG_P (r))
3507 [(set (match_operand 0 "register_operand" "")
3508 (float_extend (match_operand 1 "memory_operand" "")))]
3510 && MEM_P (operands[1])
3511 && (GET_MODE (operands[0]) == TFmode
3512 || GET_MODE (operands[0]) == XFmode
3513 || GET_MODE (operands[0]) == DFmode
3514 || GET_MODE (operands[0]) == SFmode)
3515 && (operands[2] = find_constant_src (insn))"
3516 [(set (match_dup 0) (match_dup 2))]
3518 rtx c = operands[2];
3519 rtx r = operands[0];
3521 if (GET_CODE (r) == SUBREG)
3526 if (!standard_sse_constant_p (c))
3529 else if (FP_REG_P (r))
3531 if (!standard_80387_constant_p (c))
3534 else if (MMX_REG_P (r))
3538 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3540 [(set (match_operand:X87MODEF 0 "register_operand" "")
3541 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3542 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3543 && (standard_80387_constant_p (operands[1]) == 8
3544 || standard_80387_constant_p (operands[1]) == 9)"
3545 [(set (match_dup 0)(match_dup 1))
3547 (neg:X87MODEF (match_dup 0)))]
3551 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3552 if (real_isnegzero (&r))
3553 operands[1] = CONST0_RTX (<MODE>mode);
3555 operands[1] = CONST1_RTX (<MODE>mode);
3558 (define_insn "swapxf"
3559 [(set (match_operand:XF 0 "register_operand" "+f")
3560 (match_operand:XF 1 "register_operand" "+f"))
3565 if (STACK_TOP_P (operands[0]))
3570 [(set_attr "type" "fxch")
3571 (set_attr "mode" "XF")])
3573 (define_insn "*swap<mode>"
3574 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3575 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3578 "TARGET_80387 || reload_completed"
3580 if (STACK_TOP_P (operands[0]))
3585 [(set_attr "type" "fxch")
3586 (set_attr "mode" "<MODE>")])
3588 ;; Zero extension instructions
3590 (define_expand "zero_extendsidi2"
3591 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3592 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3597 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3602 (define_insn "*zero_extendsidi2_rex64"
3603 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3605 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3608 mov\t{%k1, %k0|%k0, %k1}
3610 movd\t{%1, %0|%0, %1}
3611 movd\t{%1, %0|%0, %1}
3612 %vmovd\t{%1, %0|%0, %1}
3613 %vmovd\t{%1, %0|%0, %1}"
3614 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3615 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3616 (set_attr "prefix_0f" "0,*,*,*,*,*")
3617 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3620 [(set (match_operand:DI 0 "memory_operand" "")
3621 (zero_extend:DI (match_dup 0)))]
3623 [(set (match_dup 4) (const_int 0))]
3624 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3626 ;; %%% Kill me once multi-word ops are sane.
3627 (define_insn "zero_extendsidi2_1"
3628 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3630 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3631 (clobber (reg:CC FLAGS_REG))]
3637 movd\t{%1, %0|%0, %1}
3638 movd\t{%1, %0|%0, %1}
3639 %vmovd\t{%1, %0|%0, %1}
3640 %vmovd\t{%1, %0|%0, %1}"
3641 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3642 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3643 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3646 [(set (match_operand:DI 0 "register_operand" "")
3647 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3648 (clobber (reg:CC FLAGS_REG))]
3649 "!TARGET_64BIT && reload_completed
3650 && true_regnum (operands[0]) == true_regnum (operands[1])"
3651 [(set (match_dup 4) (const_int 0))]
3652 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3655 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3656 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3657 (clobber (reg:CC FLAGS_REG))]
3658 "!TARGET_64BIT && reload_completed
3659 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3660 [(set (match_dup 3) (match_dup 1))
3661 (set (match_dup 4) (const_int 0))]
3662 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3664 (define_insn "zero_extend<mode>di2"
3665 [(set (match_operand:DI 0 "register_operand" "=r")
3667 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3669 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3670 [(set_attr "type" "imovx")
3671 (set_attr "mode" "SI")])
3673 (define_expand "zero_extendhisi2"
3674 [(set (match_operand:SI 0 "register_operand" "")
3675 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3678 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3680 operands[1] = force_reg (HImode, operands[1]);
3681 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3686 (define_insn_and_split "zero_extendhisi2_and"
3687 [(set (match_operand:SI 0 "register_operand" "=r")
3688 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3689 (clobber (reg:CC FLAGS_REG))]
3690 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3692 "&& reload_completed"
3693 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3694 (clobber (reg:CC FLAGS_REG))])]
3696 [(set_attr "type" "alu1")
3697 (set_attr "mode" "SI")])
3699 (define_insn "*zero_extendhisi2_movzwl"
3700 [(set (match_operand:SI 0 "register_operand" "=r")
3701 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3702 "!TARGET_ZERO_EXTEND_WITH_AND
3703 || optimize_function_for_size_p (cfun)"
3704 "movz{wl|x}\t{%1, %0|%0, %1}"
3705 [(set_attr "type" "imovx")
3706 (set_attr "mode" "SI")])
3708 (define_expand "zero_extendqi<mode>2"
3710 [(set (match_operand:SWI24 0 "register_operand" "")
3711 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3712 (clobber (reg:CC FLAGS_REG))])])
3714 (define_insn "*zero_extendqi<mode>2_and"
3715 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3716 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3717 (clobber (reg:CC FLAGS_REG))]
3718 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3720 [(set_attr "type" "alu1")
3721 (set_attr "mode" "<MODE>")])
3723 ;; When source and destination does not overlap, clear destination
3724 ;; first and then do the movb
3726 [(set (match_operand:SWI24 0 "register_operand" "")
3727 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3728 (clobber (reg:CC FLAGS_REG))]
3730 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3731 && ANY_QI_REG_P (operands[0])
3732 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3733 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3734 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3736 operands[2] = gen_lowpart (QImode, operands[0]);
3737 ix86_expand_clear (operands[0]);
3740 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3741 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3742 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3743 (clobber (reg:CC FLAGS_REG))]
3744 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3746 [(set_attr "type" "imovx,alu1")
3747 (set_attr "mode" "<MODE>")])
3749 ;; For the movzbl case strip only the clobber
3751 [(set (match_operand:SWI24 0 "register_operand" "")
3752 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3753 (clobber (reg:CC FLAGS_REG))]
3755 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3756 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3758 (zero_extend:SWI24 (match_dup 1)))])
3760 ; zero extend to SImode to avoid partial register stalls
3761 (define_insn "*zero_extendqi<mode>2_movzbl"
3762 [(set (match_operand:SWI24 0 "register_operand" "=r")
3763 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3765 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3766 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3767 [(set_attr "type" "imovx")
3768 (set_attr "mode" "SI")])
3770 ;; Rest is handled by single and.
3772 [(set (match_operand:SWI24 0 "register_operand" "")
3773 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3774 (clobber (reg:CC FLAGS_REG))]
3776 && true_regnum (operands[0]) == true_regnum (operands[1])"
3777 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3778 (clobber (reg:CC FLAGS_REG))])])
3780 ;; Sign extension instructions
3782 (define_expand "extendsidi2"
3783 [(set (match_operand:DI 0 "register_operand" "")
3784 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3789 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3794 (define_insn "*extendsidi2_rex64"
3795 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3796 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3800 movs{lq|x}\t{%1, %0|%0, %1}"
3801 [(set_attr "type" "imovx")
3802 (set_attr "mode" "DI")
3803 (set_attr "prefix_0f" "0")
3804 (set_attr "modrm" "0,1")])
3806 (define_insn "extendsidi2_1"
3807 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3808 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3809 (clobber (reg:CC FLAGS_REG))
3810 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3814 ;; Extend to memory case when source register does die.
3816 [(set (match_operand:DI 0 "memory_operand" "")
3817 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3818 (clobber (reg:CC FLAGS_REG))
3819 (clobber (match_operand:SI 2 "register_operand" ""))]
3821 && dead_or_set_p (insn, operands[1])
3822 && !reg_mentioned_p (operands[1], operands[0]))"
3823 [(set (match_dup 3) (match_dup 1))
3824 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3825 (clobber (reg:CC FLAGS_REG))])
3826 (set (match_dup 4) (match_dup 1))]
3827 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3829 ;; Extend to memory case when source register does not die.
3831 [(set (match_operand:DI 0 "memory_operand" "")
3832 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3833 (clobber (reg:CC FLAGS_REG))
3834 (clobber (match_operand:SI 2 "register_operand" ""))]
3838 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3840 emit_move_insn (operands[3], operands[1]);
3842 /* Generate a cltd if possible and doing so it profitable. */
3843 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3844 && true_regnum (operands[1]) == AX_REG
3845 && true_regnum (operands[2]) == DX_REG)
3847 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3851 emit_move_insn (operands[2], operands[1]);
3852 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3854 emit_move_insn (operands[4], operands[2]);
3858 ;; Extend to register case. Optimize case where source and destination
3859 ;; registers match and cases where we can use cltd.
3861 [(set (match_operand:DI 0 "register_operand" "")
3862 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3863 (clobber (reg:CC FLAGS_REG))
3864 (clobber (match_scratch:SI 2 ""))]
3868 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3870 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3871 emit_move_insn (operands[3], operands[1]);
3873 /* Generate a cltd if possible and doing so it profitable. */
3874 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3875 && true_regnum (operands[3]) == AX_REG
3876 && true_regnum (operands[4]) == DX_REG)
3878 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3882 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3883 emit_move_insn (operands[4], operands[1]);
3885 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3889 (define_insn "extend<mode>di2"
3890 [(set (match_operand:DI 0 "register_operand" "=r")
3892 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3894 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3895 [(set_attr "type" "imovx")
3896 (set_attr "mode" "DI")])
3898 (define_insn "extendhisi2"
3899 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3900 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3903 switch (get_attr_prefix_0f (insn))
3906 return "{cwtl|cwde}";
3908 return "movs{wl|x}\t{%1, %0|%0, %1}";
3911 [(set_attr "type" "imovx")
3912 (set_attr "mode" "SI")
3913 (set (attr "prefix_0f")
3914 ;; movsx is short decodable while cwtl is vector decoded.
3915 (if_then_else (and (eq_attr "cpu" "!k6")
3916 (eq_attr "alternative" "0"))
3918 (const_string "1")))
3920 (if_then_else (eq_attr "prefix_0f" "0")
3922 (const_string "1")))])
3924 (define_insn "*extendhisi2_zext"
3925 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3928 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3931 switch (get_attr_prefix_0f (insn))
3934 return "{cwtl|cwde}";
3936 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3939 [(set_attr "type" "imovx")
3940 (set_attr "mode" "SI")
3941 (set (attr "prefix_0f")
3942 ;; movsx is short decodable while cwtl is vector decoded.
3943 (if_then_else (and (eq_attr "cpu" "!k6")
3944 (eq_attr "alternative" "0"))
3946 (const_string "1")))
3948 (if_then_else (eq_attr "prefix_0f" "0")
3950 (const_string "1")))])
3952 (define_insn "extendqisi2"
3953 [(set (match_operand:SI 0 "register_operand" "=r")
3954 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3956 "movs{bl|x}\t{%1, %0|%0, %1}"
3957 [(set_attr "type" "imovx")
3958 (set_attr "mode" "SI")])
3960 (define_insn "*extendqisi2_zext"
3961 [(set (match_operand:DI 0 "register_operand" "=r")
3963 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3965 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3966 [(set_attr "type" "imovx")
3967 (set_attr "mode" "SI")])
3969 (define_insn "extendqihi2"
3970 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3971 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3974 switch (get_attr_prefix_0f (insn))
3977 return "{cbtw|cbw}";
3979 return "movs{bw|x}\t{%1, %0|%0, %1}";
3982 [(set_attr "type" "imovx")
3983 (set_attr "mode" "HI")
3984 (set (attr "prefix_0f")
3985 ;; movsx is short decodable while cwtl is vector decoded.
3986 (if_then_else (and (eq_attr "cpu" "!k6")
3987 (eq_attr "alternative" "0"))
3989 (const_string "1")))
3991 (if_then_else (eq_attr "prefix_0f" "0")
3993 (const_string "1")))])
3995 ;; Conversions between float and double.
3997 ;; These are all no-ops in the model used for the 80387.
3998 ;; So just emit moves.
4000 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4002 [(set (match_operand:DF 0 "push_operand" "")
4003 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4005 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4006 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4009 [(set (match_operand:XF 0 "push_operand" "")
4010 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4012 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4013 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4014 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4016 (define_expand "extendsfdf2"
4017 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4018 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4019 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4021 /* ??? Needed for compress_float_constant since all fp constants
4022 are LEGITIMATE_CONSTANT_P. */
4023 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4025 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4026 && standard_80387_constant_p (operands[1]) > 0)
4028 operands[1] = simplify_const_unary_operation
4029 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4030 emit_move_insn_1 (operands[0], operands[1]);
4033 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4037 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4039 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4041 We do the conversion post reload to avoid producing of 128bit spills
4042 that might lead to ICE on 32bit target. The sequence unlikely combine
4045 [(set (match_operand:DF 0 "register_operand" "")
4047 (match_operand:SF 1 "nonimmediate_operand" "")))]
4048 "TARGET_USE_VECTOR_FP_CONVERTS
4049 && optimize_insn_for_speed_p ()
4050 && reload_completed && SSE_REG_P (operands[0])"
4055 (parallel [(const_int 0) (const_int 1)]))))]
4057 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4058 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4059 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4060 Try to avoid move when unpacking can be done in source. */
4061 if (REG_P (operands[1]))
4063 /* If it is unsafe to overwrite upper half of source, we need
4064 to move to destination and unpack there. */
4065 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4066 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4067 && true_regnum (operands[0]) != true_regnum (operands[1]))
4069 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4070 emit_move_insn (tmp, operands[1]);
4073 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4074 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4078 emit_insn (gen_vec_setv4sf_0 (operands[3],
4079 CONST0_RTX (V4SFmode), operands[1]));
4082 (define_insn "*extendsfdf2_mixed"
4083 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4085 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4086 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4088 switch (which_alternative)
4092 return output_387_reg_move (insn, operands);
4095 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4101 [(set_attr "type" "fmov,fmov,ssecvt")
4102 (set_attr "prefix" "orig,orig,maybe_vex")
4103 (set_attr "mode" "SF,XF,DF")])
4105 (define_insn "*extendsfdf2_sse"
4106 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4107 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4108 "TARGET_SSE2 && TARGET_SSE_MATH"
4109 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4110 [(set_attr "type" "ssecvt")
4111 (set_attr "prefix" "maybe_vex")
4112 (set_attr "mode" "DF")])
4114 (define_insn "*extendsfdf2_i387"
4115 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4116 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4118 "* return output_387_reg_move (insn, operands);"
4119 [(set_attr "type" "fmov")
4120 (set_attr "mode" "SF,XF")])
4122 (define_expand "extend<mode>xf2"
4123 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4124 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4127 /* ??? Needed for compress_float_constant since all fp constants
4128 are LEGITIMATE_CONSTANT_P. */
4129 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4131 if (standard_80387_constant_p (operands[1]) > 0)
4133 operands[1] = simplify_const_unary_operation
4134 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4135 emit_move_insn_1 (operands[0], operands[1]);
4138 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4142 (define_insn "*extend<mode>xf2_i387"
4143 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4145 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4147 "* return output_387_reg_move (insn, operands);"
4148 [(set_attr "type" "fmov")
4149 (set_attr "mode" "<MODE>,XF")])
4151 ;; %%% This seems bad bad news.
4152 ;; This cannot output into an f-reg because there is no way to be sure
4153 ;; of truncating in that case. Otherwise this is just like a simple move
4154 ;; insn. So we pretend we can output to a reg in order to get better
4155 ;; register preferencing, but we really use a stack slot.
4157 ;; Conversion from DFmode to SFmode.
4159 (define_expand "truncdfsf2"
4160 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4162 (match_operand:DF 1 "nonimmediate_operand" "")))]
4163 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4165 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4167 else if (flag_unsafe_math_optimizations)
4171 enum ix86_stack_slot slot = (virtuals_instantiated
4174 rtx temp = assign_386_stack_local (SFmode, slot);
4175 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4180 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4182 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4184 We do the conversion post reload to avoid producing of 128bit spills
4185 that might lead to ICE on 32bit target. The sequence unlikely combine
4188 [(set (match_operand:SF 0 "register_operand" "")
4190 (match_operand:DF 1 "nonimmediate_operand" "")))]
4191 "TARGET_USE_VECTOR_FP_CONVERTS
4192 && optimize_insn_for_speed_p ()
4193 && reload_completed && SSE_REG_P (operands[0])"
4196 (float_truncate:V2SF
4200 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4201 operands[3] = CONST0_RTX (V2SFmode);
4202 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4203 /* Use movsd for loading from memory, unpcklpd for registers.
4204 Try to avoid move when unpacking can be done in source, or SSE3
4205 movddup is available. */
4206 if (REG_P (operands[1]))
4209 && true_regnum (operands[0]) != true_regnum (operands[1])
4210 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4211 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4213 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4214 emit_move_insn (tmp, operands[1]);
4217 else if (!TARGET_SSE3)
4218 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4219 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4222 emit_insn (gen_sse2_loadlpd (operands[4],
4223 CONST0_RTX (V2DFmode), operands[1]));
4226 (define_expand "truncdfsf2_with_temp"
4227 [(parallel [(set (match_operand:SF 0 "" "")
4228 (float_truncate:SF (match_operand:DF 1 "" "")))
4229 (clobber (match_operand:SF 2 "" ""))])])
4231 (define_insn "*truncdfsf_fast_mixed"
4232 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4234 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4235 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4237 switch (which_alternative)
4240 return output_387_reg_move (insn, operands);
4242 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4247 [(set_attr "type" "fmov,ssecvt")
4248 (set_attr "prefix" "orig,maybe_vex")
4249 (set_attr "mode" "SF")])
4251 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4252 ;; because nothing we do here is unsafe.
4253 (define_insn "*truncdfsf_fast_sse"
4254 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4256 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4257 "TARGET_SSE2 && TARGET_SSE_MATH"
4258 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4259 [(set_attr "type" "ssecvt")
4260 (set_attr "prefix" "maybe_vex")
4261 (set_attr "mode" "SF")])
4263 (define_insn "*truncdfsf_fast_i387"
4264 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4266 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4267 "TARGET_80387 && flag_unsafe_math_optimizations"
4268 "* return output_387_reg_move (insn, operands);"
4269 [(set_attr "type" "fmov")
4270 (set_attr "mode" "SF")])
4272 (define_insn "*truncdfsf_mixed"
4273 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4275 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4276 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4277 "TARGET_MIX_SSE_I387"
4279 switch (which_alternative)
4282 return output_387_reg_move (insn, operands);
4284 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4290 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4291 (set_attr "unit" "*,*,i387,i387,i387")
4292 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4293 (set_attr "mode" "SF")])
4295 (define_insn "*truncdfsf_i387"
4296 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4298 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4299 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4302 switch (which_alternative)
4305 return output_387_reg_move (insn, operands);
4311 [(set_attr "type" "fmov,multi,multi,multi")
4312 (set_attr "unit" "*,i387,i387,i387")
4313 (set_attr "mode" "SF")])
4315 (define_insn "*truncdfsf2_i387_1"
4316 [(set (match_operand:SF 0 "memory_operand" "=m")
4318 (match_operand:DF 1 "register_operand" "f")))]
4320 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4321 && !TARGET_MIX_SSE_I387"
4322 "* return output_387_reg_move (insn, operands);"
4323 [(set_attr "type" "fmov")
4324 (set_attr "mode" "SF")])
4327 [(set (match_operand:SF 0 "register_operand" "")
4329 (match_operand:DF 1 "fp_register_operand" "")))
4330 (clobber (match_operand 2 "" ""))]
4332 [(set (match_dup 2) (match_dup 1))
4333 (set (match_dup 0) (match_dup 2))]
4334 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4336 ;; Conversion from XFmode to {SF,DF}mode
4338 (define_expand "truncxf<mode>2"
4339 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4340 (float_truncate:MODEF
4341 (match_operand:XF 1 "register_operand" "")))
4342 (clobber (match_dup 2))])]
4345 if (flag_unsafe_math_optimizations)
4347 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4348 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4349 if (reg != operands[0])
4350 emit_move_insn (operands[0], reg);
4355 enum ix86_stack_slot slot = (virtuals_instantiated
4358 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4362 (define_insn "*truncxfsf2_mixed"
4363 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4365 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4366 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4369 gcc_assert (!which_alternative);
4370 return output_387_reg_move (insn, operands);
4372 [(set_attr "type" "fmov,multi,multi,multi")
4373 (set_attr "unit" "*,i387,i387,i387")
4374 (set_attr "mode" "SF")])
4376 (define_insn "*truncxfdf2_mixed"
4377 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4379 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4380 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4383 gcc_assert (!which_alternative);
4384 return output_387_reg_move (insn, operands);
4386 [(set_attr "type" "fmov,multi,multi,multi")
4387 (set_attr "unit" "*,i387,i387,i387")
4388 (set_attr "mode" "DF")])
4390 (define_insn "truncxf<mode>2_i387_noop"
4391 [(set (match_operand:MODEF 0 "register_operand" "=f")
4392 (float_truncate:MODEF
4393 (match_operand:XF 1 "register_operand" "f")))]
4394 "TARGET_80387 && flag_unsafe_math_optimizations"
4395 "* return output_387_reg_move (insn, operands);"
4396 [(set_attr "type" "fmov")
4397 (set_attr "mode" "<MODE>")])
4399 (define_insn "*truncxf<mode>2_i387"
4400 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4401 (float_truncate:MODEF
4402 (match_operand:XF 1 "register_operand" "f")))]
4404 "* return output_387_reg_move (insn, operands);"
4405 [(set_attr "type" "fmov")
4406 (set_attr "mode" "<MODE>")])
4409 [(set (match_operand:MODEF 0 "register_operand" "")
4410 (float_truncate:MODEF
4411 (match_operand:XF 1 "register_operand" "")))
4412 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4413 "TARGET_80387 && reload_completed"
4414 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4415 (set (match_dup 0) (match_dup 2))])
4418 [(set (match_operand:MODEF 0 "memory_operand" "")
4419 (float_truncate:MODEF
4420 (match_operand:XF 1 "register_operand" "")))
4421 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4423 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4425 ;; Signed conversion to DImode.
4427 (define_expand "fix_truncxfdi2"
4428 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4429 (fix:DI (match_operand:XF 1 "register_operand" "")))
4430 (clobber (reg:CC FLAGS_REG))])]
4435 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4440 (define_expand "fix_trunc<mode>di2"
4441 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4442 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4443 (clobber (reg:CC FLAGS_REG))])]
4444 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4447 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4449 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4452 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4454 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4455 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4456 if (out != operands[0])
4457 emit_move_insn (operands[0], out);
4462 ;; Signed conversion to SImode.
4464 (define_expand "fix_truncxfsi2"
4465 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4466 (fix:SI (match_operand:XF 1 "register_operand" "")))
4467 (clobber (reg:CC FLAGS_REG))])]
4472 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4477 (define_expand "fix_trunc<mode>si2"
4478 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4479 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4480 (clobber (reg:CC FLAGS_REG))])]
4481 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4484 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4486 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4489 if (SSE_FLOAT_MODE_P (<MODE>mode))
4491 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4492 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4493 if (out != operands[0])
4494 emit_move_insn (operands[0], out);
4499 ;; Signed conversion to HImode.
4501 (define_expand "fix_trunc<mode>hi2"
4502 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4503 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4504 (clobber (reg:CC FLAGS_REG))])]
4506 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4510 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4515 ;; Unsigned conversion to SImode.
4517 (define_expand "fixuns_trunc<mode>si2"
4519 [(set (match_operand:SI 0 "register_operand" "")
4521 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4523 (clobber (match_scratch:<ssevecmode> 3 ""))
4524 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4525 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4527 enum machine_mode mode = <MODE>mode;
4528 enum machine_mode vecmode = <ssevecmode>mode;
4529 REAL_VALUE_TYPE TWO31r;
4532 if (optimize_insn_for_size_p ())
4535 real_ldexp (&TWO31r, &dconst1, 31);
4536 two31 = const_double_from_real_value (TWO31r, mode);
4537 two31 = ix86_build_const_vector (vecmode, true, two31);
4538 operands[2] = force_reg (vecmode, two31);
4541 (define_insn_and_split "*fixuns_trunc<mode>_1"
4542 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4544 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4545 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4546 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4547 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4548 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4549 && optimize_function_for_speed_p (cfun)"
4551 "&& reload_completed"
4554 ix86_split_convert_uns_si_sse (operands);
4558 ;; Unsigned conversion to HImode.
4559 ;; Without these patterns, we'll try the unsigned SI conversion which
4560 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4562 (define_expand "fixuns_trunc<mode>hi2"
4564 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4565 (set (match_operand:HI 0 "nonimmediate_operand" "")
4566 (subreg:HI (match_dup 2) 0))]
4567 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4568 "operands[2] = gen_reg_rtx (SImode);")
4570 ;; When SSE is available, it is always faster to use it!
4571 (define_insn "fix_trunc<mode>di_sse"
4572 [(set (match_operand:DI 0 "register_operand" "=r,r")
4573 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4574 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4575 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4576 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4577 [(set_attr "type" "sseicvt")
4578 (set_attr "prefix" "maybe_vex")
4579 (set_attr "prefix_rex" "1")
4580 (set_attr "mode" "<MODE>")
4581 (set_attr "athlon_decode" "double,vector")
4582 (set_attr "amdfam10_decode" "double,double")
4583 (set_attr "bdver1_decode" "double,double")])
4585 (define_insn "fix_trunc<mode>si_sse"
4586 [(set (match_operand:SI 0 "register_operand" "=r,r")
4587 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4588 "SSE_FLOAT_MODE_P (<MODE>mode)
4589 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4590 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4591 [(set_attr "type" "sseicvt")
4592 (set_attr "prefix" "maybe_vex")
4593 (set_attr "mode" "<MODE>")
4594 (set_attr "athlon_decode" "double,vector")
4595 (set_attr "amdfam10_decode" "double,double")
4596 (set_attr "bdver1_decode" "double,double")])
4598 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4600 [(set (match_operand:MODEF 0 "register_operand" "")
4601 (match_operand:MODEF 1 "memory_operand" ""))
4602 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4603 (fix:SSEMODEI24 (match_dup 0)))]
4604 "TARGET_SHORTEN_X87_SSE
4605 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4606 && peep2_reg_dead_p (2, operands[0])"
4607 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4609 ;; Avoid vector decoded forms of the instruction.
4611 [(match_scratch:DF 2 "Y2")
4612 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4613 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4614 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4615 [(set (match_dup 2) (match_dup 1))
4616 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4619 [(match_scratch:SF 2 "x")
4620 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4621 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4622 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4623 [(set (match_dup 2) (match_dup 1))
4624 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4626 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4627 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4628 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4629 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4631 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4632 && (TARGET_64BIT || <MODE>mode != DImode))
4634 && can_create_pseudo_p ()"
4639 if (memory_operand (operands[0], VOIDmode))
4640 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4643 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4644 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4650 [(set_attr "type" "fisttp")
4651 (set_attr "mode" "<MODE>")])
4653 (define_insn "fix_trunc<mode>_i387_fisttp"
4654 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4655 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4656 (clobber (match_scratch:XF 2 "=&1f"))]
4657 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4659 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4660 && (TARGET_64BIT || <MODE>mode != DImode))
4661 && TARGET_SSE_MATH)"
4662 "* return output_fix_trunc (insn, operands, 1);"
4663 [(set_attr "type" "fisttp")
4664 (set_attr "mode" "<MODE>")])
4666 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4667 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4668 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4669 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4670 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4671 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4673 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4674 && (TARGET_64BIT || <MODE>mode != DImode))
4675 && TARGET_SSE_MATH)"
4677 [(set_attr "type" "fisttp")
4678 (set_attr "mode" "<MODE>")])
4681 [(set (match_operand:X87MODEI 0 "register_operand" "")
4682 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4683 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4684 (clobber (match_scratch 3 ""))]
4686 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4687 (clobber (match_dup 3))])
4688 (set (match_dup 0) (match_dup 2))])
4691 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4692 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4693 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4694 (clobber (match_scratch 3 ""))]
4696 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4697 (clobber (match_dup 3))])])
4699 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4700 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4701 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4702 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4703 ;; function in i386.c.
4704 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4705 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4706 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4707 (clobber (reg:CC FLAGS_REG))]
4708 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4710 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4711 && (TARGET_64BIT || <MODE>mode != DImode))
4712 && can_create_pseudo_p ()"
4717 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4719 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4720 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4721 if (memory_operand (operands[0], VOIDmode))
4722 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4723 operands[2], operands[3]));
4726 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4727 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4728 operands[2], operands[3],
4733 [(set_attr "type" "fistp")
4734 (set_attr "i387_cw" "trunc")
4735 (set_attr "mode" "<MODE>")])
4737 (define_insn "fix_truncdi_i387"
4738 [(set (match_operand:DI 0 "memory_operand" "=m")
4739 (fix:DI (match_operand 1 "register_operand" "f")))
4740 (use (match_operand:HI 2 "memory_operand" "m"))
4741 (use (match_operand:HI 3 "memory_operand" "m"))
4742 (clobber (match_scratch:XF 4 "=&1f"))]
4743 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4745 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4746 "* return output_fix_trunc (insn, operands, 0);"
4747 [(set_attr "type" "fistp")
4748 (set_attr "i387_cw" "trunc")
4749 (set_attr "mode" "DI")])
4751 (define_insn "fix_truncdi_i387_with_temp"
4752 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4753 (fix:DI (match_operand 1 "register_operand" "f,f")))
4754 (use (match_operand:HI 2 "memory_operand" "m,m"))
4755 (use (match_operand:HI 3 "memory_operand" "m,m"))
4756 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4757 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4758 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4760 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4762 [(set_attr "type" "fistp")
4763 (set_attr "i387_cw" "trunc")
4764 (set_attr "mode" "DI")])
4767 [(set (match_operand:DI 0 "register_operand" "")
4768 (fix:DI (match_operand 1 "register_operand" "")))
4769 (use (match_operand:HI 2 "memory_operand" ""))
4770 (use (match_operand:HI 3 "memory_operand" ""))
4771 (clobber (match_operand:DI 4 "memory_operand" ""))
4772 (clobber (match_scratch 5 ""))]
4774 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4777 (clobber (match_dup 5))])
4778 (set (match_dup 0) (match_dup 4))])
4781 [(set (match_operand:DI 0 "memory_operand" "")
4782 (fix:DI (match_operand 1 "register_operand" "")))
4783 (use (match_operand:HI 2 "memory_operand" ""))
4784 (use (match_operand:HI 3 "memory_operand" ""))
4785 (clobber (match_operand:DI 4 "memory_operand" ""))
4786 (clobber (match_scratch 5 ""))]
4788 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4791 (clobber (match_dup 5))])])
4793 (define_insn "fix_trunc<mode>_i387"
4794 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4795 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4796 (use (match_operand:HI 2 "memory_operand" "m"))
4797 (use (match_operand:HI 3 "memory_operand" "m"))]
4798 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4800 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4801 "* return output_fix_trunc (insn, operands, 0);"
4802 [(set_attr "type" "fistp")
4803 (set_attr "i387_cw" "trunc")
4804 (set_attr "mode" "<MODE>")])
4806 (define_insn "fix_trunc<mode>_i387_with_temp"
4807 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4808 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4809 (use (match_operand:HI 2 "memory_operand" "m,m"))
4810 (use (match_operand:HI 3 "memory_operand" "m,m"))
4811 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4812 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4814 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4816 [(set_attr "type" "fistp")
4817 (set_attr "i387_cw" "trunc")
4818 (set_attr "mode" "<MODE>")])
4821 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4822 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4823 (use (match_operand:HI 2 "memory_operand" ""))
4824 (use (match_operand:HI 3 "memory_operand" ""))
4825 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4827 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4829 (use (match_dup 3))])
4830 (set (match_dup 0) (match_dup 4))])
4833 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4834 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4835 (use (match_operand:HI 2 "memory_operand" ""))
4836 (use (match_operand:HI 3 "memory_operand" ""))
4837 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4839 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4841 (use (match_dup 3))])])
4843 (define_insn "x86_fnstcw_1"
4844 [(set (match_operand:HI 0 "memory_operand" "=m")
4845 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4848 [(set (attr "length")
4849 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4850 (set_attr "mode" "HI")
4851 (set_attr "unit" "i387")
4852 (set_attr "bdver1_decode" "vector")])
4854 (define_insn "x86_fldcw_1"
4855 [(set (reg:HI FPCR_REG)
4856 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4859 [(set (attr "length")
4860 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4861 (set_attr "mode" "HI")
4862 (set_attr "unit" "i387")
4863 (set_attr "athlon_decode" "vector")
4864 (set_attr "amdfam10_decode" "vector")
4865 (set_attr "bdver1_decode" "vector")])
4867 ;; Conversion between fixed point and floating point.
4869 ;; Even though we only accept memory inputs, the backend _really_
4870 ;; wants to be able to do this between registers.
4872 (define_expand "floathi<mode>2"
4873 [(set (match_operand:X87MODEF 0 "register_operand" "")
4874 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4877 || TARGET_MIX_SSE_I387)")
4879 ;; Pre-reload splitter to add memory clobber to the pattern.
4880 (define_insn_and_split "*floathi<mode>2_1"
4881 [(set (match_operand:X87MODEF 0 "register_operand" "")
4882 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4884 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4885 || TARGET_MIX_SSE_I387)
4886 && can_create_pseudo_p ()"
4889 [(parallel [(set (match_dup 0)
4890 (float:X87MODEF (match_dup 1)))
4891 (clobber (match_dup 2))])]
4892 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4894 (define_insn "*floathi<mode>2_i387_with_temp"
4895 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4896 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4897 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4900 || TARGET_MIX_SSE_I387)"
4902 [(set_attr "type" "fmov,multi")
4903 (set_attr "mode" "<MODE>")
4904 (set_attr "unit" "*,i387")
4905 (set_attr "fp_int_src" "true")])
4907 (define_insn "*floathi<mode>2_i387"
4908 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4909 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4911 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4912 || TARGET_MIX_SSE_I387)"
4914 [(set_attr "type" "fmov")
4915 (set_attr "mode" "<MODE>")
4916 (set_attr "fp_int_src" "true")])
4919 [(set (match_operand:X87MODEF 0 "register_operand" "")
4920 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4921 (clobber (match_operand:HI 2 "memory_operand" ""))]
4923 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4924 || TARGET_MIX_SSE_I387)
4925 && reload_completed"
4926 [(set (match_dup 2) (match_dup 1))
4927 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4930 [(set (match_operand:X87MODEF 0 "register_operand" "")
4931 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4932 (clobber (match_operand:HI 2 "memory_operand" ""))]
4934 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4935 || TARGET_MIX_SSE_I387)
4936 && reload_completed"
4937 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4939 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4940 [(set (match_operand:X87MODEF 0 "register_operand" "")
4942 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4944 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4945 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4947 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4948 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4949 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4951 rtx reg = gen_reg_rtx (XFmode);
4954 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4956 if (<X87MODEF:MODE>mode == SFmode)
4957 insn = gen_truncxfsf2 (operands[0], reg);
4958 else if (<X87MODEF:MODE>mode == DFmode)
4959 insn = gen_truncxfdf2 (operands[0], reg);
4968 ;; Pre-reload splitter to add memory clobber to the pattern.
4969 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4970 [(set (match_operand:X87MODEF 0 "register_operand" "")
4971 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4973 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4974 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4975 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4976 || TARGET_MIX_SSE_I387))
4977 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4978 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4979 && ((<SSEMODEI24:MODE>mode == SImode
4980 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4981 && optimize_function_for_speed_p (cfun)
4982 && flag_trapping_math)
4983 || !(TARGET_INTER_UNIT_CONVERSIONS
4984 || optimize_function_for_size_p (cfun)))))
4985 && can_create_pseudo_p ()"
4988 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4989 (clobber (match_dup 2))])]
4991 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4993 /* Avoid store forwarding (partial memory) stall penalty
4994 by passing DImode value through XMM registers. */
4995 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4996 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4997 && optimize_function_for_speed_p (cfun))
4999 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5006 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5007 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5009 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5010 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5011 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5012 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5014 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5015 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5016 (set_attr "unit" "*,i387,*,*,*")
5017 (set_attr "athlon_decode" "*,*,double,direct,double")
5018 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5019 (set_attr "bdver1_decode" "*,*,double,direct,double")
5020 (set_attr "fp_int_src" "true")])
5022 (define_insn "*floatsi<mode>2_vector_mixed"
5023 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5024 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5025 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5026 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5030 [(set_attr "type" "fmov,sseicvt")
5031 (set_attr "mode" "<MODE>,<ssevecmode>")
5032 (set_attr "unit" "i387,*")
5033 (set_attr "athlon_decode" "*,direct")
5034 (set_attr "amdfam10_decode" "*,double")
5035 (set_attr "bdver1_decode" "*,direct")
5036 (set_attr "fp_int_src" "true")])
5038 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5039 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5041 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5042 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5043 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5044 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5046 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5047 (set_attr "mode" "<MODEF:MODE>")
5048 (set_attr "unit" "*,i387,*,*")
5049 (set_attr "athlon_decode" "*,*,double,direct")
5050 (set_attr "amdfam10_decode" "*,*,vector,double")
5051 (set_attr "bdver1_decode" "*,*,double,direct")
5052 (set_attr "fp_int_src" "true")])
5055 [(set (match_operand:MODEF 0 "register_operand" "")
5056 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5057 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5058 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5059 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5060 && TARGET_INTER_UNIT_CONVERSIONS
5062 && (SSE_REG_P (operands[0])
5063 || (GET_CODE (operands[0]) == SUBREG
5064 && SSE_REG_P (operands[0])))"
5065 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5068 [(set (match_operand:MODEF 0 "register_operand" "")
5069 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5070 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5071 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5072 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5073 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5075 && (SSE_REG_P (operands[0])
5076 || (GET_CODE (operands[0]) == SUBREG
5077 && SSE_REG_P (operands[0])))"
5078 [(set (match_dup 2) (match_dup 1))
5079 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5081 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5082 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5084 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5085 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5086 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5087 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5090 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5091 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5092 [(set_attr "type" "fmov,sseicvt,sseicvt")
5093 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5094 (set_attr "mode" "<MODEF:MODE>")
5095 (set (attr "prefix_rex")
5097 (and (eq_attr "prefix" "maybe_vex")
5098 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5100 (const_string "*")))
5101 (set_attr "unit" "i387,*,*")
5102 (set_attr "athlon_decode" "*,double,direct")
5103 (set_attr "amdfam10_decode" "*,vector,double")
5104 (set_attr "bdver1_decode" "*,double,direct")
5105 (set_attr "fp_int_src" "true")])
5107 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5108 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5110 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5111 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5112 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5113 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5116 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5117 [(set_attr "type" "fmov,sseicvt")
5118 (set_attr "prefix" "orig,maybe_vex")
5119 (set_attr "mode" "<MODEF:MODE>")
5120 (set (attr "prefix_rex")
5122 (and (eq_attr "prefix" "maybe_vex")
5123 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5125 (const_string "*")))
5126 (set_attr "athlon_decode" "*,direct")
5127 (set_attr "amdfam10_decode" "*,double")
5128 (set_attr "bdver1_decode" "*,direct")
5129 (set_attr "fp_int_src" "true")])
5131 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5132 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5134 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5135 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5136 "TARGET_SSE2 && TARGET_SSE_MATH
5137 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5139 [(set_attr "type" "sseicvt")
5140 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5141 (set_attr "athlon_decode" "double,direct,double")
5142 (set_attr "amdfam10_decode" "vector,double,double")
5143 (set_attr "bdver1_decode" "double,direct,double")
5144 (set_attr "fp_int_src" "true")])
5146 (define_insn "*floatsi<mode>2_vector_sse"
5147 [(set (match_operand:MODEF 0 "register_operand" "=x")
5148 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5149 "TARGET_SSE2 && TARGET_SSE_MATH
5150 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5152 [(set_attr "type" "sseicvt")
5153 (set_attr "mode" "<MODE>")
5154 (set_attr "athlon_decode" "direct")
5155 (set_attr "amdfam10_decode" "double")
5156 (set_attr "bdver1_decode" "direct")
5157 (set_attr "fp_int_src" "true")])
5160 [(set (match_operand:MODEF 0 "register_operand" "")
5161 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5162 (clobber (match_operand:SI 2 "memory_operand" ""))]
5163 "TARGET_SSE2 && TARGET_SSE_MATH
5164 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5166 && (SSE_REG_P (operands[0])
5167 || (GET_CODE (operands[0]) == SUBREG
5168 && SSE_REG_P (operands[0])))"
5171 rtx op1 = operands[1];
5173 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5175 if (GET_CODE (op1) == SUBREG)
5176 op1 = SUBREG_REG (op1);
5178 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5180 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5181 emit_insn (gen_sse2_loadld (operands[4],
5182 CONST0_RTX (V4SImode), operands[1]));
5184 /* We can ignore possible trapping value in the
5185 high part of SSE register for non-trapping math. */
5186 else if (SSE_REG_P (op1) && !flag_trapping_math)
5187 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5190 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5191 emit_move_insn (operands[2], operands[1]);
5192 emit_insn (gen_sse2_loadld (operands[4],
5193 CONST0_RTX (V4SImode), operands[2]));
5196 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5201 [(set (match_operand:MODEF 0 "register_operand" "")
5202 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5203 (clobber (match_operand:SI 2 "memory_operand" ""))]
5204 "TARGET_SSE2 && TARGET_SSE_MATH
5205 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5207 && (SSE_REG_P (operands[0])
5208 || (GET_CODE (operands[0]) == SUBREG
5209 && SSE_REG_P (operands[0])))"
5212 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5214 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5216 emit_insn (gen_sse2_loadld (operands[4],
5217 CONST0_RTX (V4SImode), operands[1]));
5219 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5224 [(set (match_operand:MODEF 0 "register_operand" "")
5225 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5226 "TARGET_SSE2 && TARGET_SSE_MATH
5227 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5229 && (SSE_REG_P (operands[0])
5230 || (GET_CODE (operands[0]) == SUBREG
5231 && SSE_REG_P (operands[0])))"
5234 rtx op1 = operands[1];
5236 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5238 if (GET_CODE (op1) == SUBREG)
5239 op1 = SUBREG_REG (op1);
5241 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5243 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5244 emit_insn (gen_sse2_loadld (operands[4],
5245 CONST0_RTX (V4SImode), operands[1]));
5247 /* We can ignore possible trapping value in the
5248 high part of SSE register for non-trapping math. */
5249 else if (SSE_REG_P (op1) && !flag_trapping_math)
5250 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5254 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5259 [(set (match_operand:MODEF 0 "register_operand" "")
5260 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5261 "TARGET_SSE2 && TARGET_SSE_MATH
5262 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5264 && (SSE_REG_P (operands[0])
5265 || (GET_CODE (operands[0]) == SUBREG
5266 && SSE_REG_P (operands[0])))"
5269 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5271 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5273 emit_insn (gen_sse2_loadld (operands[4],
5274 CONST0_RTX (V4SImode), operands[1]));
5276 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5280 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5281 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5283 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5284 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5285 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5286 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5288 [(set_attr "type" "sseicvt")
5289 (set_attr "mode" "<MODEF:MODE>")
5290 (set_attr "athlon_decode" "double,direct")
5291 (set_attr "amdfam10_decode" "vector,double")
5292 (set_attr "bdver1_decode" "double,direct")
5293 (set_attr "fp_int_src" "true")])
5295 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5296 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5298 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5299 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5301 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5302 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5303 [(set_attr "type" "sseicvt")
5304 (set_attr "prefix" "maybe_vex")
5305 (set_attr "mode" "<MODEF:MODE>")
5306 (set (attr "prefix_rex")
5308 (and (eq_attr "prefix" "maybe_vex")
5309 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5311 (const_string "*")))
5312 (set_attr "athlon_decode" "double,direct")
5313 (set_attr "amdfam10_decode" "vector,double")
5314 (set_attr "bdver1_decode" "double,direct")
5315 (set_attr "fp_int_src" "true")])
5318 [(set (match_operand:MODEF 0 "register_operand" "")
5319 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5320 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5321 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5322 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5323 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5325 && (SSE_REG_P (operands[0])
5326 || (GET_CODE (operands[0]) == SUBREG
5327 && SSE_REG_P (operands[0])))"
5328 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5330 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5331 [(set (match_operand:MODEF 0 "register_operand" "=x")
5333 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5334 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5335 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5336 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5337 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5338 [(set_attr "type" "sseicvt")
5339 (set_attr "prefix" "maybe_vex")
5340 (set_attr "mode" "<MODEF:MODE>")
5341 (set (attr "prefix_rex")
5343 (and (eq_attr "prefix" "maybe_vex")
5344 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5346 (const_string "*")))
5347 (set_attr "athlon_decode" "direct")
5348 (set_attr "amdfam10_decode" "double")
5349 (set_attr "bdver1_decode" "direct")
5350 (set_attr "fp_int_src" "true")])
5353 [(set (match_operand:MODEF 0 "register_operand" "")
5354 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5355 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5356 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5357 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5358 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5360 && (SSE_REG_P (operands[0])
5361 || (GET_CODE (operands[0]) == SUBREG
5362 && SSE_REG_P (operands[0])))"
5363 [(set (match_dup 2) (match_dup 1))
5364 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5367 [(set (match_operand:MODEF 0 "register_operand" "")
5368 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5369 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5370 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5371 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5373 && (SSE_REG_P (operands[0])
5374 || (GET_CODE (operands[0]) == SUBREG
5375 && SSE_REG_P (operands[0])))"
5376 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5378 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5379 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5381 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5382 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5384 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5388 [(set_attr "type" "fmov,multi")
5389 (set_attr "mode" "<X87MODEF:MODE>")
5390 (set_attr "unit" "*,i387")
5391 (set_attr "fp_int_src" "true")])
5393 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5394 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5396 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5398 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5400 [(set_attr "type" "fmov")
5401 (set_attr "mode" "<X87MODEF:MODE>")
5402 (set_attr "fp_int_src" "true")])
5405 [(set (match_operand:X87MODEF 0 "register_operand" "")
5406 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5407 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5409 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5411 && FP_REG_P (operands[0])"
5412 [(set (match_dup 2) (match_dup 1))
5413 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5416 [(set (match_operand:X87MODEF 0 "register_operand" "")
5417 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5418 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5420 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5422 && FP_REG_P (operands[0])"
5423 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5425 ;; Avoid store forwarding (partial memory) stall penalty
5426 ;; by passing DImode value through XMM registers. */
5428 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5429 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5431 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5432 (clobber (match_scratch:V4SI 3 "=X,x"))
5433 (clobber (match_scratch:V4SI 4 "=X,x"))
5434 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5435 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5436 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5437 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5439 [(set_attr "type" "multi")
5440 (set_attr "mode" "<X87MODEF:MODE>")
5441 (set_attr "unit" "i387")
5442 (set_attr "fp_int_src" "true")])
5445 [(set (match_operand:X87MODEF 0 "register_operand" "")
5446 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5447 (clobber (match_scratch:V4SI 3 ""))
5448 (clobber (match_scratch:V4SI 4 ""))
5449 (clobber (match_operand:DI 2 "memory_operand" ""))]
5450 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5451 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5452 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5454 && FP_REG_P (operands[0])"
5455 [(set (match_dup 2) (match_dup 3))
5456 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5458 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5459 Assemble the 64-bit DImode value in an xmm register. */
5460 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5461 gen_rtx_SUBREG (SImode, operands[1], 0)));
5462 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5463 gen_rtx_SUBREG (SImode, operands[1], 4)));
5464 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5467 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5471 [(set (match_operand:X87MODEF 0 "register_operand" "")
5472 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5473 (clobber (match_scratch:V4SI 3 ""))
5474 (clobber (match_scratch:V4SI 4 ""))
5475 (clobber (match_operand:DI 2 "memory_operand" ""))]
5476 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5477 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5478 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5480 && FP_REG_P (operands[0])"
5481 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5483 ;; Avoid store forwarding (partial memory) stall penalty by extending
5484 ;; SImode value to DImode through XMM register instead of pushing two
5485 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5486 ;; targets benefit from this optimization. Also note that fild
5487 ;; loads from memory only.
5489 (define_insn "*floatunssi<mode>2_1"
5490 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5491 (unsigned_float:X87MODEF
5492 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5493 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5494 (clobber (match_scratch:SI 3 "=X,x"))]
5496 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5499 [(set_attr "type" "multi")
5500 (set_attr "mode" "<MODE>")])
5503 [(set (match_operand:X87MODEF 0 "register_operand" "")
5504 (unsigned_float:X87MODEF
5505 (match_operand:SI 1 "register_operand" "")))
5506 (clobber (match_operand:DI 2 "memory_operand" ""))
5507 (clobber (match_scratch:SI 3 ""))]
5509 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5511 && reload_completed"
5512 [(set (match_dup 2) (match_dup 1))
5514 (float:X87MODEF (match_dup 2)))]
5515 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5518 [(set (match_operand:X87MODEF 0 "register_operand" "")
5519 (unsigned_float:X87MODEF
5520 (match_operand:SI 1 "memory_operand" "")))
5521 (clobber (match_operand:DI 2 "memory_operand" ""))
5522 (clobber (match_scratch:SI 3 ""))]
5524 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5526 && reload_completed"
5527 [(set (match_dup 2) (match_dup 3))
5529 (float:X87MODEF (match_dup 2)))]
5531 emit_move_insn (operands[3], operands[1]);
5532 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5535 (define_expand "floatunssi<mode>2"
5537 [(set (match_operand:X87MODEF 0 "register_operand" "")
5538 (unsigned_float:X87MODEF
5539 (match_operand:SI 1 "nonimmediate_operand" "")))
5540 (clobber (match_dup 2))
5541 (clobber (match_scratch:SI 3 ""))])]
5543 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5545 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5547 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5549 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5554 enum ix86_stack_slot slot = (virtuals_instantiated
5557 operands[2] = assign_386_stack_local (DImode, slot);
5561 (define_expand "floatunsdisf2"
5562 [(use (match_operand:SF 0 "register_operand" ""))
5563 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5564 "TARGET_64BIT && TARGET_SSE_MATH"
5565 "x86_emit_floatuns (operands); DONE;")
5567 (define_expand "floatunsdidf2"
5568 [(use (match_operand:DF 0 "register_operand" ""))
5569 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5570 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5571 && TARGET_SSE2 && TARGET_SSE_MATH"
5574 x86_emit_floatuns (operands);
5576 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5582 (define_expand "add<mode>3"
5583 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5584 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5585 (match_operand:SDWIM 2 "<general_operand>" "")))]
5587 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5589 (define_insn_and_split "*add<dwi>3_doubleword"
5590 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5592 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5593 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5594 (clobber (reg:CC FLAGS_REG))]
5595 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5598 [(parallel [(set (reg:CC FLAGS_REG)
5599 (unspec:CC [(match_dup 1) (match_dup 2)]
5602 (plus:DWIH (match_dup 1) (match_dup 2)))])
5603 (parallel [(set (match_dup 3)
5607 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5609 (clobber (reg:CC FLAGS_REG))])]
5610 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5612 (define_insn "*add<mode>3_cc"
5613 [(set (reg:CC FLAGS_REG)
5615 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5616 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5618 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5619 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5620 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5621 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5622 [(set_attr "type" "alu")
5623 (set_attr "mode" "<MODE>")])
5625 (define_insn "addqi3_cc"
5626 [(set (reg:CC FLAGS_REG)
5628 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5629 (match_operand:QI 2 "general_operand" "qn,qm")]
5631 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5632 (plus:QI (match_dup 1) (match_dup 2)))]
5633 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5634 "add{b}\t{%2, %0|%0, %2}"
5635 [(set_attr "type" "alu")
5636 (set_attr "mode" "QI")])
5638 (define_insn "*lea_1"
5639 [(set (match_operand:P 0 "register_operand" "=r")
5640 (match_operand:P 1 "no_seg_address_operand" "p"))]
5642 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5643 [(set_attr "type" "lea")
5644 (set_attr "mode" "<MODE>")])
5646 (define_insn "*lea_2"
5647 [(set (match_operand:SI 0 "register_operand" "=r")
5648 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5650 "lea{l}\t{%a1, %0|%0, %a1}"
5651 [(set_attr "type" "lea")
5652 (set_attr "mode" "SI")])
5654 (define_insn "*lea_2_zext"
5655 [(set (match_operand:DI 0 "register_operand" "=r")
5657 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5659 "lea{l}\t{%a1, %k0|%k0, %a1}"
5660 [(set_attr "type" "lea")
5661 (set_attr "mode" "SI")])
5663 (define_insn "*add<mode>_1"
5664 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5666 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5667 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5668 (clobber (reg:CC FLAGS_REG))]
5669 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5671 switch (get_attr_type (insn))
5677 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5678 if (operands[2] == const1_rtx)
5679 return "inc{<imodesuffix>}\t%0";
5682 gcc_assert (operands[2] == constm1_rtx);
5683 return "dec{<imodesuffix>}\t%0";
5687 /* For most processors, ADD is faster than LEA. This alternative
5688 was added to use ADD as much as possible. */
5689 if (which_alternative == 2)
5692 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5695 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5696 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5697 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5699 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5703 (cond [(eq_attr "alternative" "3")
5704 (const_string "lea")
5705 (match_operand:SWI48 2 "incdec_operand" "")
5706 (const_string "incdec")
5708 (const_string "alu")))
5709 (set (attr "length_immediate")
5711 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5713 (const_string "*")))
5714 (set_attr "mode" "<MODE>")])
5716 ;; It may seem that nonimmediate operand is proper one for operand 1.
5717 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5718 ;; we take care in ix86_binary_operator_ok to not allow two memory
5719 ;; operands so proper swapping will be done in reload. This allow
5720 ;; patterns constructed from addsi_1 to match.
5722 (define_insn "*addsi_1_zext"
5723 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5725 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5726 (match_operand:SI 2 "general_operand" "g,0,li"))))
5727 (clobber (reg:CC FLAGS_REG))]
5728 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5730 switch (get_attr_type (insn))
5736 if (operands[2] == const1_rtx)
5737 return "inc{l}\t%k0";
5740 gcc_assert (operands[2] == constm1_rtx);
5741 return "dec{l}\t%k0";
5745 /* For most processors, ADD is faster than LEA. This alternative
5746 was added to use ADD as much as possible. */
5747 if (which_alternative == 1)
5750 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5753 if (x86_maybe_negate_const_int (&operands[2], SImode))
5754 return "sub{l}\t{%2, %k0|%k0, %2}";
5756 return "add{l}\t{%2, %k0|%k0, %2}";
5760 (cond [(eq_attr "alternative" "2")
5761 (const_string "lea")
5762 (match_operand:SI 2 "incdec_operand" "")
5763 (const_string "incdec")
5765 (const_string "alu")))
5766 (set (attr "length_immediate")
5768 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5770 (const_string "*")))
5771 (set_attr "mode" "SI")])
5773 (define_insn "*addhi_1"
5774 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5775 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5776 (match_operand:HI 2 "general_operand" "rn,rm")))
5777 (clobber (reg:CC FLAGS_REG))]
5778 "TARGET_PARTIAL_REG_STALL
5779 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5781 switch (get_attr_type (insn))
5784 if (operands[2] == const1_rtx)
5785 return "inc{w}\t%0";
5788 gcc_assert (operands[2] == constm1_rtx);
5789 return "dec{w}\t%0";
5793 if (x86_maybe_negate_const_int (&operands[2], HImode))
5794 return "sub{w}\t{%2, %0|%0, %2}";
5796 return "add{w}\t{%2, %0|%0, %2}";
5800 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5801 (const_string "incdec")
5802 (const_string "alu")))
5803 (set (attr "length_immediate")
5805 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5807 (const_string "*")))
5808 (set_attr "mode" "HI")])
5810 (define_insn "*addhi_1_lea"
5811 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5812 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5813 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5814 (clobber (reg:CC FLAGS_REG))]
5815 "!TARGET_PARTIAL_REG_STALL
5816 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5818 switch (get_attr_type (insn))
5824 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5825 if (operands[2] == const1_rtx)
5826 return "inc{w}\t%0";
5829 gcc_assert (operands[2] == constm1_rtx);
5830 return "dec{w}\t%0";
5834 /* For most processors, ADD is faster than LEA. This alternative
5835 was added to use ADD as much as possible. */
5836 if (which_alternative == 2)
5839 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5842 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5843 if (x86_maybe_negate_const_int (&operands[2], HImode))
5844 return "sub{w}\t{%2, %0|%0, %2}";
5846 return "add{w}\t{%2, %0|%0, %2}";
5850 (cond [(eq_attr "alternative" "3")
5851 (const_string "lea")
5852 (match_operand:HI 2 "incdec_operand" "")
5853 (const_string "incdec")
5855 (const_string "alu")))
5856 (set (attr "length_immediate")
5858 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5860 (const_string "*")))
5861 (set_attr "mode" "HI,HI,HI,SI")])
5863 ;; %%% Potential partial reg stall on alternative 2. What to do?
5864 (define_insn "*addqi_1"
5865 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5866 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5867 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5868 (clobber (reg:CC FLAGS_REG))]
5869 "TARGET_PARTIAL_REG_STALL
5870 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5872 int widen = (which_alternative == 2);
5873 switch (get_attr_type (insn))
5876 if (operands[2] == const1_rtx)
5877 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5880 gcc_assert (operands[2] == constm1_rtx);
5881 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5885 if (x86_maybe_negate_const_int (&operands[2], QImode))
5888 return "sub{l}\t{%2, %k0|%k0, %2}";
5890 return "sub{b}\t{%2, %0|%0, %2}";
5893 return "add{l}\t{%k2, %k0|%k0, %k2}";
5895 return "add{b}\t{%2, %0|%0, %2}";
5899 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5900 (const_string "incdec")
5901 (const_string "alu")))
5902 (set (attr "length_immediate")
5904 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5906 (const_string "*")))
5907 (set_attr "mode" "QI,QI,SI")])
5909 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5910 (define_insn "*addqi_1_lea"
5911 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5912 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5913 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5914 (clobber (reg:CC FLAGS_REG))]
5915 "!TARGET_PARTIAL_REG_STALL
5916 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5918 int widen = (which_alternative == 3 || which_alternative == 4);
5920 switch (get_attr_type (insn))
5926 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5927 if (operands[2] == const1_rtx)
5928 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5931 gcc_assert (operands[2] == constm1_rtx);
5932 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5936 /* For most processors, ADD is faster than LEA. These alternatives
5937 were added to use ADD as much as possible. */
5938 if (which_alternative == 2 || which_alternative == 4)
5941 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5944 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5945 if (x86_maybe_negate_const_int (&operands[2], QImode))
5948 return "sub{l}\t{%2, %k0|%k0, %2}";
5950 return "sub{b}\t{%2, %0|%0, %2}";
5953 return "add{l}\t{%k2, %k0|%k0, %k2}";
5955 return "add{b}\t{%2, %0|%0, %2}";
5959 (cond [(eq_attr "alternative" "5")
5960 (const_string "lea")
5961 (match_operand:QI 2 "incdec_operand" "")
5962 (const_string "incdec")
5964 (const_string "alu")))
5965 (set (attr "length_immediate")
5967 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5969 (const_string "*")))
5970 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5972 (define_insn "*addqi_1_slp"
5973 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5974 (plus:QI (match_dup 0)
5975 (match_operand:QI 1 "general_operand" "qn,qnm")))
5976 (clobber (reg:CC FLAGS_REG))]
5977 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5978 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5980 switch (get_attr_type (insn))
5983 if (operands[1] == const1_rtx)
5984 return "inc{b}\t%0";
5987 gcc_assert (operands[1] == constm1_rtx);
5988 return "dec{b}\t%0";
5992 if (x86_maybe_negate_const_int (&operands[1], QImode))
5993 return "sub{b}\t{%1, %0|%0, %1}";
5995 return "add{b}\t{%1, %0|%0, %1}";
5999 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6000 (const_string "incdec")
6001 (const_string "alu1")))
6002 (set (attr "memory")
6003 (if_then_else (match_operand 1 "memory_operand" "")
6004 (const_string "load")
6005 (const_string "none")))
6006 (set_attr "mode" "QI")])
6008 ;; Convert lea to the lea pattern to avoid flags dependency.
6010 [(set (match_operand 0 "register_operand" "")
6011 (plus (match_operand 1 "register_operand" "")
6012 (match_operand 2 "nonmemory_operand" "")))
6013 (clobber (reg:CC FLAGS_REG))]
6014 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6018 enum machine_mode mode = GET_MODE (operands[0]);
6020 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6021 may confuse gen_lowpart. */
6024 operands[1] = gen_lowpart (Pmode, operands[1]);
6025 operands[2] = gen_lowpart (Pmode, operands[2]);
6028 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6030 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6031 operands[0] = gen_lowpart (SImode, operands[0]);
6033 if (TARGET_64BIT && mode != Pmode)
6034 pat = gen_rtx_SUBREG (SImode, pat, 0);
6036 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6040 ;; Convert lea to the lea pattern to avoid flags dependency.
6041 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6042 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6044 [(set (match_operand:DI 0 "register_operand" "")
6045 (plus:DI (match_operand:DI 1 "register_operand" "")
6046 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6047 (clobber (reg:CC FLAGS_REG))]
6048 "TARGET_64BIT && reload_completed
6049 && true_regnum (operands[0]) != true_regnum (operands[1])"
6051 (plus:DI (match_dup 1) (match_dup 2)))])
6053 ;; Convert lea to the lea pattern to avoid flags dependency.
6055 [(set (match_operand:DI 0 "register_operand" "")
6057 (plus:SI (match_operand:SI 1 "register_operand" "")
6058 (match_operand:SI 2 "nonmemory_operand" ""))))
6059 (clobber (reg:CC FLAGS_REG))]
6060 "TARGET_64BIT && reload_completed
6061 && ix86_lea_for_add_ok (insn, operands)"
6063 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6065 operands[1] = gen_lowpart (DImode, operands[1]);
6066 operands[2] = gen_lowpart (DImode, operands[2]);
6069 (define_insn "*add<mode>_2"
6070 [(set (reg FLAGS_REG)
6073 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6074 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6076 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6077 (plus:SWI (match_dup 1) (match_dup 2)))]
6078 "ix86_match_ccmode (insn, CCGOCmode)
6079 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6081 switch (get_attr_type (insn))
6084 if (operands[2] == const1_rtx)
6085 return "inc{<imodesuffix>}\t%0";
6088 gcc_assert (operands[2] == constm1_rtx);
6089 return "dec{<imodesuffix>}\t%0";
6093 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6094 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6096 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6100 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6101 (const_string "incdec")
6102 (const_string "alu")))
6103 (set (attr "length_immediate")
6105 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6107 (const_string "*")))
6108 (set_attr "mode" "<MODE>")])
6110 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6111 (define_insn "*addsi_2_zext"
6112 [(set (reg FLAGS_REG)
6114 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6115 (match_operand:SI 2 "general_operand" "g"))
6117 (set (match_operand:DI 0 "register_operand" "=r")
6118 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6119 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6120 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6122 switch (get_attr_type (insn))
6125 if (operands[2] == const1_rtx)
6126 return "inc{l}\t%k0";
6129 gcc_assert (operands[2] == constm1_rtx);
6130 return "dec{l}\t%k0";
6134 if (x86_maybe_negate_const_int (&operands[2], SImode))
6135 return "sub{l}\t{%2, %k0|%k0, %2}";
6137 return "add{l}\t{%2, %k0|%k0, %2}";
6141 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6142 (const_string "incdec")
6143 (const_string "alu")))
6144 (set (attr "length_immediate")
6146 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6148 (const_string "*")))
6149 (set_attr "mode" "SI")])
6151 (define_insn "*add<mode>_3"
6152 [(set (reg FLAGS_REG)
6154 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6155 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6156 (clobber (match_scratch:SWI 0 "=<r>"))]
6157 "ix86_match_ccmode (insn, CCZmode)
6158 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6160 switch (get_attr_type (insn))
6163 if (operands[2] == const1_rtx)
6164 return "inc{<imodesuffix>}\t%0";
6167 gcc_assert (operands[2] == constm1_rtx);
6168 return "dec{<imodesuffix>}\t%0";
6172 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6173 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6175 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6179 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6180 (const_string "incdec")
6181 (const_string "alu")))
6182 (set (attr "length_immediate")
6184 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6186 (const_string "*")))
6187 (set_attr "mode" "<MODE>")])
6189 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6190 (define_insn "*addsi_3_zext"
6191 [(set (reg FLAGS_REG)
6193 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6194 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6195 (set (match_operand:DI 0 "register_operand" "=r")
6196 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6197 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6198 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6200 switch (get_attr_type (insn))
6203 if (operands[2] == const1_rtx)
6204 return "inc{l}\t%k0";
6207 gcc_assert (operands[2] == constm1_rtx);
6208 return "dec{l}\t%k0";
6212 if (x86_maybe_negate_const_int (&operands[2], SImode))
6213 return "sub{l}\t{%2, %k0|%k0, %2}";
6215 return "add{l}\t{%2, %k0|%k0, %2}";
6219 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6220 (const_string "incdec")
6221 (const_string "alu")))
6222 (set (attr "length_immediate")
6224 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6226 (const_string "*")))
6227 (set_attr "mode" "SI")])
6229 ; For comparisons against 1, -1 and 128, we may generate better code
6230 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6231 ; is matched then. We can't accept general immediate, because for
6232 ; case of overflows, the result is messed up.
6233 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6234 ; only for comparisons not depending on it.
6236 (define_insn "*adddi_4"
6237 [(set (reg FLAGS_REG)
6239 (match_operand:DI 1 "nonimmediate_operand" "0")
6240 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6241 (clobber (match_scratch:DI 0 "=rm"))]
6243 && ix86_match_ccmode (insn, CCGCmode)"
6245 switch (get_attr_type (insn))
6248 if (operands[2] == constm1_rtx)
6249 return "inc{q}\t%0";
6252 gcc_assert (operands[2] == const1_rtx);
6253 return "dec{q}\t%0";
6257 if (x86_maybe_negate_const_int (&operands[2], DImode))
6258 return "add{q}\t{%2, %0|%0, %2}";
6260 return "sub{q}\t{%2, %0|%0, %2}";
6264 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6265 (const_string "incdec")
6266 (const_string "alu")))
6267 (set (attr "length_immediate")
6269 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6271 (const_string "*")))
6272 (set_attr "mode" "DI")])
6274 ; For comparisons against 1, -1 and 128, we may generate better code
6275 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6276 ; is matched then. We can't accept general immediate, because for
6277 ; case of overflows, the result is messed up.
6278 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6279 ; only for comparisons not depending on it.
6281 (define_insn "*add<mode>_4"
6282 [(set (reg FLAGS_REG)
6284 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6285 (match_operand:SWI124 2 "const_int_operand" "n")))
6286 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6287 "ix86_match_ccmode (insn, CCGCmode)"
6289 switch (get_attr_type (insn))
6292 if (operands[2] == constm1_rtx)
6293 return "inc{<imodesuffix>}\t%0";
6296 gcc_assert (operands[2] == const1_rtx);
6297 return "dec{<imodesuffix>}\t%0";
6301 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6302 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6304 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6308 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6309 (const_string "incdec")
6310 (const_string "alu")))
6311 (set (attr "length_immediate")
6313 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6315 (const_string "*")))
6316 (set_attr "mode" "<MODE>")])
6318 (define_insn "*add<mode>_5"
6319 [(set (reg FLAGS_REG)
6322 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6323 (match_operand:SWI 2 "<general_operand>" "<g>"))
6325 (clobber (match_scratch:SWI 0 "=<r>"))]
6326 "ix86_match_ccmode (insn, CCGOCmode)
6327 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6329 switch (get_attr_type (insn))
6332 if (operands[2] == const1_rtx)
6333 return "inc{<imodesuffix>}\t%0";
6336 gcc_assert (operands[2] == constm1_rtx);
6337 return "dec{<imodesuffix>}\t%0";
6341 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6342 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6344 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6348 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6349 (const_string "incdec")
6350 (const_string "alu")))
6351 (set (attr "length_immediate")
6353 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6355 (const_string "*")))
6356 (set_attr "mode" "<MODE>")])
6358 (define_insn "*addqi_ext_1_rex64"
6359 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6364 (match_operand 1 "ext_register_operand" "0")
6367 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6368 (clobber (reg:CC FLAGS_REG))]
6371 switch (get_attr_type (insn))
6374 if (operands[2] == const1_rtx)
6375 return "inc{b}\t%h0";
6378 gcc_assert (operands[2] == constm1_rtx);
6379 return "dec{b}\t%h0";
6383 return "add{b}\t{%2, %h0|%h0, %2}";
6387 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6388 (const_string "incdec")
6389 (const_string "alu")))
6390 (set_attr "modrm" "1")
6391 (set_attr "mode" "QI")])
6393 (define_insn "addqi_ext_1"
6394 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6399 (match_operand 1 "ext_register_operand" "0")
6402 (match_operand:QI 2 "general_operand" "Qmn")))
6403 (clobber (reg:CC FLAGS_REG))]
6406 switch (get_attr_type (insn))
6409 if (operands[2] == const1_rtx)
6410 return "inc{b}\t%h0";
6413 gcc_assert (operands[2] == constm1_rtx);
6414 return "dec{b}\t%h0";
6418 return "add{b}\t{%2, %h0|%h0, %2}";
6422 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6423 (const_string "incdec")
6424 (const_string "alu")))
6425 (set_attr "modrm" "1")
6426 (set_attr "mode" "QI")])
6428 (define_insn "*addqi_ext_2"
6429 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6434 (match_operand 1 "ext_register_operand" "%0")
6438 (match_operand 2 "ext_register_operand" "Q")
6441 (clobber (reg:CC FLAGS_REG))]
6443 "add{b}\t{%h2, %h0|%h0, %h2}"
6444 [(set_attr "type" "alu")
6445 (set_attr "mode" "QI")])
6447 ;; The lea patterns for non-Pmodes needs to be matched by
6448 ;; several insns converted to real lea by splitters.
6450 (define_insn_and_split "*lea_general_1"
6451 [(set (match_operand 0 "register_operand" "=r")
6452 (plus (plus (match_operand 1 "index_register_operand" "l")
6453 (match_operand 2 "register_operand" "r"))
6454 (match_operand 3 "immediate_operand" "i")))]
6455 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6456 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6457 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6458 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6459 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6460 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6461 || GET_MODE (operands[3]) == VOIDmode)"
6463 "&& reload_completed"
6467 operands[0] = gen_lowpart (SImode, operands[0]);
6468 operands[1] = gen_lowpart (Pmode, operands[1]);
6469 operands[2] = gen_lowpart (Pmode, operands[2]);
6470 operands[3] = gen_lowpart (Pmode, operands[3]);
6471 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6473 if (Pmode != SImode)
6474 pat = gen_rtx_SUBREG (SImode, pat, 0);
6475 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6478 [(set_attr "type" "lea")
6479 (set_attr "mode" "SI")])
6481 (define_insn_and_split "*lea_general_1_zext"
6482 [(set (match_operand:DI 0 "register_operand" "=r")
6485 (match_operand:SI 1 "index_register_operand" "l")
6486 (match_operand:SI 2 "register_operand" "r"))
6487 (match_operand:SI 3 "immediate_operand" "i"))))]
6490 "&& reload_completed"
6492 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6494 (match_dup 3)) 0)))]
6496 operands[1] = gen_lowpart (Pmode, operands[1]);
6497 operands[2] = gen_lowpart (Pmode, operands[2]);
6498 operands[3] = gen_lowpart (Pmode, operands[3]);
6500 [(set_attr "type" "lea")
6501 (set_attr "mode" "SI")])
6503 (define_insn_and_split "*lea_general_2"
6504 [(set (match_operand 0 "register_operand" "=r")
6505 (plus (mult (match_operand 1 "index_register_operand" "l")
6506 (match_operand 2 "const248_operand" "i"))
6507 (match_operand 3 "nonmemory_operand" "ri")))]
6508 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6509 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6510 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6511 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6512 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6513 || GET_MODE (operands[3]) == VOIDmode)"
6515 "&& reload_completed"
6519 operands[0] = gen_lowpart (SImode, operands[0]);
6520 operands[1] = gen_lowpart (Pmode, operands[1]);
6521 operands[3] = gen_lowpart (Pmode, operands[3]);
6522 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6524 if (Pmode != SImode)
6525 pat = gen_rtx_SUBREG (SImode, pat, 0);
6526 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6529 [(set_attr "type" "lea")
6530 (set_attr "mode" "SI")])
6532 (define_insn_and_split "*lea_general_2_zext"
6533 [(set (match_operand:DI 0 "register_operand" "=r")
6536 (match_operand:SI 1 "index_register_operand" "l")
6537 (match_operand:SI 2 "const248_operand" "n"))
6538 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6541 "&& reload_completed"
6543 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6545 (match_dup 3)) 0)))]
6547 operands[1] = gen_lowpart (Pmode, operands[1]);
6548 operands[3] = gen_lowpart (Pmode, operands[3]);
6550 [(set_attr "type" "lea")
6551 (set_attr "mode" "SI")])
6553 (define_insn_and_split "*lea_general_3"
6554 [(set (match_operand 0 "register_operand" "=r")
6555 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6556 (match_operand 2 "const248_operand" "i"))
6557 (match_operand 3 "register_operand" "r"))
6558 (match_operand 4 "immediate_operand" "i")))]
6559 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6560 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6561 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6562 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6563 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6565 "&& reload_completed"
6569 operands[0] = gen_lowpart (SImode, operands[0]);
6570 operands[1] = gen_lowpart (Pmode, operands[1]);
6571 operands[3] = gen_lowpart (Pmode, operands[3]);
6572 operands[4] = gen_lowpart (Pmode, operands[4]);
6573 pat = gen_rtx_PLUS (Pmode,
6574 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6578 if (Pmode != SImode)
6579 pat = gen_rtx_SUBREG (SImode, pat, 0);
6580 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6583 [(set_attr "type" "lea")
6584 (set_attr "mode" "SI")])
6586 (define_insn_and_split "*lea_general_3_zext"
6587 [(set (match_operand:DI 0 "register_operand" "=r")
6591 (match_operand:SI 1 "index_register_operand" "l")
6592 (match_operand:SI 2 "const248_operand" "n"))
6593 (match_operand:SI 3 "register_operand" "r"))
6594 (match_operand:SI 4 "immediate_operand" "i"))))]
6597 "&& reload_completed"
6599 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6602 (match_dup 4)) 0)))]
6604 operands[1] = gen_lowpart (Pmode, operands[1]);
6605 operands[3] = gen_lowpart (Pmode, operands[3]);
6606 operands[4] = gen_lowpart (Pmode, operands[4]);
6608 [(set_attr "type" "lea")
6609 (set_attr "mode" "SI")])
6611 ;; Subtract instructions
6613 (define_expand "sub<mode>3"
6614 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6615 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6616 (match_operand:SDWIM 2 "<general_operand>" "")))]
6618 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6620 (define_insn_and_split "*sub<dwi>3_doubleword"
6621 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6623 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6624 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6625 (clobber (reg:CC FLAGS_REG))]
6626 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6629 [(parallel [(set (reg:CC FLAGS_REG)
6630 (compare:CC (match_dup 1) (match_dup 2)))
6632 (minus:DWIH (match_dup 1) (match_dup 2)))])
6633 (parallel [(set (match_dup 3)
6637 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6639 (clobber (reg:CC FLAGS_REG))])]
6640 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6642 (define_insn "*sub<mode>_1"
6643 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6645 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6646 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6647 (clobber (reg:CC FLAGS_REG))]
6648 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6649 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6650 [(set_attr "type" "alu")
6651 (set_attr "mode" "<MODE>")])
6653 (define_insn "*subsi_1_zext"
6654 [(set (match_operand:DI 0 "register_operand" "=r")
6656 (minus:SI (match_operand:SI 1 "register_operand" "0")
6657 (match_operand:SI 2 "general_operand" "g"))))
6658 (clobber (reg:CC FLAGS_REG))]
6659 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6660 "sub{l}\t{%2, %k0|%k0, %2}"
6661 [(set_attr "type" "alu")
6662 (set_attr "mode" "SI")])
6664 (define_insn "*subqi_1_slp"
6665 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6666 (minus:QI (match_dup 0)
6667 (match_operand:QI 1 "general_operand" "qn,qm")))
6668 (clobber (reg:CC FLAGS_REG))]
6669 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6670 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6671 "sub{b}\t{%1, %0|%0, %1}"
6672 [(set_attr "type" "alu1")
6673 (set_attr "mode" "QI")])
6675 (define_insn "*sub<mode>_2"
6676 [(set (reg FLAGS_REG)
6679 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6680 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6682 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6683 (minus:SWI (match_dup 1) (match_dup 2)))]
6684 "ix86_match_ccmode (insn, CCGOCmode)
6685 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6686 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "mode" "<MODE>")])
6690 (define_insn "*subsi_2_zext"
6691 [(set (reg FLAGS_REG)
6693 (minus:SI (match_operand:SI 1 "register_operand" "0")
6694 (match_operand:SI 2 "general_operand" "g"))
6696 (set (match_operand:DI 0 "register_operand" "=r")
6698 (minus:SI (match_dup 1)
6700 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6701 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6702 "sub{l}\t{%2, %k0|%k0, %2}"
6703 [(set_attr "type" "alu")
6704 (set_attr "mode" "SI")])
6706 (define_insn "*sub<mode>_3"
6707 [(set (reg FLAGS_REG)
6708 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6709 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6710 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6711 (minus:SWI (match_dup 1) (match_dup 2)))]
6712 "ix86_match_ccmode (insn, CCmode)
6713 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6714 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6715 [(set_attr "type" "alu")
6716 (set_attr "mode" "<MODE>")])
6718 (define_insn "*subsi_3_zext"
6719 [(set (reg FLAGS_REG)
6720 (compare (match_operand:SI 1 "register_operand" "0")
6721 (match_operand:SI 2 "general_operand" "g")))
6722 (set (match_operand:DI 0 "register_operand" "=r")
6724 (minus:SI (match_dup 1)
6726 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6727 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6728 "sub{l}\t{%2, %1|%1, %2}"
6729 [(set_attr "type" "alu")
6730 (set_attr "mode" "SI")])
6732 ;; Add with carry and subtract with borrow
6734 (define_expand "<plusminus_insn><mode>3_carry"
6736 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6738 (match_operand:SWI 1 "nonimmediate_operand" "")
6739 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6740 [(match_operand 3 "flags_reg_operand" "")
6742 (match_operand:SWI 2 "<general_operand>" ""))))
6743 (clobber (reg:CC FLAGS_REG))])]
6744 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6746 (define_insn "*<plusminus_insn><mode>3_carry"
6747 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6749 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6751 (match_operator 3 "ix86_carry_flag_operator"
6752 [(reg FLAGS_REG) (const_int 0)])
6753 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6754 (clobber (reg:CC FLAGS_REG))]
6755 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6756 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6757 [(set_attr "type" "alu")
6758 (set_attr "use_carry" "1")
6759 (set_attr "pent_pair" "pu")
6760 (set_attr "mode" "<MODE>")])
6762 (define_insn "*addsi3_carry_zext"
6763 [(set (match_operand:DI 0 "register_operand" "=r")
6765 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6766 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6767 [(reg FLAGS_REG) (const_int 0)])
6768 (match_operand:SI 2 "general_operand" "g")))))
6769 (clobber (reg:CC FLAGS_REG))]
6770 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6771 "adc{l}\t{%2, %k0|%k0, %2}"
6772 [(set_attr "type" "alu")
6773 (set_attr "use_carry" "1")
6774 (set_attr "pent_pair" "pu")
6775 (set_attr "mode" "SI")])
6777 (define_insn "*subsi3_carry_zext"
6778 [(set (match_operand:DI 0 "register_operand" "=r")
6780 (minus:SI (match_operand:SI 1 "register_operand" "0")
6781 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6782 [(reg FLAGS_REG) (const_int 0)])
6783 (match_operand:SI 2 "general_operand" "g")))))
6784 (clobber (reg:CC FLAGS_REG))]
6785 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6786 "sbb{l}\t{%2, %k0|%k0, %2}"
6787 [(set_attr "type" "alu")
6788 (set_attr "pent_pair" "pu")
6789 (set_attr "mode" "SI")])
6791 ;; Overflow setting add and subtract instructions
6793 (define_insn "*add<mode>3_cconly_overflow"
6794 [(set (reg:CCC FLAGS_REG)
6797 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6798 (match_operand:SWI 2 "<general_operand>" "<g>"))
6800 (clobber (match_scratch:SWI 0 "=<r>"))]
6801 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6802 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6803 [(set_attr "type" "alu")
6804 (set_attr "mode" "<MODE>")])
6806 (define_insn "*sub<mode>3_cconly_overflow"
6807 [(set (reg:CCC FLAGS_REG)
6810 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6811 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6814 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6815 [(set_attr "type" "icmp")
6816 (set_attr "mode" "<MODE>")])
6818 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6819 [(set (reg:CCC FLAGS_REG)
6822 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6823 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6825 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6826 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6827 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6828 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6829 [(set_attr "type" "alu")
6830 (set_attr "mode" "<MODE>")])
6832 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6833 [(set (reg:CCC FLAGS_REG)
6836 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6837 (match_operand:SI 2 "general_operand" "g"))
6839 (set (match_operand:DI 0 "register_operand" "=r")
6840 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6841 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6842 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6843 [(set_attr "type" "alu")
6844 (set_attr "mode" "SI")])
6846 ;; The patterns that match these are at the end of this file.
6848 (define_expand "<plusminus_insn>xf3"
6849 [(set (match_operand:XF 0 "register_operand" "")
6851 (match_operand:XF 1 "register_operand" "")
6852 (match_operand:XF 2 "register_operand" "")))]
6855 (define_expand "<plusminus_insn><mode>3"
6856 [(set (match_operand:MODEF 0 "register_operand" "")
6858 (match_operand:MODEF 1 "register_operand" "")
6859 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6860 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6861 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6863 ;; Multiply instructions
6865 (define_expand "mul<mode>3"
6866 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6868 (match_operand:SWIM248 1 "register_operand" "")
6869 (match_operand:SWIM248 2 "<general_operand>" "")))
6870 (clobber (reg:CC FLAGS_REG))])])
6872 (define_expand "mulqi3"
6873 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6875 (match_operand:QI 1 "register_operand" "")
6876 (match_operand:QI 2 "nonimmediate_operand" "")))
6877 (clobber (reg:CC FLAGS_REG))])]
6878 "TARGET_QIMODE_MATH")
6881 ;; IMUL reg32/64, reg32/64, imm8 Direct
6882 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6883 ;; IMUL reg32/64, reg32/64, imm32 Direct
6884 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6885 ;; IMUL reg32/64, reg32/64 Direct
6886 ;; IMUL reg32/64, mem32/64 Direct
6888 ;; On BDVER1, all above IMULs use DirectPath
6890 (define_insn "*mul<mode>3_1"
6891 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6893 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6894 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6895 (clobber (reg:CC FLAGS_REG))]
6896 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6898 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6899 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6900 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6901 [(set_attr "type" "imul")
6902 (set_attr "prefix_0f" "0,0,1")
6903 (set (attr "athlon_decode")
6904 (cond [(eq_attr "cpu" "athlon")
6905 (const_string "vector")
6906 (eq_attr "alternative" "1")
6907 (const_string "vector")
6908 (and (eq_attr "alternative" "2")
6909 (match_operand 1 "memory_operand" ""))
6910 (const_string "vector")]
6911 (const_string "direct")))
6912 (set (attr "amdfam10_decode")
6913 (cond [(and (eq_attr "alternative" "0,1")
6914 (match_operand 1 "memory_operand" ""))
6915 (const_string "vector")]
6916 (const_string "direct")))
6917 (set_attr "bdver1_decode" "direct")
6918 (set_attr "mode" "<MODE>")])
6920 (define_insn "*mulsi3_1_zext"
6921 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6923 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6924 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6925 (clobber (reg:CC FLAGS_REG))]
6927 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6929 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6930 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6931 imul{l}\t{%2, %k0|%k0, %2}"
6932 [(set_attr "type" "imul")
6933 (set_attr "prefix_0f" "0,0,1")
6934 (set (attr "athlon_decode")
6935 (cond [(eq_attr "cpu" "athlon")
6936 (const_string "vector")
6937 (eq_attr "alternative" "1")
6938 (const_string "vector")
6939 (and (eq_attr "alternative" "2")
6940 (match_operand 1 "memory_operand" ""))
6941 (const_string "vector")]
6942 (const_string "direct")))
6943 (set (attr "amdfam10_decode")
6944 (cond [(and (eq_attr "alternative" "0,1")
6945 (match_operand 1 "memory_operand" ""))
6946 (const_string "vector")]
6947 (const_string "direct")))
6948 (set_attr "bdver1_decode" "direct")
6949 (set_attr "mode" "SI")])
6952 ;; IMUL reg16, reg16, imm8 VectorPath
6953 ;; IMUL reg16, mem16, imm8 VectorPath
6954 ;; IMUL reg16, reg16, imm16 VectorPath
6955 ;; IMUL reg16, mem16, imm16 VectorPath
6956 ;; IMUL reg16, reg16 Direct
6957 ;; IMUL reg16, mem16 Direct
6959 ;; On BDVER1, all HI MULs use DoublePath
6961 (define_insn "*mulhi3_1"
6962 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6963 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6964 (match_operand:HI 2 "general_operand" "K,n,mr")))
6965 (clobber (reg:CC FLAGS_REG))]
6967 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6969 imul{w}\t{%2, %1, %0|%0, %1, %2}
6970 imul{w}\t{%2, %1, %0|%0, %1, %2}
6971 imul{w}\t{%2, %0|%0, %2}"
6972 [(set_attr "type" "imul")
6973 (set_attr "prefix_0f" "0,0,1")
6974 (set (attr "athlon_decode")
6975 (cond [(eq_attr "cpu" "athlon")
6976 (const_string "vector")
6977 (eq_attr "alternative" "1,2")
6978 (const_string "vector")]
6979 (const_string "direct")))
6980 (set (attr "amdfam10_decode")
6981 (cond [(eq_attr "alternative" "0,1")
6982 (const_string "vector")]
6983 (const_string "direct")))
6984 (set_attr "bdver1_decode" "double")
6985 (set_attr "mode" "HI")])
6987 ;;On AMDFAM10 and BDVER1
6991 (define_insn "*mulqi3_1"
6992 [(set (match_operand:QI 0 "register_operand" "=a")
6993 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6994 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6995 (clobber (reg:CC FLAGS_REG))]
6997 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6999 [(set_attr "type" "imul")
7000 (set_attr "length_immediate" "0")
7001 (set (attr "athlon_decode")
7002 (if_then_else (eq_attr "cpu" "athlon")
7003 (const_string "vector")
7004 (const_string "direct")))
7005 (set_attr "amdfam10_decode" "direct")
7006 (set_attr "bdver1_decode" "direct")
7007 (set_attr "mode" "QI")])
7009 (define_expand "<u>mul<mode><dwi>3"
7010 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7013 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7015 (match_operand:DWIH 2 "register_operand" ""))))
7016 (clobber (reg:CC FLAGS_REG))])])
7018 (define_expand "<u>mulqihi3"
7019 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7022 (match_operand:QI 1 "nonimmediate_operand" ""))
7024 (match_operand:QI 2 "register_operand" ""))))
7025 (clobber (reg:CC FLAGS_REG))])]
7026 "TARGET_QIMODE_MATH")
7028 (define_insn "*<u>mul<mode><dwi>3_1"
7029 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7032 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7034 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7035 (clobber (reg:CC FLAGS_REG))]
7036 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7037 "<sgnprefix>mul{<imodesuffix>}\t%2"
7038 [(set_attr "type" "imul")
7039 (set_attr "length_immediate" "0")
7040 (set (attr "athlon_decode")
7041 (if_then_else (eq_attr "cpu" "athlon")
7042 (const_string "vector")
7043 (const_string "double")))
7044 (set_attr "amdfam10_decode" "double")
7045 (set_attr "bdver1_decode" "direct")
7046 (set_attr "mode" "<MODE>")])
7048 (define_insn "*<u>mulqihi3_1"
7049 [(set (match_operand:HI 0 "register_operand" "=a")
7052 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7054 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7055 (clobber (reg:CC FLAGS_REG))]
7057 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7058 "<sgnprefix>mul{b}\t%2"
7059 [(set_attr "type" "imul")
7060 (set_attr "length_immediate" "0")
7061 (set (attr "athlon_decode")
7062 (if_then_else (eq_attr "cpu" "athlon")
7063 (const_string "vector")
7064 (const_string "direct")))
7065 (set_attr "amdfam10_decode" "direct")
7066 (set_attr "bdver1_decode" "direct")
7067 (set_attr "mode" "QI")])
7069 (define_expand "<s>mul<mode>3_highpart"
7070 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7075 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7077 (match_operand:SWI48 2 "register_operand" "")))
7079 (clobber (match_scratch:SWI48 3 ""))
7080 (clobber (reg:CC FLAGS_REG))])]
7082 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7084 (define_insn "*<s>muldi3_highpart_1"
7085 [(set (match_operand:DI 0 "register_operand" "=d")
7090 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7092 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7094 (clobber (match_scratch:DI 3 "=1"))
7095 (clobber (reg:CC FLAGS_REG))]
7097 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7098 "<sgnprefix>mul{q}\t%2"
7099 [(set_attr "type" "imul")
7100 (set_attr "length_immediate" "0")
7101 (set (attr "athlon_decode")
7102 (if_then_else (eq_attr "cpu" "athlon")
7103 (const_string "vector")
7104 (const_string "double")))
7105 (set_attr "amdfam10_decode" "double")
7106 (set_attr "bdver1_decode" "direct")
7107 (set_attr "mode" "DI")])
7109 (define_insn "*<s>mulsi3_highpart_1"
7110 [(set (match_operand:SI 0 "register_operand" "=d")
7115 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7117 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7119 (clobber (match_scratch:SI 3 "=1"))
7120 (clobber (reg:CC FLAGS_REG))]
7121 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7122 "<sgnprefix>mul{l}\t%2"
7123 [(set_attr "type" "imul")
7124 (set_attr "length_immediate" "0")
7125 (set (attr "athlon_decode")
7126 (if_then_else (eq_attr "cpu" "athlon")
7127 (const_string "vector")
7128 (const_string "double")))
7129 (set_attr "amdfam10_decode" "double")
7130 (set_attr "bdver1_decode" "direct")
7131 (set_attr "mode" "SI")])
7133 (define_insn "*<s>mulsi3_highpart_zext"
7134 [(set (match_operand:DI 0 "register_operand" "=d")
7135 (zero_extend:DI (truncate:SI
7137 (mult:DI (any_extend:DI
7138 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7140 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7142 (clobber (match_scratch:SI 3 "=1"))
7143 (clobber (reg:CC FLAGS_REG))]
7145 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7146 "<sgnprefix>mul{l}\t%2"
7147 [(set_attr "type" "imul")
7148 (set_attr "length_immediate" "0")
7149 (set (attr "athlon_decode")
7150 (if_then_else (eq_attr "cpu" "athlon")
7151 (const_string "vector")
7152 (const_string "double")))
7153 (set_attr "amdfam10_decode" "double")
7154 (set_attr "bdver1_decode" "direct")
7155 (set_attr "mode" "SI")])
7157 ;; The patterns that match these are at the end of this file.
7159 (define_expand "mulxf3"
7160 [(set (match_operand:XF 0 "register_operand" "")
7161 (mult:XF (match_operand:XF 1 "register_operand" "")
7162 (match_operand:XF 2 "register_operand" "")))]
7165 (define_expand "mul<mode>3"
7166 [(set (match_operand:MODEF 0 "register_operand" "")
7167 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7168 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7169 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7170 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7172 ;; Divide instructions
7174 ;; The patterns that match these are at the end of this file.
7176 (define_expand "divxf3"
7177 [(set (match_operand:XF 0 "register_operand" "")
7178 (div:XF (match_operand:XF 1 "register_operand" "")
7179 (match_operand:XF 2 "register_operand" "")))]
7182 (define_expand "divdf3"
7183 [(set (match_operand:DF 0 "register_operand" "")
7184 (div:DF (match_operand:DF 1 "register_operand" "")
7185 (match_operand:DF 2 "nonimmediate_operand" "")))]
7186 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7187 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7189 (define_expand "divsf3"
7190 [(set (match_operand:SF 0 "register_operand" "")
7191 (div:SF (match_operand:SF 1 "register_operand" "")
7192 (match_operand:SF 2 "nonimmediate_operand" "")))]
7193 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7196 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7197 && flag_finite_math_only && !flag_trapping_math
7198 && flag_unsafe_math_optimizations)
7200 ix86_emit_swdivsf (operands[0], operands[1],
7201 operands[2], SFmode);
7206 ;; Divmod instructions.
7208 (define_expand "divmod<mode>4"
7209 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7211 (match_operand:SWIM248 1 "register_operand" "")
7212 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7213 (set (match_operand:SWIM248 3 "register_operand" "")
7214 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7215 (clobber (reg:CC FLAGS_REG))])])
7217 ;; Split with 8bit unsigned divide:
7218 ;; if (dividend an divisor are in [0-255])
7219 ;; use 8bit unsigned integer divide
7221 ;; use original integer divide
7223 [(set (match_operand:SWI48 0 "register_operand" "")
7224 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7225 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7226 (set (match_operand:SWI48 1 "register_operand" "")
7227 (mod:SWI48 (match_dup 2) (match_dup 3)))
7228 (clobber (reg:CC FLAGS_REG))]
7229 "TARGET_USE_8BIT_IDIV
7230 && TARGET_QIMODE_MATH
7231 && can_create_pseudo_p ()
7232 && !optimize_insn_for_size_p ()"
7234 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7236 (define_insn_and_split "divmod<mode>4_1"
7237 [(set (match_operand:SWI48 0 "register_operand" "=a")
7238 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7239 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7240 (set (match_operand:SWI48 1 "register_operand" "=&d")
7241 (mod:SWI48 (match_dup 2) (match_dup 3)))
7242 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7243 (clobber (reg:CC FLAGS_REG))]
7247 [(parallel [(set (match_dup 1)
7248 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7249 (clobber (reg:CC FLAGS_REG))])
7250 (parallel [(set (match_dup 0)
7251 (div:SWI48 (match_dup 2) (match_dup 3)))
7253 (mod:SWI48 (match_dup 2) (match_dup 3)))
7255 (clobber (reg:CC FLAGS_REG))])]
7257 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7259 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7260 operands[4] = operands[2];
7263 /* Avoid use of cltd in favor of a mov+shift. */
7264 emit_move_insn (operands[1], operands[2]);
7265 operands[4] = operands[1];
7268 [(set_attr "type" "multi")
7269 (set_attr "mode" "<MODE>")])
7271 (define_insn_and_split "*divmod<mode>4"
7272 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7273 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7274 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7275 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7276 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7277 (clobber (reg:CC FLAGS_REG))]
7281 [(parallel [(set (match_dup 1)
7282 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7283 (clobber (reg:CC FLAGS_REG))])
7284 (parallel [(set (match_dup 0)
7285 (div:SWIM248 (match_dup 2) (match_dup 3)))
7287 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7289 (clobber (reg:CC FLAGS_REG))])]
7291 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7293 if (<MODE>mode != HImode
7294 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7295 operands[4] = operands[2];
7298 /* Avoid use of cltd in favor of a mov+shift. */
7299 emit_move_insn (operands[1], operands[2]);
7300 operands[4] = operands[1];
7303 [(set_attr "type" "multi")
7304 (set_attr "mode" "<MODE>")])
7306 (define_insn "*divmod<mode>4_noext"
7307 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7308 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7309 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7310 (set (match_operand:SWIM248 1 "register_operand" "=d")
7311 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7312 (use (match_operand:SWIM248 4 "register_operand" "1"))
7313 (clobber (reg:CC FLAGS_REG))]
7315 "idiv{<imodesuffix>}\t%3"
7316 [(set_attr "type" "idiv")
7317 (set_attr "mode" "<MODE>")])
7319 (define_expand "divmodqi4"
7320 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7322 (match_operand:QI 1 "register_operand" "")
7323 (match_operand:QI 2 "nonimmediate_operand" "")))
7324 (set (match_operand:QI 3 "register_operand" "")
7325 (mod:QI (match_dup 1) (match_dup 2)))
7326 (clobber (reg:CC FLAGS_REG))])]
7327 "TARGET_QIMODE_MATH"
7332 tmp0 = gen_reg_rtx (HImode);
7333 tmp1 = gen_reg_rtx (HImode);
7335 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7337 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7338 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7340 /* Extract remainder from AH. */
7341 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7342 insn = emit_move_insn (operands[3], tmp1);
7344 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7345 set_unique_reg_note (insn, REG_EQUAL, mod);
7347 /* Extract quotient from AL. */
7348 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7350 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7351 set_unique_reg_note (insn, REG_EQUAL, div);
7356 ;; Divide AX by r/m8, with result stored in
7359 ;; Change div/mod to HImode and extend the second argument to HImode
7360 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7361 ;; combine may fail.
7362 (define_insn "divmodhiqi3"
7363 [(set (match_operand:HI 0 "register_operand" "=a")
7368 (mod:HI (match_operand:HI 1 "register_operand" "0")
7370 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7374 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7375 (clobber (reg:CC FLAGS_REG))]
7376 "TARGET_QIMODE_MATH"
7378 [(set_attr "type" "idiv")
7379 (set_attr "mode" "QI")])
7381 (define_expand "udivmod<mode>4"
7382 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7384 (match_operand:SWIM248 1 "register_operand" "")
7385 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7386 (set (match_operand:SWIM248 3 "register_operand" "")
7387 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7388 (clobber (reg:CC FLAGS_REG))])])
7390 ;; Split with 8bit unsigned divide:
7391 ;; if (dividend an divisor are in [0-255])
7392 ;; use 8bit unsigned integer divide
7394 ;; use original integer divide
7396 [(set (match_operand:SWI48 0 "register_operand" "")
7397 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7398 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7399 (set (match_operand:SWI48 1 "register_operand" "")
7400 (umod:SWI48 (match_dup 2) (match_dup 3)))
7401 (clobber (reg:CC FLAGS_REG))]
7402 "TARGET_USE_8BIT_IDIV
7403 && TARGET_QIMODE_MATH
7404 && can_create_pseudo_p ()
7405 && !optimize_insn_for_size_p ()"
7407 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7409 (define_insn_and_split "udivmod<mode>4_1"
7410 [(set (match_operand:SWI48 0 "register_operand" "=a")
7411 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7412 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7413 (set (match_operand:SWI48 1 "register_operand" "=&d")
7414 (umod:SWI48 (match_dup 2) (match_dup 3)))
7415 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7416 (clobber (reg:CC FLAGS_REG))]
7420 [(set (match_dup 1) (const_int 0))
7421 (parallel [(set (match_dup 0)
7422 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7424 (umod:SWI48 (match_dup 2) (match_dup 3)))
7426 (clobber (reg:CC FLAGS_REG))])]
7428 [(set_attr "type" "multi")
7429 (set_attr "mode" "<MODE>")])
7431 (define_insn_and_split "*udivmod<mode>4"
7432 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7433 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7434 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7435 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7436 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7437 (clobber (reg:CC FLAGS_REG))]
7441 [(set (match_dup 1) (const_int 0))
7442 (parallel [(set (match_dup 0)
7443 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7445 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7447 (clobber (reg:CC FLAGS_REG))])]
7449 [(set_attr "type" "multi")
7450 (set_attr "mode" "<MODE>")])
7452 (define_insn "*udivmod<mode>4_noext"
7453 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7454 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7455 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7456 (set (match_operand:SWIM248 1 "register_operand" "=d")
7457 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7458 (use (match_operand:SWIM248 4 "register_operand" "1"))
7459 (clobber (reg:CC FLAGS_REG))]
7461 "div{<imodesuffix>}\t%3"
7462 [(set_attr "type" "idiv")
7463 (set_attr "mode" "<MODE>")])
7465 (define_expand "udivmodqi4"
7466 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7468 (match_operand:QI 1 "register_operand" "")
7469 (match_operand:QI 2 "nonimmediate_operand" "")))
7470 (set (match_operand:QI 3 "register_operand" "")
7471 (umod:QI (match_dup 1) (match_dup 2)))
7472 (clobber (reg:CC FLAGS_REG))])]
7473 "TARGET_QIMODE_MATH"
7478 tmp0 = gen_reg_rtx (HImode);
7479 tmp1 = gen_reg_rtx (HImode);
7481 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7483 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7484 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7486 /* Extract remainder from AH. */
7487 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7488 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7489 insn = emit_move_insn (operands[3], tmp1);
7491 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7492 set_unique_reg_note (insn, REG_EQUAL, mod);
7494 /* Extract quotient from AL. */
7495 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7497 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7498 set_unique_reg_note (insn, REG_EQUAL, div);
7503 (define_insn "udivmodhiqi3"
7504 [(set (match_operand:HI 0 "register_operand" "=a")
7509 (mod:HI (match_operand:HI 1 "register_operand" "0")
7511 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7515 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7516 (clobber (reg:CC FLAGS_REG))]
7517 "TARGET_QIMODE_MATH"
7519 [(set_attr "type" "idiv")
7520 (set_attr "mode" "QI")])
7522 ;; We cannot use div/idiv for double division, because it causes
7523 ;; "division by zero" on the overflow and that's not what we expect
7524 ;; from truncate. Because true (non truncating) double division is
7525 ;; never generated, we can't create this insn anyway.
7528 ; [(set (match_operand:SI 0 "register_operand" "=a")
7530 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7532 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7533 ; (set (match_operand:SI 3 "register_operand" "=d")
7535 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7536 ; (clobber (reg:CC FLAGS_REG))]
7538 ; "div{l}\t{%2, %0|%0, %2}"
7539 ; [(set_attr "type" "idiv")])
7541 ;;- Logical AND instructions
7543 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7544 ;; Note that this excludes ah.
7546 (define_expand "testsi_ccno_1"
7547 [(set (reg:CCNO FLAGS_REG)
7549 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7550 (match_operand:SI 1 "nonmemory_operand" ""))
7553 (define_expand "testqi_ccz_1"
7554 [(set (reg:CCZ FLAGS_REG)
7555 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7556 (match_operand:QI 1 "nonmemory_operand" ""))
7559 (define_expand "testdi_ccno_1"
7560 [(set (reg:CCNO FLAGS_REG)
7562 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7563 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7565 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7567 (define_insn "*testdi_1"
7568 [(set (reg FLAGS_REG)
7571 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7572 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7574 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7575 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7577 test{l}\t{%k1, %k0|%k0, %k1}
7578 test{l}\t{%k1, %k0|%k0, %k1}
7579 test{q}\t{%1, %0|%0, %1}
7580 test{q}\t{%1, %0|%0, %1}
7581 test{q}\t{%1, %0|%0, %1}"
7582 [(set_attr "type" "test")
7583 (set_attr "modrm" "0,1,0,1,1")
7584 (set_attr "mode" "SI,SI,DI,DI,DI")])
7586 (define_insn "*testqi_1_maybe_si"
7587 [(set (reg FLAGS_REG)
7590 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7591 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7593 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7594 && ix86_match_ccmode (insn,
7595 CONST_INT_P (operands[1])
7596 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7598 if (which_alternative == 3)
7600 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7601 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7602 return "test{l}\t{%1, %k0|%k0, %1}";
7604 return "test{b}\t{%1, %0|%0, %1}";
7606 [(set_attr "type" "test")
7607 (set_attr "modrm" "0,1,1,1")
7608 (set_attr "mode" "QI,QI,QI,SI")
7609 (set_attr "pent_pair" "uv,np,uv,np")])
7611 (define_insn "*test<mode>_1"
7612 [(set (reg FLAGS_REG)
7615 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7616 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7618 "ix86_match_ccmode (insn, CCNOmode)
7619 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7620 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7621 [(set_attr "type" "test")
7622 (set_attr "modrm" "0,1,1")
7623 (set_attr "mode" "<MODE>")
7624 (set_attr "pent_pair" "uv,np,uv")])
7626 (define_expand "testqi_ext_ccno_0"
7627 [(set (reg:CCNO FLAGS_REG)
7631 (match_operand 0 "ext_register_operand" "")
7634 (match_operand 1 "const_int_operand" ""))
7637 (define_insn "*testqi_ext_0"
7638 [(set (reg FLAGS_REG)
7642 (match_operand 0 "ext_register_operand" "Q")
7645 (match_operand 1 "const_int_operand" "n"))
7647 "ix86_match_ccmode (insn, CCNOmode)"
7648 "test{b}\t{%1, %h0|%h0, %1}"
7649 [(set_attr "type" "test")
7650 (set_attr "mode" "QI")
7651 (set_attr "length_immediate" "1")
7652 (set_attr "modrm" "1")
7653 (set_attr "pent_pair" "np")])
7655 (define_insn "*testqi_ext_1_rex64"
7656 [(set (reg FLAGS_REG)
7660 (match_operand 0 "ext_register_operand" "Q")
7664 (match_operand:QI 1 "register_operand" "Q")))
7666 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7667 "test{b}\t{%1, %h0|%h0, %1}"
7668 [(set_attr "type" "test")
7669 (set_attr "mode" "QI")])
7671 (define_insn "*testqi_ext_1"
7672 [(set (reg FLAGS_REG)
7676 (match_operand 0 "ext_register_operand" "Q")
7680 (match_operand:QI 1 "general_operand" "Qm")))
7682 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7683 "test{b}\t{%1, %h0|%h0, %1}"
7684 [(set_attr "type" "test")
7685 (set_attr "mode" "QI")])
7687 (define_insn "*testqi_ext_2"
7688 [(set (reg FLAGS_REG)
7692 (match_operand 0 "ext_register_operand" "Q")
7696 (match_operand 1 "ext_register_operand" "Q")
7700 "ix86_match_ccmode (insn, CCNOmode)"
7701 "test{b}\t{%h1, %h0|%h0, %h1}"
7702 [(set_attr "type" "test")
7703 (set_attr "mode" "QI")])
7705 (define_insn "*testqi_ext_3_rex64"
7706 [(set (reg FLAGS_REG)
7707 (compare (zero_extract:DI
7708 (match_operand 0 "nonimmediate_operand" "rm")
7709 (match_operand:DI 1 "const_int_operand" "")
7710 (match_operand:DI 2 "const_int_operand" ""))
7713 && ix86_match_ccmode (insn, CCNOmode)
7714 && INTVAL (operands[1]) > 0
7715 && INTVAL (operands[2]) >= 0
7716 /* Ensure that resulting mask is zero or sign extended operand. */
7717 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7718 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7719 && INTVAL (operands[1]) > 32))
7720 && (GET_MODE (operands[0]) == SImode
7721 || GET_MODE (operands[0]) == DImode
7722 || GET_MODE (operands[0]) == HImode
7723 || GET_MODE (operands[0]) == QImode)"
7726 ;; Combine likes to form bit extractions for some tests. Humor it.
7727 (define_insn "*testqi_ext_3"
7728 [(set (reg FLAGS_REG)
7729 (compare (zero_extract:SI
7730 (match_operand 0 "nonimmediate_operand" "rm")
7731 (match_operand:SI 1 "const_int_operand" "")
7732 (match_operand:SI 2 "const_int_operand" ""))
7734 "ix86_match_ccmode (insn, CCNOmode)
7735 && INTVAL (operands[1]) > 0
7736 && INTVAL (operands[2]) >= 0
7737 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7738 && (GET_MODE (operands[0]) == SImode
7739 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7740 || GET_MODE (operands[0]) == HImode
7741 || GET_MODE (operands[0]) == QImode)"
7745 [(set (match_operand 0 "flags_reg_operand" "")
7746 (match_operator 1 "compare_operator"
7748 (match_operand 2 "nonimmediate_operand" "")
7749 (match_operand 3 "const_int_operand" "")
7750 (match_operand 4 "const_int_operand" ""))
7752 "ix86_match_ccmode (insn, CCNOmode)"
7753 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7755 rtx val = operands[2];
7756 HOST_WIDE_INT len = INTVAL (operands[3]);
7757 HOST_WIDE_INT pos = INTVAL (operands[4]);
7759 enum machine_mode mode, submode;
7761 mode = GET_MODE (val);
7764 /* ??? Combine likes to put non-volatile mem extractions in QImode
7765 no matter the size of the test. So find a mode that works. */
7766 if (! MEM_VOLATILE_P (val))
7768 mode = smallest_mode_for_size (pos + len, MODE_INT);
7769 val = adjust_address (val, mode, 0);
7772 else if (GET_CODE (val) == SUBREG
7773 && (submode = GET_MODE (SUBREG_REG (val)),
7774 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7775 && pos + len <= GET_MODE_BITSIZE (submode)
7776 && GET_MODE_CLASS (submode) == MODE_INT)
7778 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7780 val = SUBREG_REG (val);
7782 else if (mode == HImode && pos + len <= 8)
7784 /* Small HImode tests can be converted to QImode. */
7786 val = gen_lowpart (QImode, val);
7789 if (len == HOST_BITS_PER_WIDE_INT)
7792 mask = ((HOST_WIDE_INT)1 << len) - 1;
7795 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7798 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7799 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7800 ;; this is relatively important trick.
7801 ;; Do the conversion only post-reload to avoid limiting of the register class
7804 [(set (match_operand 0 "flags_reg_operand" "")
7805 (match_operator 1 "compare_operator"
7806 [(and (match_operand 2 "register_operand" "")
7807 (match_operand 3 "const_int_operand" ""))
7810 && QI_REG_P (operands[2])
7811 && GET_MODE (operands[2]) != QImode
7812 && ((ix86_match_ccmode (insn, CCZmode)
7813 && !(INTVAL (operands[3]) & ~(255 << 8)))
7814 || (ix86_match_ccmode (insn, CCNOmode)
7815 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7818 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7821 "operands[2] = gen_lowpart (SImode, operands[2]);
7822 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7825 [(set (match_operand 0 "flags_reg_operand" "")
7826 (match_operator 1 "compare_operator"
7827 [(and (match_operand 2 "nonimmediate_operand" "")
7828 (match_operand 3 "const_int_operand" ""))
7831 && GET_MODE (operands[2]) != QImode
7832 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7833 && ((ix86_match_ccmode (insn, CCZmode)
7834 && !(INTVAL (operands[3]) & ~255))
7835 || (ix86_match_ccmode (insn, CCNOmode)
7836 && !(INTVAL (operands[3]) & ~127)))"
7838 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7840 "operands[2] = gen_lowpart (QImode, operands[2]);
7841 operands[3] = gen_lowpart (QImode, operands[3]);")
7843 ;; %%% This used to optimize known byte-wide and operations to memory,
7844 ;; and sometimes to QImode registers. If this is considered useful,
7845 ;; it should be done with splitters.
7847 (define_expand "and<mode>3"
7848 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7849 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7850 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7852 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7854 (define_insn "*anddi_1"
7855 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7857 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7858 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7859 (clobber (reg:CC FLAGS_REG))]
7860 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7862 switch (get_attr_type (insn))
7866 enum machine_mode mode;
7868 gcc_assert (CONST_INT_P (operands[2]));
7869 if (INTVAL (operands[2]) == 0xff)
7873 gcc_assert (INTVAL (operands[2]) == 0xffff);
7877 operands[1] = gen_lowpart (mode, operands[1]);
7879 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7881 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7885 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7886 if (get_attr_mode (insn) == MODE_SI)
7887 return "and{l}\t{%k2, %k0|%k0, %k2}";
7889 return "and{q}\t{%2, %0|%0, %2}";
7892 [(set_attr "type" "alu,alu,alu,imovx")
7893 (set_attr "length_immediate" "*,*,*,0")
7894 (set (attr "prefix_rex")
7896 (and (eq_attr "type" "imovx")
7897 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7898 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7900 (const_string "*")))
7901 (set_attr "mode" "SI,DI,DI,SI")])
7903 (define_insn "*andsi_1"
7904 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7905 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7906 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7907 (clobber (reg:CC FLAGS_REG))]
7908 "ix86_binary_operator_ok (AND, SImode, operands)"
7910 switch (get_attr_type (insn))
7914 enum machine_mode mode;
7916 gcc_assert (CONST_INT_P (operands[2]));
7917 if (INTVAL (operands[2]) == 0xff)
7921 gcc_assert (INTVAL (operands[2]) == 0xffff);
7925 operands[1] = gen_lowpart (mode, operands[1]);
7927 return "movz{bl|x}\t{%1, %0|%0, %1}";
7929 return "movz{wl|x}\t{%1, %0|%0, %1}";
7933 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7934 return "and{l}\t{%2, %0|%0, %2}";
7937 [(set_attr "type" "alu,alu,imovx")
7938 (set (attr "prefix_rex")
7940 (and (eq_attr "type" "imovx")
7941 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7942 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7944 (const_string "*")))
7945 (set_attr "length_immediate" "*,*,0")
7946 (set_attr "mode" "SI")])
7948 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7949 (define_insn "*andsi_1_zext"
7950 [(set (match_operand:DI 0 "register_operand" "=r")
7952 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7953 (match_operand:SI 2 "general_operand" "g"))))
7954 (clobber (reg:CC FLAGS_REG))]
7955 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7956 "and{l}\t{%2, %k0|%k0, %2}"
7957 [(set_attr "type" "alu")
7958 (set_attr "mode" "SI")])
7960 (define_insn "*andhi_1"
7961 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7962 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7963 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7964 (clobber (reg:CC FLAGS_REG))]
7965 "ix86_binary_operator_ok (AND, HImode, operands)"
7967 switch (get_attr_type (insn))
7970 gcc_assert (CONST_INT_P (operands[2]));
7971 gcc_assert (INTVAL (operands[2]) == 0xff);
7972 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7975 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7977 return "and{w}\t{%2, %0|%0, %2}";
7980 [(set_attr "type" "alu,alu,imovx")
7981 (set_attr "length_immediate" "*,*,0")
7982 (set (attr "prefix_rex")
7984 (and (eq_attr "type" "imovx")
7985 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7987 (const_string "*")))
7988 (set_attr "mode" "HI,HI,SI")])
7990 ;; %%% Potential partial reg stall on alternative 2. What to do?
7991 (define_insn "*andqi_1"
7992 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7993 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7994 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7995 (clobber (reg:CC FLAGS_REG))]
7996 "ix86_binary_operator_ok (AND, QImode, operands)"
7998 and{b}\t{%2, %0|%0, %2}
7999 and{b}\t{%2, %0|%0, %2}
8000 and{l}\t{%k2, %k0|%k0, %k2}"
8001 [(set_attr "type" "alu")
8002 (set_attr "mode" "QI,QI,SI")])
8004 (define_insn "*andqi_1_slp"
8005 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8006 (and:QI (match_dup 0)
8007 (match_operand:QI 1 "general_operand" "qn,qmn")))
8008 (clobber (reg:CC FLAGS_REG))]
8009 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8010 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8011 "and{b}\t{%1, %0|%0, %1}"
8012 [(set_attr "type" "alu1")
8013 (set_attr "mode" "QI")])
8016 [(set (match_operand 0 "register_operand" "")
8018 (const_int -65536)))
8019 (clobber (reg:CC FLAGS_REG))]
8020 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8021 || optimize_function_for_size_p (cfun)"
8022 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8023 "operands[1] = gen_lowpart (HImode, operands[0]);")
8026 [(set (match_operand 0 "ext_register_operand" "")
8029 (clobber (reg:CC FLAGS_REG))]
8030 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8031 && reload_completed"
8032 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8033 "operands[1] = gen_lowpart (QImode, operands[0]);")
8036 [(set (match_operand 0 "ext_register_operand" "")
8038 (const_int -65281)))
8039 (clobber (reg:CC FLAGS_REG))]
8040 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8041 && reload_completed"
8042 [(parallel [(set (zero_extract:SI (match_dup 0)
8046 (zero_extract:SI (match_dup 0)
8049 (zero_extract:SI (match_dup 0)
8052 (clobber (reg:CC FLAGS_REG))])]
8053 "operands[0] = gen_lowpart (SImode, operands[0]);")
8055 (define_insn "*anddi_2"
8056 [(set (reg FLAGS_REG)
8059 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8060 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8062 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8063 (and:DI (match_dup 1) (match_dup 2)))]
8064 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8065 && ix86_binary_operator_ok (AND, DImode, operands)"
8067 and{l}\t{%k2, %k0|%k0, %k2}
8068 and{q}\t{%2, %0|%0, %2}
8069 and{q}\t{%2, %0|%0, %2}"
8070 [(set_attr "type" "alu")
8071 (set_attr "mode" "SI,DI,DI")])
8073 (define_insn "*andqi_2_maybe_si"
8074 [(set (reg FLAGS_REG)
8076 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8077 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8079 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8080 (and:QI (match_dup 1) (match_dup 2)))]
8081 "ix86_binary_operator_ok (AND, QImode, operands)
8082 && ix86_match_ccmode (insn,
8083 CONST_INT_P (operands[2])
8084 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8086 if (which_alternative == 2)
8088 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8089 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8090 return "and{l}\t{%2, %k0|%k0, %2}";
8092 return "and{b}\t{%2, %0|%0, %2}";
8094 [(set_attr "type" "alu")
8095 (set_attr "mode" "QI,QI,SI")])
8097 (define_insn "*and<mode>_2"
8098 [(set (reg FLAGS_REG)
8099 (compare (and:SWI124
8100 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8101 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8103 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8104 (and:SWI124 (match_dup 1) (match_dup 2)))]
8105 "ix86_match_ccmode (insn, CCNOmode)
8106 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8107 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8108 [(set_attr "type" "alu")
8109 (set_attr "mode" "<MODE>")])
8111 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8112 (define_insn "*andsi_2_zext"
8113 [(set (reg FLAGS_REG)
8115 (match_operand:SI 1 "nonimmediate_operand" "%0")
8116 (match_operand:SI 2 "general_operand" "g"))
8118 (set (match_operand:DI 0 "register_operand" "=r")
8119 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8120 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8121 && ix86_binary_operator_ok (AND, SImode, operands)"
8122 "and{l}\t{%2, %k0|%k0, %2}"
8123 [(set_attr "type" "alu")
8124 (set_attr "mode" "SI")])
8126 (define_insn "*andqi_2_slp"
8127 [(set (reg FLAGS_REG)
8129 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8130 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8132 (set (strict_low_part (match_dup 0))
8133 (and:QI (match_dup 0) (match_dup 1)))]
8134 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8135 && ix86_match_ccmode (insn, CCNOmode)
8136 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8137 "and{b}\t{%1, %0|%0, %1}"
8138 [(set_attr "type" "alu1")
8139 (set_attr "mode" "QI")])
8141 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8142 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8143 ;; for a QImode operand, which of course failed.
8144 (define_insn "andqi_ext_0"
8145 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8150 (match_operand 1 "ext_register_operand" "0")
8153 (match_operand 2 "const_int_operand" "n")))
8154 (clobber (reg:CC FLAGS_REG))]
8156 "and{b}\t{%2, %h0|%h0, %2}"
8157 [(set_attr "type" "alu")
8158 (set_attr "length_immediate" "1")
8159 (set_attr "modrm" "1")
8160 (set_attr "mode" "QI")])
8162 ;; Generated by peephole translating test to and. This shows up
8163 ;; often in fp comparisons.
8164 (define_insn "*andqi_ext_0_cc"
8165 [(set (reg FLAGS_REG)
8169 (match_operand 1 "ext_register_operand" "0")
8172 (match_operand 2 "const_int_operand" "n"))
8174 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8183 "ix86_match_ccmode (insn, CCNOmode)"
8184 "and{b}\t{%2, %h0|%h0, %2}"
8185 [(set_attr "type" "alu")
8186 (set_attr "length_immediate" "1")
8187 (set_attr "modrm" "1")
8188 (set_attr "mode" "QI")])
8190 (define_insn "*andqi_ext_1_rex64"
8191 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8196 (match_operand 1 "ext_register_operand" "0")
8200 (match_operand 2 "ext_register_operand" "Q"))))
8201 (clobber (reg:CC FLAGS_REG))]
8203 "and{b}\t{%2, %h0|%h0, %2}"
8204 [(set_attr "type" "alu")
8205 (set_attr "length_immediate" "0")
8206 (set_attr "mode" "QI")])
8208 (define_insn "*andqi_ext_1"
8209 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8214 (match_operand 1 "ext_register_operand" "0")
8218 (match_operand:QI 2 "general_operand" "Qm"))))
8219 (clobber (reg:CC FLAGS_REG))]
8221 "and{b}\t{%2, %h0|%h0, %2}"
8222 [(set_attr "type" "alu")
8223 (set_attr "length_immediate" "0")
8224 (set_attr "mode" "QI")])
8226 (define_insn "*andqi_ext_2"
8227 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8232 (match_operand 1 "ext_register_operand" "%0")
8236 (match_operand 2 "ext_register_operand" "Q")
8239 (clobber (reg:CC FLAGS_REG))]
8241 "and{b}\t{%h2, %h0|%h0, %h2}"
8242 [(set_attr "type" "alu")
8243 (set_attr "length_immediate" "0")
8244 (set_attr "mode" "QI")])
8246 ;; Convert wide AND instructions with immediate operand to shorter QImode
8247 ;; equivalents when possible.
8248 ;; Don't do the splitting with memory operands, since it introduces risk
8249 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8250 ;; for size, but that can (should?) be handled by generic code instead.
8252 [(set (match_operand 0 "register_operand" "")
8253 (and (match_operand 1 "register_operand" "")
8254 (match_operand 2 "const_int_operand" "")))
8255 (clobber (reg:CC FLAGS_REG))]
8257 && QI_REG_P (operands[0])
8258 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8259 && !(~INTVAL (operands[2]) & ~(255 << 8))
8260 && GET_MODE (operands[0]) != QImode"
8261 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8262 (and:SI (zero_extract:SI (match_dup 1)
8263 (const_int 8) (const_int 8))
8265 (clobber (reg:CC FLAGS_REG))])]
8266 "operands[0] = gen_lowpart (SImode, operands[0]);
8267 operands[1] = gen_lowpart (SImode, operands[1]);
8268 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8270 ;; Since AND can be encoded with sign extended immediate, this is only
8271 ;; profitable when 7th bit is not set.
8273 [(set (match_operand 0 "register_operand" "")
8274 (and (match_operand 1 "general_operand" "")
8275 (match_operand 2 "const_int_operand" "")))
8276 (clobber (reg:CC FLAGS_REG))]
8278 && ANY_QI_REG_P (operands[0])
8279 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8280 && !(~INTVAL (operands[2]) & ~255)
8281 && !(INTVAL (operands[2]) & 128)
8282 && GET_MODE (operands[0]) != QImode"
8283 [(parallel [(set (strict_low_part (match_dup 0))
8284 (and:QI (match_dup 1)
8286 (clobber (reg:CC FLAGS_REG))])]
8287 "operands[0] = gen_lowpart (QImode, operands[0]);
8288 operands[1] = gen_lowpart (QImode, operands[1]);
8289 operands[2] = gen_lowpart (QImode, operands[2]);")
8291 ;; Logical inclusive and exclusive OR instructions
8293 ;; %%% This used to optimize known byte-wide and operations to memory.
8294 ;; If this is considered useful, it should be done with splitters.
8296 (define_expand "<code><mode>3"
8297 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8298 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8299 (match_operand:SWIM 2 "<general_operand>" "")))]
8301 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8303 (define_insn "*<code><mode>_1"
8304 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8306 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8307 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8308 (clobber (reg:CC FLAGS_REG))]
8309 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8310 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8311 [(set_attr "type" "alu")
8312 (set_attr "mode" "<MODE>")])
8314 ;; %%% Potential partial reg stall on alternative 2. What to do?
8315 (define_insn "*<code>qi_1"
8316 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8317 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8318 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8319 (clobber (reg:CC FLAGS_REG))]
8320 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8322 <logic>{b}\t{%2, %0|%0, %2}
8323 <logic>{b}\t{%2, %0|%0, %2}
8324 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8325 [(set_attr "type" "alu")
8326 (set_attr "mode" "QI,QI,SI")])
8328 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8329 (define_insn "*<code>si_1_zext"
8330 [(set (match_operand:DI 0 "register_operand" "=r")
8332 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8333 (match_operand:SI 2 "general_operand" "g"))))
8334 (clobber (reg:CC FLAGS_REG))]
8335 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8336 "<logic>{l}\t{%2, %k0|%k0, %2}"
8337 [(set_attr "type" "alu")
8338 (set_attr "mode" "SI")])
8340 (define_insn "*<code>si_1_zext_imm"
8341 [(set (match_operand:DI 0 "register_operand" "=r")
8343 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8344 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8345 (clobber (reg:CC FLAGS_REG))]
8346 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8347 "<logic>{l}\t{%2, %k0|%k0, %2}"
8348 [(set_attr "type" "alu")
8349 (set_attr "mode" "SI")])
8351 (define_insn "*<code>qi_1_slp"
8352 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8353 (any_or:QI (match_dup 0)
8354 (match_operand:QI 1 "general_operand" "qmn,qn")))
8355 (clobber (reg:CC FLAGS_REG))]
8356 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8357 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8358 "<logic>{b}\t{%1, %0|%0, %1}"
8359 [(set_attr "type" "alu1")
8360 (set_attr "mode" "QI")])
8362 (define_insn "*<code><mode>_2"
8363 [(set (reg FLAGS_REG)
8364 (compare (any_or:SWI
8365 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8366 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8368 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8369 (any_or:SWI (match_dup 1) (match_dup 2)))]
8370 "ix86_match_ccmode (insn, CCNOmode)
8371 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8372 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8373 [(set_attr "type" "alu")
8374 (set_attr "mode" "<MODE>")])
8376 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8377 ;; ??? Special case for immediate operand is missing - it is tricky.
8378 (define_insn "*<code>si_2_zext"
8379 [(set (reg FLAGS_REG)
8380 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8381 (match_operand:SI 2 "general_operand" "g"))
8383 (set (match_operand:DI 0 "register_operand" "=r")
8384 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8385 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8386 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8387 "<logic>{l}\t{%2, %k0|%k0, %2}"
8388 [(set_attr "type" "alu")
8389 (set_attr "mode" "SI")])
8391 (define_insn "*<code>si_2_zext_imm"
8392 [(set (reg FLAGS_REG)
8394 (match_operand:SI 1 "nonimmediate_operand" "%0")
8395 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8397 (set (match_operand:DI 0 "register_operand" "=r")
8398 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8399 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8400 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8401 "<logic>{l}\t{%2, %k0|%k0, %2}"
8402 [(set_attr "type" "alu")
8403 (set_attr "mode" "SI")])
8405 (define_insn "*<code>qi_2_slp"
8406 [(set (reg FLAGS_REG)
8407 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8408 (match_operand:QI 1 "general_operand" "qmn,qn"))
8410 (set (strict_low_part (match_dup 0))
8411 (any_or:QI (match_dup 0) (match_dup 1)))]
8412 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8413 && ix86_match_ccmode (insn, CCNOmode)
8414 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8415 "<logic>{b}\t{%1, %0|%0, %1}"
8416 [(set_attr "type" "alu1")
8417 (set_attr "mode" "QI")])
8419 (define_insn "*<code><mode>_3"
8420 [(set (reg FLAGS_REG)
8421 (compare (any_or:SWI
8422 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8423 (match_operand:SWI 2 "<general_operand>" "<g>"))
8425 (clobber (match_scratch:SWI 0 "=<r>"))]
8426 "ix86_match_ccmode (insn, CCNOmode)
8427 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8428 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8429 [(set_attr "type" "alu")
8430 (set_attr "mode" "<MODE>")])
8432 (define_insn "*<code>qi_ext_0"
8433 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8438 (match_operand 1 "ext_register_operand" "0")
8441 (match_operand 2 "const_int_operand" "n")))
8442 (clobber (reg:CC FLAGS_REG))]
8443 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8444 "<logic>{b}\t{%2, %h0|%h0, %2}"
8445 [(set_attr "type" "alu")
8446 (set_attr "length_immediate" "1")
8447 (set_attr "modrm" "1")
8448 (set_attr "mode" "QI")])
8450 (define_insn "*<code>qi_ext_1_rex64"
8451 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8456 (match_operand 1 "ext_register_operand" "0")
8460 (match_operand 2 "ext_register_operand" "Q"))))
8461 (clobber (reg:CC FLAGS_REG))]
8463 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8464 "<logic>{b}\t{%2, %h0|%h0, %2}"
8465 [(set_attr "type" "alu")
8466 (set_attr "length_immediate" "0")
8467 (set_attr "mode" "QI")])
8469 (define_insn "*<code>qi_ext_1"
8470 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8475 (match_operand 1 "ext_register_operand" "0")
8479 (match_operand:QI 2 "general_operand" "Qm"))))
8480 (clobber (reg:CC FLAGS_REG))]
8482 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8483 "<logic>{b}\t{%2, %h0|%h0, %2}"
8484 [(set_attr "type" "alu")
8485 (set_attr "length_immediate" "0")
8486 (set_attr "mode" "QI")])
8488 (define_insn "*<code>qi_ext_2"
8489 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8493 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8496 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8499 (clobber (reg:CC FLAGS_REG))]
8500 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8501 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8502 [(set_attr "type" "alu")
8503 (set_attr "length_immediate" "0")
8504 (set_attr "mode" "QI")])
8507 [(set (match_operand 0 "register_operand" "")
8508 (any_or (match_operand 1 "register_operand" "")
8509 (match_operand 2 "const_int_operand" "")))
8510 (clobber (reg:CC FLAGS_REG))]
8512 && QI_REG_P (operands[0])
8513 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8514 && !(INTVAL (operands[2]) & ~(255 << 8))
8515 && GET_MODE (operands[0]) != QImode"
8516 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8517 (any_or:SI (zero_extract:SI (match_dup 1)
8518 (const_int 8) (const_int 8))
8520 (clobber (reg:CC FLAGS_REG))])]
8521 "operands[0] = gen_lowpart (SImode, operands[0]);
8522 operands[1] = gen_lowpart (SImode, operands[1]);
8523 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8525 ;; Since OR can be encoded with sign extended immediate, this is only
8526 ;; profitable when 7th bit is set.
8528 [(set (match_operand 0 "register_operand" "")
8529 (any_or (match_operand 1 "general_operand" "")
8530 (match_operand 2 "const_int_operand" "")))
8531 (clobber (reg:CC FLAGS_REG))]
8533 && ANY_QI_REG_P (operands[0])
8534 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8535 && !(INTVAL (operands[2]) & ~255)
8536 && (INTVAL (operands[2]) & 128)
8537 && GET_MODE (operands[0]) != QImode"
8538 [(parallel [(set (strict_low_part (match_dup 0))
8539 (any_or:QI (match_dup 1)
8541 (clobber (reg:CC FLAGS_REG))])]
8542 "operands[0] = gen_lowpart (QImode, operands[0]);
8543 operands[1] = gen_lowpart (QImode, operands[1]);
8544 operands[2] = gen_lowpart (QImode, operands[2]);")
8546 (define_expand "xorqi_cc_ext_1"
8548 (set (reg:CCNO FLAGS_REG)
8552 (match_operand 1 "ext_register_operand" "")
8555 (match_operand:QI 2 "general_operand" ""))
8557 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8567 (define_insn "*xorqi_cc_ext_1_rex64"
8568 [(set (reg FLAGS_REG)
8572 (match_operand 1 "ext_register_operand" "0")
8575 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8577 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8586 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8587 "xor{b}\t{%2, %h0|%h0, %2}"
8588 [(set_attr "type" "alu")
8589 (set_attr "modrm" "1")
8590 (set_attr "mode" "QI")])
8592 (define_insn "*xorqi_cc_ext_1"
8593 [(set (reg FLAGS_REG)
8597 (match_operand 1 "ext_register_operand" "0")
8600 (match_operand:QI 2 "general_operand" "qmn"))
8602 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8611 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8612 "xor{b}\t{%2, %h0|%h0, %2}"
8613 [(set_attr "type" "alu")
8614 (set_attr "modrm" "1")
8615 (set_attr "mode" "QI")])
8617 ;; Negation instructions
8619 (define_expand "neg<mode>2"
8620 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8621 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8623 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8625 (define_insn_and_split "*neg<dwi>2_doubleword"
8626 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8627 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8628 (clobber (reg:CC FLAGS_REG))]
8629 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8633 [(set (reg:CCZ FLAGS_REG)
8634 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8635 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8638 (plus:DWIH (match_dup 3)
8639 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8641 (clobber (reg:CC FLAGS_REG))])
8644 (neg:DWIH (match_dup 2)))
8645 (clobber (reg:CC FLAGS_REG))])]
8646 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8648 (define_insn "*neg<mode>2_1"
8649 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8650 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8651 (clobber (reg:CC FLAGS_REG))]
8652 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8653 "neg{<imodesuffix>}\t%0"
8654 [(set_attr "type" "negnot")
8655 (set_attr "mode" "<MODE>")])
8657 ;; Combine is quite creative about this pattern.
8658 (define_insn "*negsi2_1_zext"
8659 [(set (match_operand:DI 0 "register_operand" "=r")
8661 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8664 (clobber (reg:CC FLAGS_REG))]
8665 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8667 [(set_attr "type" "negnot")
8668 (set_attr "mode" "SI")])
8670 ;; The problem with neg is that it does not perform (compare x 0),
8671 ;; it really performs (compare 0 x), which leaves us with the zero
8672 ;; flag being the only useful item.
8674 (define_insn "*neg<mode>2_cmpz"
8675 [(set (reg:CCZ FLAGS_REG)
8677 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8679 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8680 (neg:SWI (match_dup 1)))]
8681 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8682 "neg{<imodesuffix>}\t%0"
8683 [(set_attr "type" "negnot")
8684 (set_attr "mode" "<MODE>")])
8686 (define_insn "*negsi2_cmpz_zext"
8687 [(set (reg:CCZ FLAGS_REG)
8691 (match_operand:DI 1 "register_operand" "0")
8695 (set (match_operand:DI 0 "register_operand" "=r")
8696 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8699 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8701 [(set_attr "type" "negnot")
8702 (set_attr "mode" "SI")])
8704 ;; Changing of sign for FP values is doable using integer unit too.
8706 (define_expand "<code><mode>2"
8707 [(set (match_operand:X87MODEF 0 "register_operand" "")
8708 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8709 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8710 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8712 (define_insn "*absneg<mode>2_mixed"
8713 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8714 (match_operator:MODEF 3 "absneg_operator"
8715 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8716 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8721 (define_insn "*absneg<mode>2_sse"
8722 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8723 (match_operator:MODEF 3 "absneg_operator"
8724 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8725 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8726 (clobber (reg:CC FLAGS_REG))]
8727 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8730 (define_insn "*absneg<mode>2_i387"
8731 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8732 (match_operator:X87MODEF 3 "absneg_operator"
8733 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8734 (use (match_operand 2 "" ""))
8735 (clobber (reg:CC FLAGS_REG))]
8736 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8739 (define_expand "<code>tf2"
8740 [(set (match_operand:TF 0 "register_operand" "")
8741 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8743 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8745 (define_insn "*absnegtf2_sse"
8746 [(set (match_operand:TF 0 "register_operand" "=x,x")
8747 (match_operator:TF 3 "absneg_operator"
8748 [(match_operand:TF 1 "register_operand" "0,x")]))
8749 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8750 (clobber (reg:CC FLAGS_REG))]
8754 ;; Splitters for fp abs and neg.
8757 [(set (match_operand 0 "fp_register_operand" "")
8758 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8759 (use (match_operand 2 "" ""))
8760 (clobber (reg:CC FLAGS_REG))]
8762 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8765 [(set (match_operand 0 "register_operand" "")
8766 (match_operator 3 "absneg_operator"
8767 [(match_operand 1 "register_operand" "")]))
8768 (use (match_operand 2 "nonimmediate_operand" ""))
8769 (clobber (reg:CC FLAGS_REG))]
8770 "reload_completed && SSE_REG_P (operands[0])"
8771 [(set (match_dup 0) (match_dup 3))]
8773 enum machine_mode mode = GET_MODE (operands[0]);
8774 enum machine_mode vmode = GET_MODE (operands[2]);
8777 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8778 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8779 if (operands_match_p (operands[0], operands[2]))
8782 operands[1] = operands[2];
8785 if (GET_CODE (operands[3]) == ABS)
8786 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8788 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8793 [(set (match_operand:SF 0 "register_operand" "")
8794 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8795 (use (match_operand:V4SF 2 "" ""))
8796 (clobber (reg:CC FLAGS_REG))]
8798 [(parallel [(set (match_dup 0) (match_dup 1))
8799 (clobber (reg:CC FLAGS_REG))])]
8802 operands[0] = gen_lowpart (SImode, operands[0]);
8803 if (GET_CODE (operands[1]) == ABS)
8805 tmp = gen_int_mode (0x7fffffff, SImode);
8806 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8810 tmp = gen_int_mode (0x80000000, SImode);
8811 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8817 [(set (match_operand:DF 0 "register_operand" "")
8818 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8819 (use (match_operand 2 "" ""))
8820 (clobber (reg:CC FLAGS_REG))]
8822 [(parallel [(set (match_dup 0) (match_dup 1))
8823 (clobber (reg:CC FLAGS_REG))])]
8828 tmp = gen_lowpart (DImode, operands[0]);
8829 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8832 if (GET_CODE (operands[1]) == ABS)
8835 tmp = gen_rtx_NOT (DImode, tmp);
8839 operands[0] = gen_highpart (SImode, operands[0]);
8840 if (GET_CODE (operands[1]) == ABS)
8842 tmp = gen_int_mode (0x7fffffff, SImode);
8843 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8847 tmp = gen_int_mode (0x80000000, SImode);
8848 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8855 [(set (match_operand:XF 0 "register_operand" "")
8856 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8857 (use (match_operand 2 "" ""))
8858 (clobber (reg:CC FLAGS_REG))]
8860 [(parallel [(set (match_dup 0) (match_dup 1))
8861 (clobber (reg:CC FLAGS_REG))])]
8864 operands[0] = gen_rtx_REG (SImode,
8865 true_regnum (operands[0])
8866 + (TARGET_64BIT ? 1 : 2));
8867 if (GET_CODE (operands[1]) == ABS)
8869 tmp = GEN_INT (0x7fff);
8870 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8874 tmp = GEN_INT (0x8000);
8875 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8880 ;; Conditionalize these after reload. If they match before reload, we
8881 ;; lose the clobber and ability to use integer instructions.
8883 (define_insn "*<code><mode>2_1"
8884 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8885 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8887 && (reload_completed
8888 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8889 "f<absneg_mnemonic>"
8890 [(set_attr "type" "fsgn")
8891 (set_attr "mode" "<MODE>")])
8893 (define_insn "*<code>extendsfdf2"
8894 [(set (match_operand:DF 0 "register_operand" "=f")
8895 (absneg:DF (float_extend:DF
8896 (match_operand:SF 1 "register_operand" "0"))))]
8897 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8898 "f<absneg_mnemonic>"
8899 [(set_attr "type" "fsgn")
8900 (set_attr "mode" "DF")])
8902 (define_insn "*<code>extendsfxf2"
8903 [(set (match_operand:XF 0 "register_operand" "=f")
8904 (absneg:XF (float_extend:XF
8905 (match_operand:SF 1 "register_operand" "0"))))]
8907 "f<absneg_mnemonic>"
8908 [(set_attr "type" "fsgn")
8909 (set_attr "mode" "XF")])
8911 (define_insn "*<code>extenddfxf2"
8912 [(set (match_operand:XF 0 "register_operand" "=f")
8913 (absneg:XF (float_extend:XF
8914 (match_operand:DF 1 "register_operand" "0"))))]
8916 "f<absneg_mnemonic>"
8917 [(set_attr "type" "fsgn")
8918 (set_attr "mode" "XF")])
8920 ;; Copysign instructions
8922 (define_mode_iterator CSGNMODE [SF DF TF])
8923 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8925 (define_expand "copysign<mode>3"
8926 [(match_operand:CSGNMODE 0 "register_operand" "")
8927 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8928 (match_operand:CSGNMODE 2 "register_operand" "")]
8929 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8930 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8931 "ix86_expand_copysign (operands); DONE;")
8933 (define_insn_and_split "copysign<mode>3_const"
8934 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8936 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8937 (match_operand:CSGNMODE 2 "register_operand" "0")
8938 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8940 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8941 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8943 "&& reload_completed"
8945 "ix86_split_copysign_const (operands); DONE;")
8947 (define_insn "copysign<mode>3_var"
8948 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8950 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8951 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8952 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8953 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8955 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8956 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8957 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8961 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8963 [(match_operand:CSGNMODE 2 "register_operand" "")
8964 (match_operand:CSGNMODE 3 "register_operand" "")
8965 (match_operand:<CSGNVMODE> 4 "" "")
8966 (match_operand:<CSGNVMODE> 5 "" "")]
8968 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8969 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8970 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8971 && reload_completed"
8973 "ix86_split_copysign_var (operands); DONE;")
8975 ;; One complement instructions
8977 (define_expand "one_cmpl<mode>2"
8978 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8979 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8981 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8983 (define_insn "*one_cmpl<mode>2_1"
8984 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8985 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8986 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8987 "not{<imodesuffix>}\t%0"
8988 [(set_attr "type" "negnot")
8989 (set_attr "mode" "<MODE>")])
8991 ;; %%% Potential partial reg stall on alternative 1. What to do?
8992 (define_insn "*one_cmplqi2_1"
8993 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8994 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8995 "ix86_unary_operator_ok (NOT, QImode, operands)"
8999 [(set_attr "type" "negnot")
9000 (set_attr "mode" "QI,SI")])
9002 ;; ??? Currently never generated - xor is used instead.
9003 (define_insn "*one_cmplsi2_1_zext"
9004 [(set (match_operand:DI 0 "register_operand" "=r")
9006 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9007 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9009 [(set_attr "type" "negnot")
9010 (set_attr "mode" "SI")])
9012 (define_insn "*one_cmpl<mode>2_2"
9013 [(set (reg FLAGS_REG)
9014 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9016 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9017 (not:SWI (match_dup 1)))]
9018 "ix86_match_ccmode (insn, CCNOmode)
9019 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9021 [(set_attr "type" "alu1")
9022 (set_attr "mode" "<MODE>")])
9025 [(set (match_operand 0 "flags_reg_operand" "")
9026 (match_operator 2 "compare_operator"
9027 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9029 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9030 (not:SWI (match_dup 3)))]
9031 "ix86_match_ccmode (insn, CCNOmode)"
9032 [(parallel [(set (match_dup 0)
9033 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9036 (xor:SWI (match_dup 3) (const_int -1)))])])
9038 ;; ??? Currently never generated - xor is used instead.
9039 (define_insn "*one_cmplsi2_2_zext"
9040 [(set (reg FLAGS_REG)
9041 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9043 (set (match_operand:DI 0 "register_operand" "=r")
9044 (zero_extend:DI (not:SI (match_dup 1))))]
9045 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9046 && ix86_unary_operator_ok (NOT, SImode, operands)"
9048 [(set_attr "type" "alu1")
9049 (set_attr "mode" "SI")])
9052 [(set (match_operand 0 "flags_reg_operand" "")
9053 (match_operator 2 "compare_operator"
9054 [(not:SI (match_operand:SI 3 "register_operand" ""))
9056 (set (match_operand:DI 1 "register_operand" "")
9057 (zero_extend:DI (not:SI (match_dup 3))))]
9058 "ix86_match_ccmode (insn, CCNOmode)"
9059 [(parallel [(set (match_dup 0)
9060 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9063 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9065 ;; Shift instructions
9067 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9068 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9069 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9070 ;; from the assembler input.
9072 ;; This instruction shifts the target reg/mem as usual, but instead of
9073 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9074 ;; is a left shift double, bits are taken from the high order bits of
9075 ;; reg, else if the insn is a shift right double, bits are taken from the
9076 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9077 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9079 ;; Since sh[lr]d does not change the `reg' operand, that is done
9080 ;; separately, making all shifts emit pairs of shift double and normal
9081 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9082 ;; support a 63 bit shift, each shift where the count is in a reg expands
9083 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9085 ;; If the shift count is a constant, we need never emit more than one
9086 ;; shift pair, instead using moves and sign extension for counts greater
9089 (define_expand "ashl<mode>3"
9090 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9091 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9092 (match_operand:QI 2 "nonmemory_operand" "")))]
9094 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9096 (define_insn "*ashl<mode>3_doubleword"
9097 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9098 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9099 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9100 (clobber (reg:CC FLAGS_REG))]
9103 [(set_attr "type" "multi")])
9106 [(set (match_operand:DWI 0 "register_operand" "")
9107 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9108 (match_operand:QI 2 "nonmemory_operand" "")))
9109 (clobber (reg:CC FLAGS_REG))]
9110 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9112 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9114 ;; By default we don't ask for a scratch register, because when DWImode
9115 ;; values are manipulated, registers are already at a premium. But if
9116 ;; we have one handy, we won't turn it away.
9119 [(match_scratch:DWIH 3 "r")
9120 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9122 (match_operand:<DWI> 1 "nonmemory_operand" "")
9123 (match_operand:QI 2 "nonmemory_operand" "")))
9124 (clobber (reg:CC FLAGS_REG))])
9128 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9130 (define_insn "x86_64_shld"
9131 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9132 (ior:DI (ashift:DI (match_dup 0)
9133 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9134 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9135 (minus:QI (const_int 64) (match_dup 2)))))
9136 (clobber (reg:CC FLAGS_REG))]
9138 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9139 [(set_attr "type" "ishift")
9140 (set_attr "prefix_0f" "1")
9141 (set_attr "mode" "DI")
9142 (set_attr "athlon_decode" "vector")
9143 (set_attr "amdfam10_decode" "vector")
9144 (set_attr "bdver1_decode" "vector")])
9146 (define_insn "x86_shld"
9147 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9148 (ior:SI (ashift:SI (match_dup 0)
9149 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9150 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9151 (minus:QI (const_int 32) (match_dup 2)))))
9152 (clobber (reg:CC FLAGS_REG))]
9154 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9155 [(set_attr "type" "ishift")
9156 (set_attr "prefix_0f" "1")
9157 (set_attr "mode" "SI")
9158 (set_attr "pent_pair" "np")
9159 (set_attr "athlon_decode" "vector")
9160 (set_attr "amdfam10_decode" "vector")
9161 (set_attr "bdver1_decode" "vector")])
9163 (define_expand "x86_shift<mode>_adj_1"
9164 [(set (reg:CCZ FLAGS_REG)
9165 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9168 (set (match_operand:SWI48 0 "register_operand" "")
9169 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9170 (match_operand:SWI48 1 "register_operand" "")
9173 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9174 (match_operand:SWI48 3 "register_operand" "r")
9177 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9179 (define_expand "x86_shift<mode>_adj_2"
9180 [(use (match_operand:SWI48 0 "register_operand" ""))
9181 (use (match_operand:SWI48 1 "register_operand" ""))
9182 (use (match_operand:QI 2 "register_operand" ""))]
9185 rtx label = gen_label_rtx ();
9188 emit_insn (gen_testqi_ccz_1 (operands[2],
9189 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9191 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9192 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9193 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9194 gen_rtx_LABEL_REF (VOIDmode, label),
9196 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9197 JUMP_LABEL (tmp) = label;
9199 emit_move_insn (operands[0], operands[1]);
9200 ix86_expand_clear (operands[1]);
9203 LABEL_NUSES (label) = 1;
9208 ;; Avoid useless masking of count operand.
9209 (define_insn_and_split "*ashl<mode>3_mask"
9210 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9212 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9215 (match_operand:SI 2 "nonimmediate_operand" "c")
9216 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9217 (clobber (reg:CC FLAGS_REG))]
9218 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9219 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9220 == GET_MODE_BITSIZE (<MODE>mode)-1"
9223 [(parallel [(set (match_dup 0)
9224 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9225 (clobber (reg:CC FLAGS_REG))])]
9227 if (can_create_pseudo_p ())
9228 operands [2] = force_reg (SImode, operands[2]);
9230 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9232 [(set_attr "type" "ishift")
9233 (set_attr "mode" "<MODE>")])
9235 (define_insn "*ashl<mode>3_1"
9236 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9237 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9238 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9239 (clobber (reg:CC FLAGS_REG))]
9240 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9242 switch (get_attr_type (insn))
9248 gcc_assert (operands[2] == const1_rtx);
9249 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9250 return "add{<imodesuffix>}\t%0, %0";
9253 if (operands[2] == const1_rtx
9254 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9255 return "sal{<imodesuffix>}\t%0";
9257 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9261 (cond [(eq_attr "alternative" "1")
9262 (const_string "lea")
9263 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9265 (match_operand 0 "register_operand" ""))
9266 (match_operand 2 "const1_operand" ""))
9267 (const_string "alu")
9269 (const_string "ishift")))
9270 (set (attr "length_immediate")
9272 (ior (eq_attr "type" "alu")
9273 (and (eq_attr "type" "ishift")
9274 (and (match_operand 2 "const1_operand" "")
9275 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9278 (const_string "*")))
9279 (set_attr "mode" "<MODE>")])
9281 (define_insn "*ashlsi3_1_zext"
9282 [(set (match_operand:DI 0 "register_operand" "=r,r")
9284 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9285 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9286 (clobber (reg:CC FLAGS_REG))]
9287 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9289 switch (get_attr_type (insn))
9295 gcc_assert (operands[2] == const1_rtx);
9296 return "add{l}\t%k0, %k0";
9299 if (operands[2] == const1_rtx
9300 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9301 return "sal{l}\t%k0";
9303 return "sal{l}\t{%2, %k0|%k0, %2}";
9307 (cond [(eq_attr "alternative" "1")
9308 (const_string "lea")
9309 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9311 (match_operand 2 "const1_operand" ""))
9312 (const_string "alu")
9314 (const_string "ishift")))
9315 (set (attr "length_immediate")
9317 (ior (eq_attr "type" "alu")
9318 (and (eq_attr "type" "ishift")
9319 (and (match_operand 2 "const1_operand" "")
9320 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9323 (const_string "*")))
9324 (set_attr "mode" "SI")])
9326 (define_insn "*ashlhi3_1"
9327 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9328 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9329 (match_operand:QI 2 "nonmemory_operand" "cI")))
9330 (clobber (reg:CC FLAGS_REG))]
9331 "TARGET_PARTIAL_REG_STALL
9332 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9334 switch (get_attr_type (insn))
9337 gcc_assert (operands[2] == const1_rtx);
9338 return "add{w}\t%0, %0";
9341 if (operands[2] == const1_rtx
9342 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9343 return "sal{w}\t%0";
9345 return "sal{w}\t{%2, %0|%0, %2}";
9349 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9351 (match_operand 0 "register_operand" ""))
9352 (match_operand 2 "const1_operand" ""))
9353 (const_string "alu")
9355 (const_string "ishift")))
9356 (set (attr "length_immediate")
9358 (ior (eq_attr "type" "alu")
9359 (and (eq_attr "type" "ishift")
9360 (and (match_operand 2 "const1_operand" "")
9361 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9364 (const_string "*")))
9365 (set_attr "mode" "HI")])
9367 (define_insn "*ashlhi3_1_lea"
9368 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9369 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9370 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9371 (clobber (reg:CC FLAGS_REG))]
9372 "!TARGET_PARTIAL_REG_STALL
9373 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9375 switch (get_attr_type (insn))
9381 gcc_assert (operands[2] == const1_rtx);
9382 return "add{w}\t%0, %0";
9385 if (operands[2] == const1_rtx
9386 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9387 return "sal{w}\t%0";
9389 return "sal{w}\t{%2, %0|%0, %2}";
9393 (cond [(eq_attr "alternative" "1")
9394 (const_string "lea")
9395 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9397 (match_operand 0 "register_operand" ""))
9398 (match_operand 2 "const1_operand" ""))
9399 (const_string "alu")
9401 (const_string "ishift")))
9402 (set (attr "length_immediate")
9404 (ior (eq_attr "type" "alu")
9405 (and (eq_attr "type" "ishift")
9406 (and (match_operand 2 "const1_operand" "")
9407 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9410 (const_string "*")))
9411 (set_attr "mode" "HI,SI")])
9413 (define_insn "*ashlqi3_1"
9414 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9415 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9416 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9417 (clobber (reg:CC FLAGS_REG))]
9418 "TARGET_PARTIAL_REG_STALL
9419 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9421 switch (get_attr_type (insn))
9424 gcc_assert (operands[2] == const1_rtx);
9425 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9426 return "add{l}\t%k0, %k0";
9428 return "add{b}\t%0, %0";
9431 if (operands[2] == const1_rtx
9432 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9434 if (get_attr_mode (insn) == MODE_SI)
9435 return "sal{l}\t%k0";
9437 return "sal{b}\t%0";
9441 if (get_attr_mode (insn) == MODE_SI)
9442 return "sal{l}\t{%2, %k0|%k0, %2}";
9444 return "sal{b}\t{%2, %0|%0, %2}";
9449 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9451 (match_operand 0 "register_operand" ""))
9452 (match_operand 2 "const1_operand" ""))
9453 (const_string "alu")
9455 (const_string "ishift")))
9456 (set (attr "length_immediate")
9458 (ior (eq_attr "type" "alu")
9459 (and (eq_attr "type" "ishift")
9460 (and (match_operand 2 "const1_operand" "")
9461 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9464 (const_string "*")))
9465 (set_attr "mode" "QI,SI")])
9467 ;; %%% Potential partial reg stall on alternative 2. What to do?
9468 (define_insn "*ashlqi3_1_lea"
9469 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9470 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9471 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9472 (clobber (reg:CC FLAGS_REG))]
9473 "!TARGET_PARTIAL_REG_STALL
9474 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9476 switch (get_attr_type (insn))
9482 gcc_assert (operands[2] == const1_rtx);
9483 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9484 return "add{l}\t%k0, %k0";
9486 return "add{b}\t%0, %0";
9489 if (operands[2] == const1_rtx
9490 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9492 if (get_attr_mode (insn) == MODE_SI)
9493 return "sal{l}\t%k0";
9495 return "sal{b}\t%0";
9499 if (get_attr_mode (insn) == MODE_SI)
9500 return "sal{l}\t{%2, %k0|%k0, %2}";
9502 return "sal{b}\t{%2, %0|%0, %2}";
9507 (cond [(eq_attr "alternative" "2")
9508 (const_string "lea")
9509 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9511 (match_operand 0 "register_operand" ""))
9512 (match_operand 2 "const1_operand" ""))
9513 (const_string "alu")
9515 (const_string "ishift")))
9516 (set (attr "length_immediate")
9518 (ior (eq_attr "type" "alu")
9519 (and (eq_attr "type" "ishift")
9520 (and (match_operand 2 "const1_operand" "")
9521 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9524 (const_string "*")))
9525 (set_attr "mode" "QI,SI,SI")])
9527 (define_insn "*ashlqi3_1_slp"
9528 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9529 (ashift:QI (match_dup 0)
9530 (match_operand:QI 1 "nonmemory_operand" "cI")))
9531 (clobber (reg:CC FLAGS_REG))]
9532 "(optimize_function_for_size_p (cfun)
9533 || !TARGET_PARTIAL_FLAG_REG_STALL
9534 || (operands[1] == const1_rtx
9536 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9538 switch (get_attr_type (insn))
9541 gcc_assert (operands[1] == const1_rtx);
9542 return "add{b}\t%0, %0";
9545 if (operands[1] == const1_rtx
9546 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9547 return "sal{b}\t%0";
9549 return "sal{b}\t{%1, %0|%0, %1}";
9553 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9555 (match_operand 0 "register_operand" ""))
9556 (match_operand 1 "const1_operand" ""))
9557 (const_string "alu")
9559 (const_string "ishift1")))
9560 (set (attr "length_immediate")
9562 (ior (eq_attr "type" "alu")
9563 (and (eq_attr "type" "ishift1")
9564 (and (match_operand 1 "const1_operand" "")
9565 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9568 (const_string "*")))
9569 (set_attr "mode" "QI")])
9571 ;; Convert lea to the lea pattern to avoid flags dependency.
9573 [(set (match_operand 0 "register_operand" "")
9574 (ashift (match_operand 1 "index_register_operand" "")
9575 (match_operand:QI 2 "const_int_operand" "")))
9576 (clobber (reg:CC FLAGS_REG))]
9578 && true_regnum (operands[0]) != true_regnum (operands[1])"
9582 enum machine_mode mode = GET_MODE (operands[0]);
9585 operands[1] = gen_lowpart (Pmode, operands[1]);
9586 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9588 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9590 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9591 operands[0] = gen_lowpart (SImode, operands[0]);
9593 if (TARGET_64BIT && mode != Pmode)
9594 pat = gen_rtx_SUBREG (SImode, pat, 0);
9596 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9600 ;; Convert lea to the lea pattern to avoid flags dependency.
9602 [(set (match_operand:DI 0 "register_operand" "")
9604 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9605 (match_operand:QI 2 "const_int_operand" ""))))
9606 (clobber (reg:CC FLAGS_REG))]
9607 "TARGET_64BIT && reload_completed
9608 && true_regnum (operands[0]) != true_regnum (operands[1])"
9610 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9612 operands[1] = gen_lowpart (DImode, operands[1]);
9613 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9616 ;; This pattern can't accept a variable shift count, since shifts by
9617 ;; zero don't affect the flags. We assume that shifts by constant
9618 ;; zero are optimized away.
9619 (define_insn "*ashl<mode>3_cmp"
9620 [(set (reg FLAGS_REG)
9622 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9623 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9625 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9626 (ashift:SWI (match_dup 1) (match_dup 2)))]
9627 "(optimize_function_for_size_p (cfun)
9628 || !TARGET_PARTIAL_FLAG_REG_STALL
9629 || (operands[2] == const1_rtx
9631 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9632 && ix86_match_ccmode (insn, CCGOCmode)
9633 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9635 switch (get_attr_type (insn))
9638 gcc_assert (operands[2] == const1_rtx);
9639 return "add{<imodesuffix>}\t%0, %0";
9642 if (operands[2] == const1_rtx
9643 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9644 return "sal{<imodesuffix>}\t%0";
9646 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9650 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9652 (match_operand 0 "register_operand" ""))
9653 (match_operand 2 "const1_operand" ""))
9654 (const_string "alu")
9656 (const_string "ishift")))
9657 (set (attr "length_immediate")
9659 (ior (eq_attr "type" "alu")
9660 (and (eq_attr "type" "ishift")
9661 (and (match_operand 2 "const1_operand" "")
9662 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9665 (const_string "*")))
9666 (set_attr "mode" "<MODE>")])
9668 (define_insn "*ashlsi3_cmp_zext"
9669 [(set (reg FLAGS_REG)
9671 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9672 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9674 (set (match_operand:DI 0 "register_operand" "=r")
9675 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9677 && (optimize_function_for_size_p (cfun)
9678 || !TARGET_PARTIAL_FLAG_REG_STALL
9679 || (operands[2] == const1_rtx
9681 || TARGET_DOUBLE_WITH_ADD)))
9682 && ix86_match_ccmode (insn, CCGOCmode)
9683 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9685 switch (get_attr_type (insn))
9688 gcc_assert (operands[2] == const1_rtx);
9689 return "add{l}\t%k0, %k0";
9692 if (operands[2] == const1_rtx
9693 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9694 return "sal{l}\t%k0";
9696 return "sal{l}\t{%2, %k0|%k0, %2}";
9700 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9702 (match_operand 2 "const1_operand" ""))
9703 (const_string "alu")
9705 (const_string "ishift")))
9706 (set (attr "length_immediate")
9708 (ior (eq_attr "type" "alu")
9709 (and (eq_attr "type" "ishift")
9710 (and (match_operand 2 "const1_operand" "")
9711 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9714 (const_string "*")))
9715 (set_attr "mode" "SI")])
9717 (define_insn "*ashl<mode>3_cconly"
9718 [(set (reg FLAGS_REG)
9720 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9721 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9723 (clobber (match_scratch:SWI 0 "=<r>"))]
9724 "(optimize_function_for_size_p (cfun)
9725 || !TARGET_PARTIAL_FLAG_REG_STALL
9726 || (operands[2] == const1_rtx
9728 || TARGET_DOUBLE_WITH_ADD)))
9729 && ix86_match_ccmode (insn, CCGOCmode)"
9731 switch (get_attr_type (insn))
9734 gcc_assert (operands[2] == const1_rtx);
9735 return "add{<imodesuffix>}\t%0, %0";
9738 if (operands[2] == const1_rtx
9739 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9740 return "sal{<imodesuffix>}\t%0";
9742 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9746 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9748 (match_operand 0 "register_operand" ""))
9749 (match_operand 2 "const1_operand" ""))
9750 (const_string "alu")
9752 (const_string "ishift")))
9753 (set (attr "length_immediate")
9755 (ior (eq_attr "type" "alu")
9756 (and (eq_attr "type" "ishift")
9757 (and (match_operand 2 "const1_operand" "")
9758 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9761 (const_string "*")))
9762 (set_attr "mode" "<MODE>")])
9764 ;; See comment above `ashl<mode>3' about how this works.
9766 (define_expand "<shiftrt_insn><mode>3"
9767 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9768 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9769 (match_operand:QI 2 "nonmemory_operand" "")))]
9771 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9773 ;; Avoid useless masking of count operand.
9774 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9775 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9777 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9780 (match_operand:SI 2 "nonimmediate_operand" "c")
9781 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9782 (clobber (reg:CC FLAGS_REG))]
9783 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9784 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9785 == GET_MODE_BITSIZE (<MODE>mode)-1"
9788 [(parallel [(set (match_dup 0)
9789 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9790 (clobber (reg:CC FLAGS_REG))])]
9792 if (can_create_pseudo_p ())
9793 operands [2] = force_reg (SImode, operands[2]);
9795 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9797 [(set_attr "type" "ishift")
9798 (set_attr "mode" "<MODE>")])
9800 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9801 [(set (match_operand:DWI 0 "register_operand" "=r")
9802 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9803 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9804 (clobber (reg:CC FLAGS_REG))]
9807 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9809 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9810 [(set_attr "type" "multi")])
9812 ;; By default we don't ask for a scratch register, because when DWImode
9813 ;; values are manipulated, registers are already at a premium. But if
9814 ;; we have one handy, we won't turn it away.
9817 [(match_scratch:DWIH 3 "r")
9818 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9820 (match_operand:<DWI> 1 "register_operand" "")
9821 (match_operand:QI 2 "nonmemory_operand" "")))
9822 (clobber (reg:CC FLAGS_REG))])
9826 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9828 (define_insn "x86_64_shrd"
9829 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9830 (ior:DI (ashiftrt:DI (match_dup 0)
9831 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9832 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9833 (minus:QI (const_int 64) (match_dup 2)))))
9834 (clobber (reg:CC FLAGS_REG))]
9836 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9837 [(set_attr "type" "ishift")
9838 (set_attr "prefix_0f" "1")
9839 (set_attr "mode" "DI")
9840 (set_attr "athlon_decode" "vector")
9841 (set_attr "amdfam10_decode" "vector")
9842 (set_attr "bdver1_decode" "vector")])
9844 (define_insn "x86_shrd"
9845 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9846 (ior:SI (ashiftrt:SI (match_dup 0)
9847 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9848 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9849 (minus:QI (const_int 32) (match_dup 2)))))
9850 (clobber (reg:CC FLAGS_REG))]
9852 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9853 [(set_attr "type" "ishift")
9854 (set_attr "prefix_0f" "1")
9855 (set_attr "mode" "SI")
9856 (set_attr "pent_pair" "np")
9857 (set_attr "athlon_decode" "vector")
9858 (set_attr "amdfam10_decode" "vector")
9859 (set_attr "bdver1_decode" "vector")])
9861 (define_insn "ashrdi3_cvt"
9862 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9863 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9864 (match_operand:QI 2 "const_int_operand" "")))
9865 (clobber (reg:CC FLAGS_REG))]
9866 "TARGET_64BIT && INTVAL (operands[2]) == 63
9867 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9868 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9871 sar{q}\t{%2, %0|%0, %2}"
9872 [(set_attr "type" "imovx,ishift")
9873 (set_attr "prefix_0f" "0,*")
9874 (set_attr "length_immediate" "0,*")
9875 (set_attr "modrm" "0,1")
9876 (set_attr "mode" "DI")])
9878 (define_insn "ashrsi3_cvt"
9879 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9880 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9881 (match_operand:QI 2 "const_int_operand" "")))
9882 (clobber (reg:CC FLAGS_REG))]
9883 "INTVAL (operands[2]) == 31
9884 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9885 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9888 sar{l}\t{%2, %0|%0, %2}"
9889 [(set_attr "type" "imovx,ishift")
9890 (set_attr "prefix_0f" "0,*")
9891 (set_attr "length_immediate" "0,*")
9892 (set_attr "modrm" "0,1")
9893 (set_attr "mode" "SI")])
9895 (define_insn "*ashrsi3_cvt_zext"
9896 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9898 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9899 (match_operand:QI 2 "const_int_operand" ""))))
9900 (clobber (reg:CC FLAGS_REG))]
9901 "TARGET_64BIT && INTVAL (operands[2]) == 31
9902 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9903 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9906 sar{l}\t{%2, %k0|%k0, %2}"
9907 [(set_attr "type" "imovx,ishift")
9908 (set_attr "prefix_0f" "0,*")
9909 (set_attr "length_immediate" "0,*")
9910 (set_attr "modrm" "0,1")
9911 (set_attr "mode" "SI")])
9913 (define_expand "x86_shift<mode>_adj_3"
9914 [(use (match_operand:SWI48 0 "register_operand" ""))
9915 (use (match_operand:SWI48 1 "register_operand" ""))
9916 (use (match_operand:QI 2 "register_operand" ""))]
9919 rtx label = gen_label_rtx ();
9922 emit_insn (gen_testqi_ccz_1 (operands[2],
9923 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9925 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9926 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9927 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9928 gen_rtx_LABEL_REF (VOIDmode, label),
9930 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9931 JUMP_LABEL (tmp) = label;
9933 emit_move_insn (operands[0], operands[1]);
9934 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9935 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9937 LABEL_NUSES (label) = 1;
9942 (define_insn "*<shiftrt_insn><mode>3_1"
9943 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9944 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9945 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9946 (clobber (reg:CC FLAGS_REG))]
9947 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9949 if (operands[2] == const1_rtx
9950 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9951 return "<shiftrt>{<imodesuffix>}\t%0";
9953 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9955 [(set_attr "type" "ishift")
9956 (set (attr "length_immediate")
9958 (and (match_operand 2 "const1_operand" "")
9959 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9962 (const_string "*")))
9963 (set_attr "mode" "<MODE>")])
9965 (define_insn "*<shiftrt_insn>si3_1_zext"
9966 [(set (match_operand:DI 0 "register_operand" "=r")
9968 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9969 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9970 (clobber (reg:CC FLAGS_REG))]
9971 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9973 if (operands[2] == const1_rtx
9974 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9975 return "<shiftrt>{l}\t%k0";
9977 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9979 [(set_attr "type" "ishift")
9980 (set (attr "length_immediate")
9982 (and (match_operand 2 "const1_operand" "")
9983 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9986 (const_string "*")))
9987 (set_attr "mode" "SI")])
9989 (define_insn "*<shiftrt_insn>qi3_1_slp"
9990 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9991 (any_shiftrt:QI (match_dup 0)
9992 (match_operand:QI 1 "nonmemory_operand" "cI")))
9993 (clobber (reg:CC FLAGS_REG))]
9994 "(optimize_function_for_size_p (cfun)
9995 || !TARGET_PARTIAL_REG_STALL
9996 || (operands[1] == const1_rtx
9999 if (operands[1] == const1_rtx
10000 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10001 return "<shiftrt>{b}\t%0";
10003 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10005 [(set_attr "type" "ishift1")
10006 (set (attr "length_immediate")
10008 (and (match_operand 1 "const1_operand" "")
10009 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10012 (const_string "*")))
10013 (set_attr "mode" "QI")])
10015 ;; This pattern can't accept a variable shift count, since shifts by
10016 ;; zero don't affect the flags. We assume that shifts by constant
10017 ;; zero are optimized away.
10018 (define_insn "*<shiftrt_insn><mode>3_cmp"
10019 [(set (reg FLAGS_REG)
10022 (match_operand:SWI 1 "nonimmediate_operand" "0")
10023 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10025 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10026 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10027 "(optimize_function_for_size_p (cfun)
10028 || !TARGET_PARTIAL_FLAG_REG_STALL
10029 || (operands[2] == const1_rtx
10031 && ix86_match_ccmode (insn, CCGOCmode)
10032 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10034 if (operands[2] == const1_rtx
10035 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10036 return "<shiftrt>{<imodesuffix>}\t%0";
10038 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10040 [(set_attr "type" "ishift")
10041 (set (attr "length_immediate")
10043 (and (match_operand 2 "const1_operand" "")
10044 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10047 (const_string "*")))
10048 (set_attr "mode" "<MODE>")])
10050 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10051 [(set (reg FLAGS_REG)
10053 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10054 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10056 (set (match_operand:DI 0 "register_operand" "=r")
10057 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10059 && (optimize_function_for_size_p (cfun)
10060 || !TARGET_PARTIAL_FLAG_REG_STALL
10061 || (operands[2] == const1_rtx
10063 && ix86_match_ccmode (insn, CCGOCmode)
10064 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10066 if (operands[2] == const1_rtx
10067 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10068 return "<shiftrt>{l}\t%k0";
10070 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10072 [(set_attr "type" "ishift")
10073 (set (attr "length_immediate")
10075 (and (match_operand 2 "const1_operand" "")
10076 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10079 (const_string "*")))
10080 (set_attr "mode" "SI")])
10082 (define_insn "*<shiftrt_insn><mode>3_cconly"
10083 [(set (reg FLAGS_REG)
10086 (match_operand:SWI 1 "register_operand" "0")
10087 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10089 (clobber (match_scratch:SWI 0 "=<r>"))]
10090 "(optimize_function_for_size_p (cfun)
10091 || !TARGET_PARTIAL_FLAG_REG_STALL
10092 || (operands[2] == const1_rtx
10094 && ix86_match_ccmode (insn, CCGOCmode)"
10096 if (operands[2] == const1_rtx
10097 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10098 return "<shiftrt>{<imodesuffix>}\t%0";
10100 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10102 [(set_attr "type" "ishift")
10103 (set (attr "length_immediate")
10105 (and (match_operand 2 "const1_operand" "")
10106 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10109 (const_string "*")))
10110 (set_attr "mode" "<MODE>")])
10112 ;; Rotate instructions
10114 (define_expand "<rotate_insn>ti3"
10115 [(set (match_operand:TI 0 "register_operand" "")
10116 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10117 (match_operand:QI 2 "nonmemory_operand" "")))]
10120 if (const_1_to_63_operand (operands[2], VOIDmode))
10121 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10122 (operands[0], operands[1], operands[2]));
10129 (define_expand "<rotate_insn>di3"
10130 [(set (match_operand:DI 0 "shiftdi_operand" "")
10131 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10132 (match_operand:QI 2 "nonmemory_operand" "")))]
10136 ix86_expand_binary_operator (<CODE>, DImode, operands);
10137 else if (const_1_to_31_operand (operands[2], VOIDmode))
10138 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10139 (operands[0], operands[1], operands[2]));
10146 (define_expand "<rotate_insn><mode>3"
10147 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10148 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10149 (match_operand:QI 2 "nonmemory_operand" "")))]
10151 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10153 ;; Avoid useless masking of count operand.
10154 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10155 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10157 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10160 (match_operand:SI 2 "nonimmediate_operand" "c")
10161 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10162 (clobber (reg:CC FLAGS_REG))]
10163 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10164 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10165 == GET_MODE_BITSIZE (<MODE>mode)-1"
10168 [(parallel [(set (match_dup 0)
10169 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10170 (clobber (reg:CC FLAGS_REG))])]
10172 if (can_create_pseudo_p ())
10173 operands [2] = force_reg (SImode, operands[2]);
10175 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10177 [(set_attr "type" "rotate")
10178 (set_attr "mode" "<MODE>")])
10180 ;; Implement rotation using two double-precision
10181 ;; shift instructions and a scratch register.
10183 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10184 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10185 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10186 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10187 (clobber (reg:CC FLAGS_REG))
10188 (clobber (match_scratch:DWIH 3 "=&r"))]
10192 [(set (match_dup 3) (match_dup 4))
10194 [(set (match_dup 4)
10195 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10196 (lshiftrt:DWIH (match_dup 5)
10197 (minus:QI (match_dup 6) (match_dup 2)))))
10198 (clobber (reg:CC FLAGS_REG))])
10200 [(set (match_dup 5)
10201 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10202 (lshiftrt:DWIH (match_dup 3)
10203 (minus:QI (match_dup 6) (match_dup 2)))))
10204 (clobber (reg:CC FLAGS_REG))])]
10206 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10208 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10211 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10212 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10213 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10214 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10215 (clobber (reg:CC FLAGS_REG))
10216 (clobber (match_scratch:DWIH 3 "=&r"))]
10220 [(set (match_dup 3) (match_dup 4))
10222 [(set (match_dup 4)
10223 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10224 (ashift:DWIH (match_dup 5)
10225 (minus:QI (match_dup 6) (match_dup 2)))))
10226 (clobber (reg:CC FLAGS_REG))])
10228 [(set (match_dup 5)
10229 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10230 (ashift:DWIH (match_dup 3)
10231 (minus:QI (match_dup 6) (match_dup 2)))))
10232 (clobber (reg:CC FLAGS_REG))])]
10234 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10236 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10239 (define_insn "*<rotate_insn><mode>3_1"
10240 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10241 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10242 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10243 (clobber (reg:CC FLAGS_REG))]
10244 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10246 if (operands[2] == const1_rtx
10247 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10248 return "<rotate>{<imodesuffix>}\t%0";
10250 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10252 [(set_attr "type" "rotate")
10253 (set (attr "length_immediate")
10255 (and (match_operand 2 "const1_operand" "")
10256 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10259 (const_string "*")))
10260 (set_attr "mode" "<MODE>")])
10262 (define_insn "*<rotate_insn>si3_1_zext"
10263 [(set (match_operand:DI 0 "register_operand" "=r")
10265 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10266 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10267 (clobber (reg:CC FLAGS_REG))]
10268 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10270 if (operands[2] == const1_rtx
10271 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10272 return "<rotate>{l}\t%k0";
10274 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10276 [(set_attr "type" "rotate")
10277 (set (attr "length_immediate")
10279 (and (match_operand 2 "const1_operand" "")
10280 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10283 (const_string "*")))
10284 (set_attr "mode" "SI")])
10286 (define_insn "*<rotate_insn>qi3_1_slp"
10287 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10288 (any_rotate:QI (match_dup 0)
10289 (match_operand:QI 1 "nonmemory_operand" "cI")))
10290 (clobber (reg:CC FLAGS_REG))]
10291 "(optimize_function_for_size_p (cfun)
10292 || !TARGET_PARTIAL_REG_STALL
10293 || (operands[1] == const1_rtx
10294 && TARGET_SHIFT1))"
10296 if (operands[1] == const1_rtx
10297 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10298 return "<rotate>{b}\t%0";
10300 return "<rotate>{b}\t{%1, %0|%0, %1}";
10302 [(set_attr "type" "rotate1")
10303 (set (attr "length_immediate")
10305 (and (match_operand 1 "const1_operand" "")
10306 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10309 (const_string "*")))
10310 (set_attr "mode" "QI")])
10313 [(set (match_operand:HI 0 "register_operand" "")
10314 (any_rotate:HI (match_dup 0) (const_int 8)))
10315 (clobber (reg:CC FLAGS_REG))]
10317 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10318 [(parallel [(set (strict_low_part (match_dup 0))
10319 (bswap:HI (match_dup 0)))
10320 (clobber (reg:CC FLAGS_REG))])])
10322 ;; Bit set / bit test instructions
10324 (define_expand "extv"
10325 [(set (match_operand:SI 0 "register_operand" "")
10326 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10327 (match_operand:SI 2 "const8_operand" "")
10328 (match_operand:SI 3 "const8_operand" "")))]
10331 /* Handle extractions from %ah et al. */
10332 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10335 /* From mips.md: extract_bit_field doesn't verify that our source
10336 matches the predicate, so check it again here. */
10337 if (! ext_register_operand (operands[1], VOIDmode))
10341 (define_expand "extzv"
10342 [(set (match_operand:SI 0 "register_operand" "")
10343 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10344 (match_operand:SI 2 "const8_operand" "")
10345 (match_operand:SI 3 "const8_operand" "")))]
10348 /* Handle extractions from %ah et al. */
10349 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10352 /* From mips.md: extract_bit_field doesn't verify that our source
10353 matches the predicate, so check it again here. */
10354 if (! ext_register_operand (operands[1], VOIDmode))
10358 (define_expand "insv"
10359 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10360 (match_operand 1 "const8_operand" "")
10361 (match_operand 2 "const8_operand" ""))
10362 (match_operand 3 "register_operand" ""))]
10365 rtx (*gen_mov_insv_1) (rtx, rtx);
10367 /* Handle insertions to %ah et al. */
10368 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10371 /* From mips.md: insert_bit_field doesn't verify that our source
10372 matches the predicate, so check it again here. */
10373 if (! ext_register_operand (operands[0], VOIDmode))
10376 gen_mov_insv_1 = (TARGET_64BIT
10377 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10379 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10383 ;; %%% bts, btr, btc, bt.
10384 ;; In general these instructions are *slow* when applied to memory,
10385 ;; since they enforce atomic operation. When applied to registers,
10386 ;; it depends on the cpu implementation. They're never faster than
10387 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10388 ;; no point. But in 64-bit, we can't hold the relevant immediates
10389 ;; within the instruction itself, so operating on bits in the high
10390 ;; 32-bits of a register becomes easier.
10392 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10393 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10394 ;; negdf respectively, so they can never be disabled entirely.
10396 (define_insn "*btsq"
10397 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10399 (match_operand:DI 1 "const_0_to_63_operand" ""))
10401 (clobber (reg:CC FLAGS_REG))]
10402 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10403 "bts{q}\t{%1, %0|%0, %1}"
10404 [(set_attr "type" "alu1")
10405 (set_attr "prefix_0f" "1")
10406 (set_attr "mode" "DI")])
10408 (define_insn "*btrq"
10409 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10411 (match_operand:DI 1 "const_0_to_63_operand" ""))
10413 (clobber (reg:CC FLAGS_REG))]
10414 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10415 "btr{q}\t{%1, %0|%0, %1}"
10416 [(set_attr "type" "alu1")
10417 (set_attr "prefix_0f" "1")
10418 (set_attr "mode" "DI")])
10420 (define_insn "*btcq"
10421 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10423 (match_operand:DI 1 "const_0_to_63_operand" ""))
10424 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10425 (clobber (reg:CC FLAGS_REG))]
10426 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10427 "btc{q}\t{%1, %0|%0, %1}"
10428 [(set_attr "type" "alu1")
10429 (set_attr "prefix_0f" "1")
10430 (set_attr "mode" "DI")])
10432 ;; Allow Nocona to avoid these instructions if a register is available.
10435 [(match_scratch:DI 2 "r")
10436 (parallel [(set (zero_extract:DI
10437 (match_operand:DI 0 "register_operand" "")
10439 (match_operand:DI 1 "const_0_to_63_operand" ""))
10441 (clobber (reg:CC FLAGS_REG))])]
10442 "TARGET_64BIT && !TARGET_USE_BT"
10445 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10448 if (HOST_BITS_PER_WIDE_INT >= 64)
10449 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10450 else if (i < HOST_BITS_PER_WIDE_INT)
10451 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10453 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10455 op1 = immed_double_const (lo, hi, DImode);
10458 emit_move_insn (operands[2], op1);
10462 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10467 [(match_scratch:DI 2 "r")
10468 (parallel [(set (zero_extract:DI
10469 (match_operand:DI 0 "register_operand" "")
10471 (match_operand:DI 1 "const_0_to_63_operand" ""))
10473 (clobber (reg:CC FLAGS_REG))])]
10474 "TARGET_64BIT && !TARGET_USE_BT"
10477 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10480 if (HOST_BITS_PER_WIDE_INT >= 64)
10481 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10482 else if (i < HOST_BITS_PER_WIDE_INT)
10483 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10485 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10487 op1 = immed_double_const (~lo, ~hi, DImode);
10490 emit_move_insn (operands[2], op1);
10494 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10499 [(match_scratch:DI 2 "r")
10500 (parallel [(set (zero_extract:DI
10501 (match_operand:DI 0 "register_operand" "")
10503 (match_operand:DI 1 "const_0_to_63_operand" ""))
10504 (not:DI (zero_extract:DI
10505 (match_dup 0) (const_int 1) (match_dup 1))))
10506 (clobber (reg:CC FLAGS_REG))])]
10507 "TARGET_64BIT && !TARGET_USE_BT"
10510 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10513 if (HOST_BITS_PER_WIDE_INT >= 64)
10514 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10515 else if (i < HOST_BITS_PER_WIDE_INT)
10516 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10518 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10520 op1 = immed_double_const (lo, hi, DImode);
10523 emit_move_insn (operands[2], op1);
10527 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10531 (define_insn "*bt<mode>"
10532 [(set (reg:CCC FLAGS_REG)
10534 (zero_extract:SWI48
10535 (match_operand:SWI48 0 "register_operand" "r")
10537 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10539 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10540 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10541 [(set_attr "type" "alu1")
10542 (set_attr "prefix_0f" "1")
10543 (set_attr "mode" "<MODE>")])
10545 ;; Store-flag instructions.
10547 ;; For all sCOND expanders, also expand the compare or test insn that
10548 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10550 (define_insn_and_split "*setcc_di_1"
10551 [(set (match_operand:DI 0 "register_operand" "=q")
10552 (match_operator:DI 1 "ix86_comparison_operator"
10553 [(reg FLAGS_REG) (const_int 0)]))]
10554 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10556 "&& reload_completed"
10557 [(set (match_dup 2) (match_dup 1))
10558 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10560 PUT_MODE (operands[1], QImode);
10561 operands[2] = gen_lowpart (QImode, operands[0]);
10564 (define_insn_and_split "*setcc_si_1_and"
10565 [(set (match_operand:SI 0 "register_operand" "=q")
10566 (match_operator:SI 1 "ix86_comparison_operator"
10567 [(reg FLAGS_REG) (const_int 0)]))
10568 (clobber (reg:CC FLAGS_REG))]
10569 "!TARGET_PARTIAL_REG_STALL
10570 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10572 "&& reload_completed"
10573 [(set (match_dup 2) (match_dup 1))
10574 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10575 (clobber (reg:CC FLAGS_REG))])]
10577 PUT_MODE (operands[1], QImode);
10578 operands[2] = gen_lowpart (QImode, operands[0]);
10581 (define_insn_and_split "*setcc_si_1_movzbl"
10582 [(set (match_operand:SI 0 "register_operand" "=q")
10583 (match_operator:SI 1 "ix86_comparison_operator"
10584 [(reg FLAGS_REG) (const_int 0)]))]
10585 "!TARGET_PARTIAL_REG_STALL
10586 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10588 "&& reload_completed"
10589 [(set (match_dup 2) (match_dup 1))
10590 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10592 PUT_MODE (operands[1], QImode);
10593 operands[2] = gen_lowpart (QImode, operands[0]);
10596 (define_insn "*setcc_qi"
10597 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10598 (match_operator:QI 1 "ix86_comparison_operator"
10599 [(reg FLAGS_REG) (const_int 0)]))]
10602 [(set_attr "type" "setcc")
10603 (set_attr "mode" "QI")])
10605 (define_insn "*setcc_qi_slp"
10606 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10607 (match_operator:QI 1 "ix86_comparison_operator"
10608 [(reg FLAGS_REG) (const_int 0)]))]
10611 [(set_attr "type" "setcc")
10612 (set_attr "mode" "QI")])
10614 ;; In general it is not safe to assume too much about CCmode registers,
10615 ;; so simplify-rtx stops when it sees a second one. Under certain
10616 ;; conditions this is safe on x86, so help combine not create
10623 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10624 (ne:QI (match_operator 1 "ix86_comparison_operator"
10625 [(reg FLAGS_REG) (const_int 0)])
10628 [(set (match_dup 0) (match_dup 1))]
10629 "PUT_MODE (operands[1], QImode);")
10632 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10633 (ne:QI (match_operator 1 "ix86_comparison_operator"
10634 [(reg FLAGS_REG) (const_int 0)])
10637 [(set (match_dup 0) (match_dup 1))]
10638 "PUT_MODE (operands[1], QImode);")
10641 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10642 (eq:QI (match_operator 1 "ix86_comparison_operator"
10643 [(reg FLAGS_REG) (const_int 0)])
10646 [(set (match_dup 0) (match_dup 1))]
10648 rtx new_op1 = copy_rtx (operands[1]);
10649 operands[1] = new_op1;
10650 PUT_MODE (new_op1, QImode);
10651 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10652 GET_MODE (XEXP (new_op1, 0))));
10654 /* Make sure that (a) the CCmode we have for the flags is strong
10655 enough for the reversed compare or (b) we have a valid FP compare. */
10656 if (! ix86_comparison_operator (new_op1, VOIDmode))
10661 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10662 (eq:QI (match_operator 1 "ix86_comparison_operator"
10663 [(reg FLAGS_REG) (const_int 0)])
10666 [(set (match_dup 0) (match_dup 1))]
10668 rtx new_op1 = copy_rtx (operands[1]);
10669 operands[1] = new_op1;
10670 PUT_MODE (new_op1, QImode);
10671 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10672 GET_MODE (XEXP (new_op1, 0))));
10674 /* Make sure that (a) the CCmode we have for the flags is strong
10675 enough for the reversed compare or (b) we have a valid FP compare. */
10676 if (! ix86_comparison_operator (new_op1, VOIDmode))
10680 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10681 ;; subsequent logical operations are used to imitate conditional moves.
10682 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10685 (define_insn "*avx_setcc<mode>"
10686 [(set (match_operand:MODEF 0 "register_operand" "=x")
10687 (match_operator:MODEF 1 "avx_comparison_float_operator"
10688 [(match_operand:MODEF 2 "register_operand" "x")
10689 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10691 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10692 [(set_attr "type" "ssecmp")
10693 (set_attr "prefix" "vex")
10694 (set_attr "length_immediate" "1")
10695 (set_attr "mode" "<MODE>")])
10697 (define_insn "*sse_setcc<mode>"
10698 [(set (match_operand:MODEF 0 "register_operand" "=x")
10699 (match_operator:MODEF 1 "sse_comparison_operator"
10700 [(match_operand:MODEF 2 "register_operand" "0")
10701 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10702 "SSE_FLOAT_MODE_P (<MODE>mode)"
10703 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10704 [(set_attr "type" "ssecmp")
10705 (set_attr "length_immediate" "1")
10706 (set_attr "mode" "<MODE>")])
10708 ;; Basic conditional jump instructions.
10709 ;; We ignore the overflow flag for signed branch instructions.
10711 (define_insn "*jcc_1"
10713 (if_then_else (match_operator 1 "ix86_comparison_operator"
10714 [(reg FLAGS_REG) (const_int 0)])
10715 (label_ref (match_operand 0 "" ""))
10719 [(set_attr "type" "ibr")
10720 (set_attr "modrm" "0")
10721 (set (attr "length")
10722 (if_then_else (and (ge (minus (match_dup 0) (pc))
10724 (lt (minus (match_dup 0) (pc))
10729 (define_insn "*jcc_2"
10731 (if_then_else (match_operator 1 "ix86_comparison_operator"
10732 [(reg FLAGS_REG) (const_int 0)])
10734 (label_ref (match_operand 0 "" ""))))]
10737 [(set_attr "type" "ibr")
10738 (set_attr "modrm" "0")
10739 (set (attr "length")
10740 (if_then_else (and (ge (minus (match_dup 0) (pc))
10742 (lt (minus (match_dup 0) (pc))
10747 ;; In general it is not safe to assume too much about CCmode registers,
10748 ;; so simplify-rtx stops when it sees a second one. Under certain
10749 ;; conditions this is safe on x86, so help combine not create
10757 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10758 [(reg FLAGS_REG) (const_int 0)])
10760 (label_ref (match_operand 1 "" ""))
10764 (if_then_else (match_dup 0)
10765 (label_ref (match_dup 1))
10767 "PUT_MODE (operands[0], VOIDmode);")
10771 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10772 [(reg FLAGS_REG) (const_int 0)])
10774 (label_ref (match_operand 1 "" ""))
10778 (if_then_else (match_dup 0)
10779 (label_ref (match_dup 1))
10782 rtx new_op0 = copy_rtx (operands[0]);
10783 operands[0] = new_op0;
10784 PUT_MODE (new_op0, VOIDmode);
10785 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10786 GET_MODE (XEXP (new_op0, 0))));
10788 /* Make sure that (a) the CCmode we have for the flags is strong
10789 enough for the reversed compare or (b) we have a valid FP compare. */
10790 if (! ix86_comparison_operator (new_op0, VOIDmode))
10794 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10795 ;; pass generates from shift insn with QImode operand. Actually, the mode
10796 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10797 ;; appropriate modulo of the bit offset value.
10799 (define_insn_and_split "*jcc_bt<mode>"
10801 (if_then_else (match_operator 0 "bt_comparison_operator"
10802 [(zero_extract:SWI48
10803 (match_operand:SWI48 1 "register_operand" "r")
10806 (match_operand:QI 2 "register_operand" "r")))
10808 (label_ref (match_operand 3 "" ""))
10810 (clobber (reg:CC FLAGS_REG))]
10811 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10814 [(set (reg:CCC FLAGS_REG)
10816 (zero_extract:SWI48
10822 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10823 (label_ref (match_dup 3))
10826 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10828 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10831 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10832 ;; also for DImode, this is what combine produces.
10833 (define_insn_and_split "*jcc_bt<mode>_mask"
10835 (if_then_else (match_operator 0 "bt_comparison_operator"
10836 [(zero_extract:SWI48
10837 (match_operand:SWI48 1 "register_operand" "r")
10840 (match_operand:SI 2 "register_operand" "r")
10841 (match_operand:SI 3 "const_int_operand" "n")))])
10842 (label_ref (match_operand 4 "" ""))
10844 (clobber (reg:CC FLAGS_REG))]
10845 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10846 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10847 == GET_MODE_BITSIZE (<MODE>mode)-1"
10850 [(set (reg:CCC FLAGS_REG)
10852 (zero_extract:SWI48
10858 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10859 (label_ref (match_dup 4))
10862 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10864 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10867 (define_insn_and_split "*jcc_btsi_1"
10869 (if_then_else (match_operator 0 "bt_comparison_operator"
10872 (match_operand:SI 1 "register_operand" "r")
10873 (match_operand:QI 2 "register_operand" "r"))
10876 (label_ref (match_operand 3 "" ""))
10878 (clobber (reg:CC FLAGS_REG))]
10879 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10882 [(set (reg:CCC FLAGS_REG)
10890 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10891 (label_ref (match_dup 3))
10894 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10896 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10899 ;; avoid useless masking of bit offset operand
10900 (define_insn_and_split "*jcc_btsi_mask_1"
10903 (match_operator 0 "bt_comparison_operator"
10906 (match_operand:SI 1 "register_operand" "r")
10909 (match_operand:SI 2 "register_operand" "r")
10910 (match_operand:SI 3 "const_int_operand" "n")) 0))
10913 (label_ref (match_operand 4 "" ""))
10915 (clobber (reg:CC FLAGS_REG))]
10916 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10917 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10920 [(set (reg:CCC FLAGS_REG)
10928 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10929 (label_ref (match_dup 4))
10931 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10933 ;; Define combination compare-and-branch fp compare instructions to help
10936 (define_insn "*fp_jcc_1_387"
10938 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10939 [(match_operand 1 "register_operand" "f")
10940 (match_operand 2 "nonimmediate_operand" "fm")])
10941 (label_ref (match_operand 3 "" ""))
10943 (clobber (reg:CCFP FPSR_REG))
10944 (clobber (reg:CCFP FLAGS_REG))
10945 (clobber (match_scratch:HI 4 "=a"))]
10947 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10948 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10949 && SELECT_CC_MODE (GET_CODE (operands[0]),
10950 operands[1], operands[2]) == CCFPmode
10954 (define_insn "*fp_jcc_1r_387"
10956 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10957 [(match_operand 1 "register_operand" "f")
10958 (match_operand 2 "nonimmediate_operand" "fm")])
10960 (label_ref (match_operand 3 "" ""))))
10961 (clobber (reg:CCFP FPSR_REG))
10962 (clobber (reg:CCFP FLAGS_REG))
10963 (clobber (match_scratch:HI 4 "=a"))]
10965 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10966 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10967 && SELECT_CC_MODE (GET_CODE (operands[0]),
10968 operands[1], operands[2]) == CCFPmode
10972 (define_insn "*fp_jcc_2_387"
10974 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10975 [(match_operand 1 "register_operand" "f")
10976 (match_operand 2 "register_operand" "f")])
10977 (label_ref (match_operand 3 "" ""))
10979 (clobber (reg:CCFP FPSR_REG))
10980 (clobber (reg:CCFP FLAGS_REG))
10981 (clobber (match_scratch:HI 4 "=a"))]
10982 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10983 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10987 (define_insn "*fp_jcc_2r_387"
10989 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10990 [(match_operand 1 "register_operand" "f")
10991 (match_operand 2 "register_operand" "f")])
10993 (label_ref (match_operand 3 "" ""))))
10994 (clobber (reg:CCFP FPSR_REG))
10995 (clobber (reg:CCFP FLAGS_REG))
10996 (clobber (match_scratch:HI 4 "=a"))]
10997 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10998 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11002 (define_insn "*fp_jcc_3_387"
11004 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11005 [(match_operand 1 "register_operand" "f")
11006 (match_operand 2 "const0_operand" "")])
11007 (label_ref (match_operand 3 "" ""))
11009 (clobber (reg:CCFP FPSR_REG))
11010 (clobber (reg:CCFP FLAGS_REG))
11011 (clobber (match_scratch:HI 4 "=a"))]
11012 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11013 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11014 && SELECT_CC_MODE (GET_CODE (operands[0]),
11015 operands[1], operands[2]) == CCFPmode
11021 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11022 [(match_operand 1 "register_operand" "")
11023 (match_operand 2 "nonimmediate_operand" "")])
11024 (match_operand 3 "" "")
11025 (match_operand 4 "" "")))
11026 (clobber (reg:CCFP FPSR_REG))
11027 (clobber (reg:CCFP FLAGS_REG))]
11031 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11032 operands[3], operands[4], NULL_RTX, NULL_RTX);
11038 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11039 [(match_operand 1 "register_operand" "")
11040 (match_operand 2 "general_operand" "")])
11041 (match_operand 3 "" "")
11042 (match_operand 4 "" "")))
11043 (clobber (reg:CCFP FPSR_REG))
11044 (clobber (reg:CCFP FLAGS_REG))
11045 (clobber (match_scratch:HI 5 "=a"))]
11049 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11050 operands[3], operands[4], operands[5], NULL_RTX);
11054 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11055 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11056 ;; with a precedence over other operators and is always put in the first
11057 ;; place. Swap condition and operands to match ficom instruction.
11059 (define_insn "*fp_jcc_4_<mode>_387"
11062 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11063 [(match_operator 1 "float_operator"
11064 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11065 (match_operand 3 "register_operand" "f,f")])
11066 (label_ref (match_operand 4 "" ""))
11068 (clobber (reg:CCFP FPSR_REG))
11069 (clobber (reg:CCFP FLAGS_REG))
11070 (clobber (match_scratch:HI 5 "=a,a"))]
11071 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11072 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11073 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11074 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11081 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11082 [(match_operator 1 "float_operator"
11083 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11084 (match_operand 3 "register_operand" "")])
11085 (match_operand 4 "" "")
11086 (match_operand 5 "" "")))
11087 (clobber (reg:CCFP FPSR_REG))
11088 (clobber (reg:CCFP FLAGS_REG))
11089 (clobber (match_scratch:HI 6 "=a"))]
11093 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11095 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11096 operands[3], operands[7],
11097 operands[4], operands[5], operands[6], NULL_RTX);
11101 ;; %%% Kill this when reload knows how to do it.
11105 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11106 [(match_operator 1 "float_operator"
11107 [(match_operand:X87MODEI12 2 "register_operand" "")])
11108 (match_operand 3 "register_operand" "")])
11109 (match_operand 4 "" "")
11110 (match_operand 5 "" "")))
11111 (clobber (reg:CCFP FPSR_REG))
11112 (clobber (reg:CCFP FLAGS_REG))
11113 (clobber (match_scratch:HI 6 "=a"))]
11117 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11118 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11120 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11121 operands[3], operands[7],
11122 operands[4], operands[5], operands[6], operands[2]);
11126 ;; Unconditional and other jump instructions
11128 (define_insn "jump"
11130 (label_ref (match_operand 0 "" "")))]
11133 [(set_attr "type" "ibr")
11134 (set (attr "length")
11135 (if_then_else (and (ge (minus (match_dup 0) (pc))
11137 (lt (minus (match_dup 0) (pc))
11141 (set_attr "modrm" "0")])
11143 (define_expand "indirect_jump"
11144 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11148 (define_insn "*indirect_jump"
11149 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11152 [(set_attr "type" "ibr")
11153 (set_attr "length_immediate" "0")])
11155 (define_expand "tablejump"
11156 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11157 (use (label_ref (match_operand 1 "" "")))])]
11160 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11161 relative. Convert the relative address to an absolute address. */
11165 enum rtx_code code;
11167 /* We can't use @GOTOFF for text labels on VxWorks;
11168 see gotoff_operand. */
11169 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11173 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11175 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11179 op1 = pic_offset_table_rtx;
11184 op0 = pic_offset_table_rtx;
11188 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11193 (define_insn "*tablejump_1"
11194 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11195 (use (label_ref (match_operand 1 "" "")))]
11198 [(set_attr "type" "ibr")
11199 (set_attr "length_immediate" "0")])
11201 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11204 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11205 (set (match_operand:QI 1 "register_operand" "")
11206 (match_operator:QI 2 "ix86_comparison_operator"
11207 [(reg FLAGS_REG) (const_int 0)]))
11208 (set (match_operand 3 "q_regs_operand" "")
11209 (zero_extend (match_dup 1)))]
11210 "(peep2_reg_dead_p (3, operands[1])
11211 || operands_match_p (operands[1], operands[3]))
11212 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11213 [(set (match_dup 4) (match_dup 0))
11214 (set (strict_low_part (match_dup 5))
11217 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11218 operands[5] = gen_lowpart (QImode, operands[3]);
11219 ix86_expand_clear (operands[3]);
11222 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11225 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11226 (set (match_operand:QI 1 "register_operand" "")
11227 (match_operator:QI 2 "ix86_comparison_operator"
11228 [(reg FLAGS_REG) (const_int 0)]))
11229 (parallel [(set (match_operand 3 "q_regs_operand" "")
11230 (zero_extend (match_dup 1)))
11231 (clobber (reg:CC FLAGS_REG))])]
11232 "(peep2_reg_dead_p (3, operands[1])
11233 || operands_match_p (operands[1], operands[3]))
11234 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11235 [(set (match_dup 4) (match_dup 0))
11236 (set (strict_low_part (match_dup 5))
11239 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11240 operands[5] = gen_lowpart (QImode, operands[3]);
11241 ix86_expand_clear (operands[3]);
11244 ;; Call instructions.
11246 ;; The predicates normally associated with named expanders are not properly
11247 ;; checked for calls. This is a bug in the generic code, but it isn't that
11248 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11250 ;; P6 processors will jump to the address after the decrement when %esp
11251 ;; is used as a call operand, so they will execute return address as a code.
11252 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11254 ;; Call subroutine returning no value.
11256 (define_expand "call_pop"
11257 [(parallel [(call (match_operand:QI 0 "" "")
11258 (match_operand:SI 1 "" ""))
11259 (set (reg:SI SP_REG)
11260 (plus:SI (reg:SI SP_REG)
11261 (match_operand:SI 3 "" "")))])]
11264 ix86_expand_call (NULL, operands[0], operands[1],
11265 operands[2], operands[3], 0);
11269 (define_insn_and_split "*call_pop_0_vzeroupper"
11271 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11272 (match_operand:SI 1 "" ""))
11273 (set (reg:SI SP_REG)
11274 (plus:SI (reg:SI SP_REG)
11275 (match_operand:SI 2 "immediate_operand" "")))])
11276 (unspec [(match_operand 3 "const_int_operand" "")]
11277 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11278 "TARGET_VZEROUPPER && !TARGET_64BIT"
11280 "&& reload_completed"
11282 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11283 [(set_attr "type" "call")])
11285 (define_insn "*call_pop_0"
11286 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11287 (match_operand:SI 1 "" ""))
11288 (set (reg:SI SP_REG)
11289 (plus:SI (reg:SI SP_REG)
11290 (match_operand:SI 2 "immediate_operand" "")))]
11293 if (SIBLING_CALL_P (insn))
11296 return "call\t%P0";
11298 [(set_attr "type" "call")])
11300 (define_insn_and_split "*call_pop_1_vzeroupper"
11302 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11303 (match_operand:SI 1 "" ""))
11304 (set (reg:SI SP_REG)
11305 (plus:SI (reg:SI SP_REG)
11306 (match_operand:SI 2 "immediate_operand" "i")))])
11307 (unspec [(match_operand 3 "const_int_operand" "")]
11308 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11309 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11311 "&& reload_completed"
11313 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11314 [(set_attr "type" "call")])
11316 (define_insn "*call_pop_1"
11317 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11318 (match_operand:SI 1 "" ""))
11319 (set (reg:SI SP_REG)
11320 (plus:SI (reg:SI SP_REG)
11321 (match_operand:SI 2 "immediate_operand" "i")))]
11322 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11324 if (constant_call_address_operand (operands[0], Pmode))
11325 return "call\t%P0";
11326 return "call\t%A0";
11328 [(set_attr "type" "call")])
11330 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11332 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11333 (match_operand:SI 1 "" ""))
11334 (set (reg:SI SP_REG)
11335 (plus:SI (reg:SI SP_REG)
11336 (match_operand:SI 2 "immediate_operand" "i,i")))])
11337 (unspec [(match_operand 3 "const_int_operand" "")]
11338 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11339 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11341 "&& reload_completed"
11343 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11344 [(set_attr "type" "call")])
11346 (define_insn "*sibcall_pop_1"
11347 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11348 (match_operand:SI 1 "" ""))
11349 (set (reg:SI SP_REG)
11350 (plus:SI (reg:SI SP_REG)
11351 (match_operand:SI 2 "immediate_operand" "i,i")))]
11352 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11356 [(set_attr "type" "call")])
11358 (define_expand "call"
11359 [(call (match_operand:QI 0 "" "")
11360 (match_operand 1 "" ""))
11361 (use (match_operand 2 "" ""))]
11364 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11368 (define_expand "sibcall"
11369 [(call (match_operand:QI 0 "" "")
11370 (match_operand 1 "" ""))
11371 (use (match_operand 2 "" ""))]
11374 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11378 (define_insn_and_split "*call_0_vzeroupper"
11379 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11380 (match_operand 1 "" ""))
11381 (unspec [(match_operand 2 "const_int_operand" "")]
11382 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11383 "TARGET_VZEROUPPER"
11385 "&& reload_completed"
11387 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11388 [(set_attr "type" "call")])
11390 (define_insn "*call_0"
11391 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11392 (match_operand 1 "" ""))]
11394 { return ix86_output_call_insn (insn, operands[0], 0); }
11395 [(set_attr "type" "call")])
11397 (define_insn_and_split "*call_1_vzeroupper"
11398 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11399 (match_operand 1 "" ""))
11400 (unspec [(match_operand 2 "const_int_operand" "")]
11401 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11402 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11404 "&& reload_completed"
11406 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11407 [(set_attr "type" "call")])
11409 (define_insn "*call_1"
11410 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11411 (match_operand 1 "" ""))]
11412 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11413 { return ix86_output_call_insn (insn, operands[0], 0); }
11414 [(set_attr "type" "call")])
11416 (define_insn_and_split "*sibcall_1_vzeroupper"
11417 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11418 (match_operand 1 "" ""))
11419 (unspec [(match_operand 2 "const_int_operand" "")]
11420 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11421 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11423 "&& reload_completed"
11425 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11426 [(set_attr "type" "call")])
11428 (define_insn "*sibcall_1"
11429 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11430 (match_operand 1 "" ""))]
11431 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11432 { return ix86_output_call_insn (insn, operands[0], 0); }
11433 [(set_attr "type" "call")])
11435 (define_insn_and_split "*call_1_rex64_vzeroupper"
11436 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11437 (match_operand 1 "" ""))
11438 (unspec [(match_operand 2 "const_int_operand" "")]
11439 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11440 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11441 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11443 "&& reload_completed"
11445 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11446 [(set_attr "type" "call")])
11448 (define_insn "*call_1_rex64"
11449 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11450 (match_operand 1 "" ""))]
11451 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11452 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11453 { return ix86_output_call_insn (insn, operands[0], 0); }
11454 [(set_attr "type" "call")])
11456 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11458 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11459 (match_operand 1 "" ""))
11460 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11461 (clobber (reg:TI XMM6_REG))
11462 (clobber (reg:TI XMM7_REG))
11463 (clobber (reg:TI XMM8_REG))
11464 (clobber (reg:TI XMM9_REG))
11465 (clobber (reg:TI XMM10_REG))
11466 (clobber (reg:TI XMM11_REG))
11467 (clobber (reg:TI XMM12_REG))
11468 (clobber (reg:TI XMM13_REG))
11469 (clobber (reg:TI XMM14_REG))
11470 (clobber (reg:TI XMM15_REG))
11471 (clobber (reg:DI SI_REG))
11472 (clobber (reg:DI DI_REG))])
11473 (unspec [(match_operand 2 "const_int_operand" "")]
11474 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11475 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11477 "&& reload_completed"
11479 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11480 [(set_attr "type" "call")])
11482 (define_insn "*call_1_rex64_ms_sysv"
11483 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11484 (match_operand 1 "" ""))
11485 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11486 (clobber (reg:TI XMM6_REG))
11487 (clobber (reg:TI XMM7_REG))
11488 (clobber (reg:TI XMM8_REG))
11489 (clobber (reg:TI XMM9_REG))
11490 (clobber (reg:TI XMM10_REG))
11491 (clobber (reg:TI XMM11_REG))
11492 (clobber (reg:TI XMM12_REG))
11493 (clobber (reg:TI XMM13_REG))
11494 (clobber (reg:TI XMM14_REG))
11495 (clobber (reg:TI XMM15_REG))
11496 (clobber (reg:DI SI_REG))
11497 (clobber (reg:DI DI_REG))]
11498 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11499 { return ix86_output_call_insn (insn, operands[0], 0); }
11500 [(set_attr "type" "call")])
11502 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11503 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11504 (match_operand 1 "" ""))
11505 (unspec [(match_operand 2 "const_int_operand" "")]
11506 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11507 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11509 "&& reload_completed"
11511 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11512 [(set_attr "type" "call")])
11514 (define_insn "*call_1_rex64_large"
11515 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11516 (match_operand 1 "" ""))]
11517 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11518 { return ix86_output_call_insn (insn, operands[0], 0); }
11519 [(set_attr "type" "call")])
11521 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11522 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11523 (match_operand 1 "" ""))
11524 (unspec [(match_operand 2 "const_int_operand" "")]
11525 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11526 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11528 "&& reload_completed"
11530 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11531 [(set_attr "type" "call")])
11533 (define_insn "*sibcall_1_rex64"
11534 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11535 (match_operand 1 "" ""))]
11536 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11537 { return ix86_output_call_insn (insn, operands[0], 0); }
11538 [(set_attr "type" "call")])
11540 ;; Call subroutine, returning value in operand 0
11541 (define_expand "call_value_pop"
11542 [(parallel [(set (match_operand 0 "" "")
11543 (call (match_operand:QI 1 "" "")
11544 (match_operand:SI 2 "" "")))
11545 (set (reg:SI SP_REG)
11546 (plus:SI (reg:SI SP_REG)
11547 (match_operand:SI 4 "" "")))])]
11550 ix86_expand_call (operands[0], operands[1], operands[2],
11551 operands[3], operands[4], 0);
11555 (define_expand "call_value"
11556 [(set (match_operand 0 "" "")
11557 (call (match_operand:QI 1 "" "")
11558 (match_operand:SI 2 "" "")))
11559 (use (match_operand:SI 3 "" ""))]
11560 ;; Operand 3 is not used on the i386.
11563 ix86_expand_call (operands[0], operands[1], operands[2],
11564 operands[3], NULL, 0);
11568 (define_expand "sibcall_value"
11569 [(set (match_operand 0 "" "")
11570 (call (match_operand:QI 1 "" "")
11571 (match_operand:SI 2 "" "")))
11572 (use (match_operand:SI 3 "" ""))]
11573 ;; Operand 3 is not used on the i386.
11576 ix86_expand_call (operands[0], operands[1], operands[2],
11577 operands[3], NULL, 1);
11581 ;; Call subroutine returning any type.
11583 (define_expand "untyped_call"
11584 [(parallel [(call (match_operand 0 "" "")
11586 (match_operand 1 "" "")
11587 (match_operand 2 "" "")])]
11592 /* In order to give reg-stack an easier job in validating two
11593 coprocessor registers as containing a possible return value,
11594 simply pretend the untyped call returns a complex long double
11597 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11598 and should have the default ABI. */
11600 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11601 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11602 operands[0], const0_rtx,
11603 GEN_INT ((TARGET_64BIT
11604 ? (ix86_abi == SYSV_ABI
11605 ? X86_64_SSE_REGPARM_MAX
11606 : X86_64_MS_SSE_REGPARM_MAX)
11607 : X86_32_SSE_REGPARM_MAX)
11611 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11613 rtx set = XVECEXP (operands[2], 0, i);
11614 emit_move_insn (SET_DEST (set), SET_SRC (set));
11617 /* The optimizer does not know that the call sets the function value
11618 registers we stored in the result block. We avoid problems by
11619 claiming that all hard registers are used and clobbered at this
11621 emit_insn (gen_blockage ());
11626 ;; Prologue and epilogue instructions
11628 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11629 ;; all of memory. This blocks insns from being moved across this point.
11631 (define_insn "blockage"
11632 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11635 [(set_attr "length" "0")])
11637 ;; Do not schedule instructions accessing memory across this point.
11639 (define_expand "memory_blockage"
11640 [(set (match_dup 0)
11641 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11644 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11645 MEM_VOLATILE_P (operands[0]) = 1;
11648 (define_insn "*memory_blockage"
11649 [(set (match_operand:BLK 0 "" "")
11650 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11653 [(set_attr "length" "0")])
11655 ;; As USE insns aren't meaningful after reload, this is used instead
11656 ;; to prevent deleting instructions setting registers for PIC code
11657 (define_insn "prologue_use"
11658 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11661 [(set_attr "length" "0")])
11663 ;; Insn emitted into the body of a function to return from a function.
11664 ;; This is only done if the function's epilogue is known to be simple.
11665 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11667 (define_expand "return"
11669 "ix86_can_use_return_insn_p ()"
11671 if (crtl->args.pops_args)
11673 rtx popc = GEN_INT (crtl->args.pops_args);
11674 emit_jump_insn (gen_return_pop_internal (popc));
11679 (define_insn "return_internal"
11683 [(set_attr "length" "1")
11684 (set_attr "atom_unit" "jeu")
11685 (set_attr "length_immediate" "0")
11686 (set_attr "modrm" "0")])
11688 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11689 ;; instruction Athlon and K8 have.
11691 (define_insn "return_internal_long"
11693 (unspec [(const_int 0)] UNSPEC_REP)]
11696 [(set_attr "length" "2")
11697 (set_attr "atom_unit" "jeu")
11698 (set_attr "length_immediate" "0")
11699 (set_attr "prefix_rep" "1")
11700 (set_attr "modrm" "0")])
11702 (define_insn "return_pop_internal"
11704 (use (match_operand:SI 0 "const_int_operand" ""))]
11707 [(set_attr "length" "3")
11708 (set_attr "atom_unit" "jeu")
11709 (set_attr "length_immediate" "2")
11710 (set_attr "modrm" "0")])
11712 (define_insn "return_indirect_internal"
11714 (use (match_operand:SI 0 "register_operand" "r"))]
11717 [(set_attr "type" "ibr")
11718 (set_attr "length_immediate" "0")])
11724 [(set_attr "length" "1")
11725 (set_attr "length_immediate" "0")
11726 (set_attr "modrm" "0")])
11728 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11729 (define_insn "nops"
11730 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11734 int num = INTVAL (operands[0]);
11736 gcc_assert (num >= 1 && num <= 8);
11739 fputs ("\tnop\n", asm_out_file);
11743 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11744 (set_attr "length_immediate" "0")
11745 (set_attr "modrm" "0")])
11747 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11748 ;; branch prediction penalty for the third jump in a 16-byte
11752 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11755 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11756 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11758 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11759 The align insn is used to avoid 3 jump instructions in the row to improve
11760 branch prediction and the benefits hardly outweigh the cost of extra 8
11761 nops on the average inserted by full alignment pseudo operation. */
11765 [(set_attr "length" "16")])
11767 (define_expand "prologue"
11770 "ix86_expand_prologue (); DONE;")
11772 (define_insn "set_got"
11773 [(set (match_operand:SI 0 "register_operand" "=r")
11774 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11775 (clobber (reg:CC FLAGS_REG))]
11777 "* return output_set_got (operands[0], NULL_RTX);"
11778 [(set_attr "type" "multi")
11779 (set_attr "length" "12")])
11781 (define_insn "set_got_labelled"
11782 [(set (match_operand:SI 0 "register_operand" "=r")
11783 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11785 (clobber (reg:CC FLAGS_REG))]
11787 "* return output_set_got (operands[0], operands[1]);"
11788 [(set_attr "type" "multi")
11789 (set_attr "length" "12")])
11791 (define_insn "set_got_rex64"
11792 [(set (match_operand:DI 0 "register_operand" "=r")
11793 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11795 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11796 [(set_attr "type" "lea")
11797 (set_attr "length_address" "4")
11798 (set_attr "mode" "DI")])
11800 (define_insn "set_rip_rex64"
11801 [(set (match_operand:DI 0 "register_operand" "=r")
11802 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11804 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11805 [(set_attr "type" "lea")
11806 (set_attr "length_address" "4")
11807 (set_attr "mode" "DI")])
11809 (define_insn "set_got_offset_rex64"
11810 [(set (match_operand:DI 0 "register_operand" "=r")
11812 [(label_ref (match_operand 1 "" ""))]
11813 UNSPEC_SET_GOT_OFFSET))]
11815 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11816 [(set_attr "type" "imov")
11817 (set_attr "length_immediate" "0")
11818 (set_attr "length_address" "8")
11819 (set_attr "mode" "DI")])
11821 (define_expand "epilogue"
11824 "ix86_expand_epilogue (1); DONE;")
11826 (define_expand "sibcall_epilogue"
11829 "ix86_expand_epilogue (0); DONE;")
11831 (define_expand "eh_return"
11832 [(use (match_operand 0 "register_operand" ""))]
11835 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11837 /* Tricky bit: we write the address of the handler to which we will
11838 be returning into someone else's stack frame, one word below the
11839 stack address we wish to restore. */
11840 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11841 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11842 tmp = gen_rtx_MEM (Pmode, tmp);
11843 emit_move_insn (tmp, ra);
11845 emit_jump_insn (gen_eh_return_internal ());
11850 (define_insn_and_split "eh_return_internal"
11854 "epilogue_completed"
11856 "ix86_expand_epilogue (2); DONE;")
11858 (define_insn "leave"
11859 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11860 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11861 (clobber (mem:BLK (scratch)))]
11864 [(set_attr "type" "leave")])
11866 (define_insn "leave_rex64"
11867 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11868 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11869 (clobber (mem:BLK (scratch)))]
11872 [(set_attr "type" "leave")])
11874 ;; Handle -fsplit-stack.
11876 (define_expand "split_stack_prologue"
11880 ix86_expand_split_stack_prologue ();
11884 ;; In order to support the call/return predictor, we use a return
11885 ;; instruction which the middle-end doesn't see.
11886 (define_insn "split_stack_return"
11887 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11888 UNSPECV_SPLIT_STACK_RETURN)]
11891 if (operands[0] == const0_rtx)
11896 [(set_attr "atom_unit" "jeu")
11897 (set_attr "modrm" "0")
11898 (set (attr "length")
11899 (if_then_else (match_operand:SI 0 "const0_operand" "")
11902 (set (attr "length_immediate")
11903 (if_then_else (match_operand:SI 0 "const0_operand" "")
11907 ;; If there are operand 0 bytes available on the stack, jump to
11910 (define_expand "split_stack_space_check"
11911 [(set (pc) (if_then_else
11912 (ltu (minus (reg SP_REG)
11913 (match_operand 0 "register_operand" ""))
11914 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11915 (label_ref (match_operand 1 "" ""))
11919 rtx reg, size, limit;
11921 reg = gen_reg_rtx (Pmode);
11922 size = force_reg (Pmode, operands[0]);
11923 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11924 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11925 UNSPEC_STACK_CHECK);
11926 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11927 ix86_expand_branch (GEU, reg, limit, operands[1]);
11932 ;; Bit manipulation instructions.
11934 (define_expand "ffs<mode>2"
11935 [(set (match_dup 2) (const_int -1))
11936 (parallel [(set (reg:CCZ FLAGS_REG)
11938 (match_operand:SWI48 1 "nonimmediate_operand" "")
11940 (set (match_operand:SWI48 0 "register_operand" "")
11941 (ctz:SWI48 (match_dup 1)))])
11942 (set (match_dup 0) (if_then_else:SWI48
11943 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11946 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11947 (clobber (reg:CC FLAGS_REG))])]
11950 if (<MODE>mode == SImode && !TARGET_CMOVE)
11952 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11955 operands[2] = gen_reg_rtx (<MODE>mode);
11958 (define_insn_and_split "ffssi2_no_cmove"
11959 [(set (match_operand:SI 0 "register_operand" "=r")
11960 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11961 (clobber (match_scratch:SI 2 "=&q"))
11962 (clobber (reg:CC FLAGS_REG))]
11965 "&& reload_completed"
11966 [(parallel [(set (reg:CCZ FLAGS_REG)
11967 (compare:CCZ (match_dup 1) (const_int 0)))
11968 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11969 (set (strict_low_part (match_dup 3))
11970 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11971 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11972 (clobber (reg:CC FLAGS_REG))])
11973 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11974 (clobber (reg:CC FLAGS_REG))])
11975 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11976 (clobber (reg:CC FLAGS_REG))])]
11978 operands[3] = gen_lowpart (QImode, operands[2]);
11979 ix86_expand_clear (operands[2]);
11982 (define_insn "*ffs<mode>_1"
11983 [(set (reg:CCZ FLAGS_REG)
11984 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11986 (set (match_operand:SWI48 0 "register_operand" "=r")
11987 (ctz:SWI48 (match_dup 1)))]
11989 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11990 [(set_attr "type" "alu1")
11991 (set_attr "prefix_0f" "1")
11992 (set_attr "mode" "<MODE>")])
11994 (define_insn "ctz<mode>2"
11995 [(set (match_operand:SWI248 0 "register_operand" "=r")
11996 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11997 (clobber (reg:CC FLAGS_REG))]
12001 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12003 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12005 [(set_attr "type" "alu1")
12006 (set_attr "prefix_0f" "1")
12007 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12008 (set_attr "mode" "<MODE>")])
12010 (define_expand "clz<mode>2"
12012 [(set (match_operand:SWI248 0 "register_operand" "")
12015 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12016 (clobber (reg:CC FLAGS_REG))])
12018 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12019 (clobber (reg:CC FLAGS_REG))])]
12024 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12027 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12030 (define_insn "clz<mode>2_abm"
12031 [(set (match_operand:SWI248 0 "register_operand" "=r")
12032 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12033 (clobber (reg:CC FLAGS_REG))]
12034 "TARGET_ABM || TARGET_BMI"
12035 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12036 [(set_attr "prefix_rep" "1")
12037 (set_attr "type" "bitmanip")
12038 (set_attr "mode" "<MODE>")])
12040 ;; BMI instructions.
12041 (define_insn "*bmi_andn_<mode>"
12042 [(set (match_operand:SWI48 0 "register_operand" "=r")
12045 (match_operand:SWI48 1 "register_operand" "r"))
12046 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12047 (clobber (reg:CC FLAGS_REG))]
12049 "andn\t{%2, %1, %0|%0, %1, %2}"
12050 [(set_attr "type" "bitmanip")
12051 (set_attr "mode" "<MODE>")])
12053 (define_insn "bmi_bextr_<mode>"
12054 [(set (match_operand:SWI48 0 "register_operand" "=r")
12055 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12056 (match_operand:SWI48 2 "register_operand" "r")]
12058 (clobber (reg:CC FLAGS_REG))]
12060 "bextr\t{%2, %1, %0|%0, %1, %2}"
12061 [(set_attr "type" "bitmanip")
12062 (set_attr "mode" "<MODE>")])
12064 (define_insn "*bmi_blsi_<mode>"
12065 [(set (match_operand:SWI48 0 "register_operand" "=r")
12068 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12070 (clobber (reg:CC FLAGS_REG))]
12072 "blsi\t{%1, %0|%0, %1}"
12073 [(set_attr "type" "bitmanip")
12074 (set_attr "mode" "<MODE>")])
12076 (define_insn "*bmi_blsmsk_<mode>"
12077 [(set (match_operand:SWI48 0 "register_operand" "=r")
12080 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12083 (clobber (reg:CC FLAGS_REG))]
12085 "blsmsk\t{%1, %0|%0, %1}"
12086 [(set_attr "type" "bitmanip")
12087 (set_attr "mode" "<MODE>")])
12089 (define_insn "*bmi_blsr_<mode>"
12090 [(set (match_operand:SWI48 0 "register_operand" "=r")
12093 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12096 (clobber (reg:CC FLAGS_REG))]
12098 "blsr\t{%1, %0|%0, %1}"
12099 [(set_attr "type" "bitmanip")
12100 (set_attr "mode" "<MODE>")])
12102 ;; TBM instructions.
12103 (define_insn "tbm_bextri_<mode>"
12104 [(set (match_operand:SWI48 0 "register_operand" "=r")
12105 (zero_extract:SWI48
12106 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12107 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12108 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12109 (clobber (reg:CC FLAGS_REG))]
12112 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12113 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12115 [(set_attr "type" "bitmanip")
12116 (set_attr "mode" "<MODE>")])
12118 (define_insn "*tbm_blcfill_<mode>"
12119 [(set (match_operand:SWI48 0 "register_operand" "=r")
12122 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12125 (clobber (reg:CC FLAGS_REG))]
12127 "blcfill\t{%1, %0|%0, %1}"
12128 [(set_attr "type" "bitmanip")
12129 (set_attr "mode" "<MODE>")])
12131 (define_insn "*tbm_blci_<mode>"
12132 [(set (match_operand:SWI48 0 "register_operand" "=r")
12136 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12139 (clobber (reg:CC FLAGS_REG))]
12141 "blci\t{%1, %0|%0, %1}"
12142 [(set_attr "type" "bitmanip")
12143 (set_attr "mode" "<MODE>")])
12145 (define_insn "*tbm_blcic_<mode>"
12146 [(set (match_operand:SWI48 0 "register_operand" "=r")
12149 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12153 (clobber (reg:CC FLAGS_REG))]
12155 "blcic\t{%1, %0|%0, %1}"
12156 [(set_attr "type" "bitmanip")
12157 (set_attr "mode" "<MODE>")])
12159 (define_insn "*tbm_blcmsk_<mode>"
12160 [(set (match_operand:SWI48 0 "register_operand" "=r")
12163 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12166 (clobber (reg:CC FLAGS_REG))]
12168 "blcmsk\t{%1, %0|%0, %1}"
12169 [(set_attr "type" "bitmanip")
12170 (set_attr "mode" "<MODE>")])
12172 (define_insn "*tbm_blcs_<mode>"
12173 [(set (match_operand:SWI48 0 "register_operand" "=r")
12176 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12179 (clobber (reg:CC FLAGS_REG))]
12181 "blcs\t{%1, %0|%0, %1}"
12182 [(set_attr "type" "bitmanip")
12183 (set_attr "mode" "<MODE>")])
12185 (define_insn "*tbm_blsfill_<mode>"
12186 [(set (match_operand:SWI48 0 "register_operand" "=r")
12189 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12192 (clobber (reg:CC FLAGS_REG))]
12194 "blsfill\t{%1, %0|%0, %1}"
12195 [(set_attr "type" "bitmanip")
12196 (set_attr "mode" "<MODE>")])
12198 (define_insn "*tbm_blsic_<mode>"
12199 [(set (match_operand:SWI48 0 "register_operand" "=r")
12202 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12206 (clobber (reg:CC FLAGS_REG))]
12208 "blsic\t{%1, %0|%0, %1}"
12209 [(set_attr "type" "bitmanip")
12210 (set_attr "mode" "<MODE>")])
12212 (define_insn "*tbm_t1mskc_<mode>"
12213 [(set (match_operand:SWI48 0 "register_operand" "=r")
12216 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12220 (clobber (reg:CC FLAGS_REG))]
12222 "t1mskc\t{%1, %0|%0, %1}"
12223 [(set_attr "type" "bitmanip")
12224 (set_attr "mode" "<MODE>")])
12226 (define_insn "*tbm_tzmsk_<mode>"
12227 [(set (match_operand:SWI48 0 "register_operand" "=r")
12230 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12234 (clobber (reg:CC FLAGS_REG))]
12236 "tzmsk\t{%1, %0|%0, %1}"
12237 [(set_attr "type" "bitmanip")
12238 (set_attr "mode" "<MODE>")])
12240 (define_insn "bsr_rex64"
12241 [(set (match_operand:DI 0 "register_operand" "=r")
12242 (minus:DI (const_int 63)
12243 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12244 (clobber (reg:CC FLAGS_REG))]
12246 "bsr{q}\t{%1, %0|%0, %1}"
12247 [(set_attr "type" "alu1")
12248 (set_attr "prefix_0f" "1")
12249 (set_attr "mode" "DI")])
12252 [(set (match_operand:SI 0 "register_operand" "=r")
12253 (minus:SI (const_int 31)
12254 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12255 (clobber (reg:CC FLAGS_REG))]
12257 "bsr{l}\t{%1, %0|%0, %1}"
12258 [(set_attr "type" "alu1")
12259 (set_attr "prefix_0f" "1")
12260 (set_attr "mode" "SI")])
12262 (define_insn "*bsrhi"
12263 [(set (match_operand:HI 0 "register_operand" "=r")
12264 (minus:HI (const_int 15)
12265 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12266 (clobber (reg:CC FLAGS_REG))]
12268 "bsr{w}\t{%1, %0|%0, %1}"
12269 [(set_attr "type" "alu1")
12270 (set_attr "prefix_0f" "1")
12271 (set_attr "mode" "HI")])
12273 (define_insn "popcount<mode>2"
12274 [(set (match_operand:SWI248 0 "register_operand" "=r")
12276 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12277 (clobber (reg:CC FLAGS_REG))]
12281 return "popcnt\t{%1, %0|%0, %1}";
12283 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12286 [(set_attr "prefix_rep" "1")
12287 (set_attr "type" "bitmanip")
12288 (set_attr "mode" "<MODE>")])
12290 (define_insn "*popcount<mode>2_cmp"
12291 [(set (reg FLAGS_REG)
12294 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12296 (set (match_operand:SWI248 0 "register_operand" "=r")
12297 (popcount:SWI248 (match_dup 1)))]
12298 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12301 return "popcnt\t{%1, %0|%0, %1}";
12303 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12306 [(set_attr "prefix_rep" "1")
12307 (set_attr "type" "bitmanip")
12308 (set_attr "mode" "<MODE>")])
12310 (define_insn "*popcountsi2_cmp_zext"
12311 [(set (reg FLAGS_REG)
12313 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12315 (set (match_operand:DI 0 "register_operand" "=r")
12316 (zero_extend:DI(popcount:SI (match_dup 1))))]
12317 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12320 return "popcnt\t{%1, %0|%0, %1}";
12322 return "popcnt{l}\t{%1, %0|%0, %1}";
12325 [(set_attr "prefix_rep" "1")
12326 (set_attr "type" "bitmanip")
12327 (set_attr "mode" "SI")])
12329 (define_expand "bswap<mode>2"
12330 [(set (match_operand:SWI48 0 "register_operand" "")
12331 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12334 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12336 rtx x = operands[0];
12338 emit_move_insn (x, operands[1]);
12339 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12340 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12341 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12346 (define_insn "*bswap<mode>2_movbe"
12347 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12348 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12350 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12353 movbe\t{%1, %0|%0, %1}
12354 movbe\t{%1, %0|%0, %1}"
12355 [(set_attr "type" "bitmanip,imov,imov")
12356 (set_attr "modrm" "0,1,1")
12357 (set_attr "prefix_0f" "*,1,1")
12358 (set_attr "prefix_extra" "*,1,1")
12359 (set_attr "mode" "<MODE>")])
12361 (define_insn "*bswap<mode>2_1"
12362 [(set (match_operand:SWI48 0 "register_operand" "=r")
12363 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12366 [(set_attr "type" "bitmanip")
12367 (set_attr "modrm" "0")
12368 (set_attr "mode" "<MODE>")])
12370 (define_insn "*bswaphi_lowpart_1"
12371 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12372 (bswap:HI (match_dup 0)))
12373 (clobber (reg:CC FLAGS_REG))]
12374 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12376 xchg{b}\t{%h0, %b0|%b0, %h0}
12377 rol{w}\t{$8, %0|%0, 8}"
12378 [(set_attr "length" "2,4")
12379 (set_attr "mode" "QI,HI")])
12381 (define_insn "bswaphi_lowpart"
12382 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12383 (bswap:HI (match_dup 0)))
12384 (clobber (reg:CC FLAGS_REG))]
12386 "rol{w}\t{$8, %0|%0, 8}"
12387 [(set_attr "length" "4")
12388 (set_attr "mode" "HI")])
12390 (define_expand "paritydi2"
12391 [(set (match_operand:DI 0 "register_operand" "")
12392 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12395 rtx scratch = gen_reg_rtx (QImode);
12398 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12399 NULL_RTX, operands[1]));
12401 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12402 gen_rtx_REG (CCmode, FLAGS_REG),
12404 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12407 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12410 rtx tmp = gen_reg_rtx (SImode);
12412 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12413 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12418 (define_expand "paritysi2"
12419 [(set (match_operand:SI 0 "register_operand" "")
12420 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12423 rtx scratch = gen_reg_rtx (QImode);
12426 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12428 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12429 gen_rtx_REG (CCmode, FLAGS_REG),
12431 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12433 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12437 (define_insn_and_split "paritydi2_cmp"
12438 [(set (reg:CC FLAGS_REG)
12439 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12441 (clobber (match_scratch:DI 0 "=r"))
12442 (clobber (match_scratch:SI 1 "=&r"))
12443 (clobber (match_scratch:HI 2 "=Q"))]
12446 "&& reload_completed"
12448 [(set (match_dup 1)
12449 (xor:SI (match_dup 1) (match_dup 4)))
12450 (clobber (reg:CC FLAGS_REG))])
12452 [(set (reg:CC FLAGS_REG)
12453 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12454 (clobber (match_dup 1))
12455 (clobber (match_dup 2))])]
12457 operands[4] = gen_lowpart (SImode, operands[3]);
12461 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12462 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12465 operands[1] = gen_highpart (SImode, operands[3]);
12468 (define_insn_and_split "paritysi2_cmp"
12469 [(set (reg:CC FLAGS_REG)
12470 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12472 (clobber (match_scratch:SI 0 "=r"))
12473 (clobber (match_scratch:HI 1 "=&Q"))]
12476 "&& reload_completed"
12478 [(set (match_dup 1)
12479 (xor:HI (match_dup 1) (match_dup 3)))
12480 (clobber (reg:CC FLAGS_REG))])
12482 [(set (reg:CC FLAGS_REG)
12483 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12484 (clobber (match_dup 1))])]
12486 operands[3] = gen_lowpart (HImode, operands[2]);
12488 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12489 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12492 (define_insn "*parityhi2_cmp"
12493 [(set (reg:CC FLAGS_REG)
12494 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12496 (clobber (match_scratch:HI 0 "=Q"))]
12498 "xor{b}\t{%h0, %b0|%b0, %h0}"
12499 [(set_attr "length" "2")
12500 (set_attr "mode" "HI")])
12502 ;; Thread-local storage patterns for ELF.
12504 ;; Note that these code sequences must appear exactly as shown
12505 ;; in order to allow linker relaxation.
12507 (define_insn "*tls_global_dynamic_32_gnu"
12508 [(set (match_operand:SI 0 "register_operand" "=a")
12509 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12510 (match_operand:SI 2 "tls_symbolic_operand" "")
12511 (match_operand:SI 3 "call_insn_operand" "")]
12513 (clobber (match_scratch:SI 4 "=d"))
12514 (clobber (match_scratch:SI 5 "=c"))
12515 (clobber (reg:CC FLAGS_REG))]
12516 "!TARGET_64BIT && TARGET_GNU_TLS"
12517 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12518 [(set_attr "type" "multi")
12519 (set_attr "length" "12")])
12521 (define_expand "tls_global_dynamic_32"
12522 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12525 (match_operand:SI 1 "tls_symbolic_operand" "")
12528 (clobber (match_scratch:SI 4 ""))
12529 (clobber (match_scratch:SI 5 ""))
12530 (clobber (reg:CC FLAGS_REG))])]
12534 operands[2] = pic_offset_table_rtx;
12537 operands[2] = gen_reg_rtx (Pmode);
12538 emit_insn (gen_set_got (operands[2]));
12540 if (TARGET_GNU2_TLS)
12542 emit_insn (gen_tls_dynamic_gnu2_32
12543 (operands[0], operands[1], operands[2]));
12546 operands[3] = ix86_tls_get_addr ();
12549 (define_insn "*tls_global_dynamic_64"
12550 [(set (match_operand:DI 0 "register_operand" "=a")
12551 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12552 (match_operand:DI 3 "" "")))
12553 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12556 { 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"; }
12557 [(set_attr "type" "multi")
12558 (set_attr "length" "16")])
12560 (define_expand "tls_global_dynamic_64"
12561 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12562 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12563 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12567 if (TARGET_GNU2_TLS)
12569 emit_insn (gen_tls_dynamic_gnu2_64
12570 (operands[0], operands[1]));
12573 operands[2] = ix86_tls_get_addr ();
12576 (define_insn "*tls_local_dynamic_base_32_gnu"
12577 [(set (match_operand:SI 0 "register_operand" "=a")
12578 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12579 (match_operand:SI 2 "call_insn_operand" "")]
12580 UNSPEC_TLS_LD_BASE))
12581 (clobber (match_scratch:SI 3 "=d"))
12582 (clobber (match_scratch:SI 4 "=c"))
12583 (clobber (reg:CC FLAGS_REG))]
12584 "!TARGET_64BIT && TARGET_GNU_TLS"
12585 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12586 [(set_attr "type" "multi")
12587 (set_attr "length" "11")])
12589 (define_expand "tls_local_dynamic_base_32"
12590 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12591 (unspec:SI [(match_dup 1) (match_dup 2)]
12592 UNSPEC_TLS_LD_BASE))
12593 (clobber (match_scratch:SI 3 ""))
12594 (clobber (match_scratch:SI 4 ""))
12595 (clobber (reg:CC FLAGS_REG))])]
12599 operands[1] = pic_offset_table_rtx;
12602 operands[1] = gen_reg_rtx (Pmode);
12603 emit_insn (gen_set_got (operands[1]));
12605 if (TARGET_GNU2_TLS)
12607 emit_insn (gen_tls_dynamic_gnu2_32
12608 (operands[0], ix86_tls_module_base (), operands[1]));
12611 operands[2] = ix86_tls_get_addr ();
12614 (define_insn "*tls_local_dynamic_base_64"
12615 [(set (match_operand:DI 0 "register_operand" "=a")
12616 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12617 (match_operand:DI 2 "" "")))
12618 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12620 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12621 [(set_attr "type" "multi")
12622 (set_attr "length" "12")])
12624 (define_expand "tls_local_dynamic_base_64"
12625 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12626 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12627 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12630 if (TARGET_GNU2_TLS)
12632 emit_insn (gen_tls_dynamic_gnu2_64
12633 (operands[0], ix86_tls_module_base ()));
12636 operands[1] = ix86_tls_get_addr ();
12639 ;; Local dynamic of a single variable is a lose. Show combine how
12640 ;; to convert that back to global dynamic.
12642 (define_insn_and_split "*tls_local_dynamic_32_once"
12643 [(set (match_operand:SI 0 "register_operand" "=a")
12644 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12645 (match_operand:SI 2 "call_insn_operand" "")]
12646 UNSPEC_TLS_LD_BASE)
12647 (const:SI (unspec:SI
12648 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12650 (clobber (match_scratch:SI 4 "=d"))
12651 (clobber (match_scratch:SI 5 "=c"))
12652 (clobber (reg:CC FLAGS_REG))]
12656 [(parallel [(set (match_dup 0)
12657 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12659 (clobber (match_dup 4))
12660 (clobber (match_dup 5))
12661 (clobber (reg:CC FLAGS_REG))])])
12663 ;; Segment register for the thread base ptr load
12664 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12666 ;; Load and add the thread base pointer from %gs:0.
12667 (define_insn "*load_tp_<mode>"
12668 [(set (match_operand:P 0 "register_operand" "=r")
12669 (unspec:P [(const_int 0)] UNSPEC_TP))]
12671 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12672 [(set_attr "type" "imov")
12673 (set_attr "modrm" "0")
12674 (set_attr "length" "7")
12675 (set_attr "memory" "load")
12676 (set_attr "imm_disp" "false")])
12678 (define_insn "*add_tp_<mode>"
12679 [(set (match_operand:P 0 "register_operand" "=r")
12680 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12681 (match_operand:P 1 "register_operand" "0")))
12682 (clobber (reg:CC FLAGS_REG))]
12684 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12685 [(set_attr "type" "alu")
12686 (set_attr "modrm" "0")
12687 (set_attr "length" "7")
12688 (set_attr "memory" "load")
12689 (set_attr "imm_disp" "false")])
12691 ;; GNU2 TLS patterns can be split.
12693 (define_expand "tls_dynamic_gnu2_32"
12694 [(set (match_dup 3)
12695 (plus:SI (match_operand:SI 2 "register_operand" "")
12697 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12700 [(set (match_operand:SI 0 "register_operand" "")
12701 (unspec:SI [(match_dup 1) (match_dup 3)
12702 (match_dup 2) (reg:SI SP_REG)]
12704 (clobber (reg:CC FLAGS_REG))])]
12705 "!TARGET_64BIT && TARGET_GNU2_TLS"
12707 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12708 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12711 (define_insn "*tls_dynamic_lea_32"
12712 [(set (match_operand:SI 0 "register_operand" "=r")
12713 (plus:SI (match_operand:SI 1 "register_operand" "b")
12715 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12716 UNSPEC_TLSDESC))))]
12717 "!TARGET_64BIT && TARGET_GNU2_TLS"
12718 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12719 [(set_attr "type" "lea")
12720 (set_attr "mode" "SI")
12721 (set_attr "length" "6")
12722 (set_attr "length_address" "4")])
12724 (define_insn "*tls_dynamic_call_32"
12725 [(set (match_operand:SI 0 "register_operand" "=a")
12726 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12727 (match_operand:SI 2 "register_operand" "0")
12728 ;; we have to make sure %ebx still points to the GOT
12729 (match_operand:SI 3 "register_operand" "b")
12732 (clobber (reg:CC FLAGS_REG))]
12733 "!TARGET_64BIT && TARGET_GNU2_TLS"
12734 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12735 [(set_attr "type" "call")
12736 (set_attr "length" "2")
12737 (set_attr "length_address" "0")])
12739 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12740 [(set (match_operand:SI 0 "register_operand" "=&a")
12742 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12743 (match_operand:SI 4 "" "")
12744 (match_operand:SI 2 "register_operand" "b")
12747 (const:SI (unspec:SI
12748 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12750 (clobber (reg:CC FLAGS_REG))]
12751 "!TARGET_64BIT && TARGET_GNU2_TLS"
12754 [(set (match_dup 0) (match_dup 5))]
12756 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12757 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12760 (define_expand "tls_dynamic_gnu2_64"
12761 [(set (match_dup 2)
12762 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12765 [(set (match_operand:DI 0 "register_operand" "")
12766 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12768 (clobber (reg:CC FLAGS_REG))])]
12769 "TARGET_64BIT && TARGET_GNU2_TLS"
12771 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12772 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12775 (define_insn "*tls_dynamic_lea_64"
12776 [(set (match_operand:DI 0 "register_operand" "=r")
12777 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12779 "TARGET_64BIT && TARGET_GNU2_TLS"
12780 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12781 [(set_attr "type" "lea")
12782 (set_attr "mode" "DI")
12783 (set_attr "length" "7")
12784 (set_attr "length_address" "4")])
12786 (define_insn "*tls_dynamic_call_64"
12787 [(set (match_operand:DI 0 "register_operand" "=a")
12788 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12789 (match_operand:DI 2 "register_operand" "0")
12792 (clobber (reg:CC FLAGS_REG))]
12793 "TARGET_64BIT && TARGET_GNU2_TLS"
12794 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12795 [(set_attr "type" "call")
12796 (set_attr "length" "2")
12797 (set_attr "length_address" "0")])
12799 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12800 [(set (match_operand:DI 0 "register_operand" "=&a")
12802 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12803 (match_operand:DI 3 "" "")
12806 (const:DI (unspec:DI
12807 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12809 (clobber (reg:CC FLAGS_REG))]
12810 "TARGET_64BIT && TARGET_GNU2_TLS"
12813 [(set (match_dup 0) (match_dup 4))]
12815 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12816 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12819 ;; These patterns match the binary 387 instructions for addM3, subM3,
12820 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12821 ;; SFmode. The first is the normal insn, the second the same insn but
12822 ;; with one operand a conversion, and the third the same insn but with
12823 ;; the other operand a conversion. The conversion may be SFmode or
12824 ;; SImode if the target mode DFmode, but only SImode if the target mode
12827 ;; Gcc is slightly more smart about handling normal two address instructions
12828 ;; so use special patterns for add and mull.
12830 (define_insn "*fop_<mode>_comm_mixed_avx"
12831 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12832 (match_operator:MODEF 3 "binary_fp_operator"
12833 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12834 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12835 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12836 && COMMUTATIVE_ARITH_P (operands[3])
12837 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12838 "* return output_387_binary_op (insn, operands);"
12839 [(set (attr "type")
12840 (if_then_else (eq_attr "alternative" "1")
12841 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12842 (const_string "ssemul")
12843 (const_string "sseadd"))
12844 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12845 (const_string "fmul")
12846 (const_string "fop"))))
12847 (set_attr "prefix" "orig,maybe_vex")
12848 (set_attr "mode" "<MODE>")])
12850 (define_insn "*fop_<mode>_comm_mixed"
12851 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12852 (match_operator:MODEF 3 "binary_fp_operator"
12853 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12854 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12855 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12856 && COMMUTATIVE_ARITH_P (operands[3])
12857 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12858 "* return output_387_binary_op (insn, operands);"
12859 [(set (attr "type")
12860 (if_then_else (eq_attr "alternative" "1")
12861 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12862 (const_string "ssemul")
12863 (const_string "sseadd"))
12864 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12865 (const_string "fmul")
12866 (const_string "fop"))))
12867 (set_attr "mode" "<MODE>")])
12869 (define_insn "*fop_<mode>_comm_avx"
12870 [(set (match_operand:MODEF 0 "register_operand" "=x")
12871 (match_operator:MODEF 3 "binary_fp_operator"
12872 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12873 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12874 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12875 && COMMUTATIVE_ARITH_P (operands[3])
12876 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12877 "* return output_387_binary_op (insn, operands);"
12878 [(set (attr "type")
12879 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12880 (const_string "ssemul")
12881 (const_string "sseadd")))
12882 (set_attr "prefix" "vex")
12883 (set_attr "mode" "<MODE>")])
12885 (define_insn "*fop_<mode>_comm_sse"
12886 [(set (match_operand:MODEF 0 "register_operand" "=x")
12887 (match_operator:MODEF 3 "binary_fp_operator"
12888 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12889 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12890 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12891 && COMMUTATIVE_ARITH_P (operands[3])
12892 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12893 "* return output_387_binary_op (insn, operands);"
12894 [(set (attr "type")
12895 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12896 (const_string "ssemul")
12897 (const_string "sseadd")))
12898 (set_attr "mode" "<MODE>")])
12900 (define_insn "*fop_<mode>_comm_i387"
12901 [(set (match_operand:MODEF 0 "register_operand" "=f")
12902 (match_operator:MODEF 3 "binary_fp_operator"
12903 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12904 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12905 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12906 && COMMUTATIVE_ARITH_P (operands[3])
12907 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12908 "* return output_387_binary_op (insn, operands);"
12909 [(set (attr "type")
12910 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12911 (const_string "fmul")
12912 (const_string "fop")))
12913 (set_attr "mode" "<MODE>")])
12915 (define_insn "*fop_<mode>_1_mixed_avx"
12916 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12917 (match_operator:MODEF 3 "binary_fp_operator"
12918 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12919 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12920 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12921 && !COMMUTATIVE_ARITH_P (operands[3])
12922 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12923 "* return output_387_binary_op (insn, operands);"
12924 [(set (attr "type")
12925 (cond [(and (eq_attr "alternative" "2")
12926 (match_operand:MODEF 3 "mult_operator" ""))
12927 (const_string "ssemul")
12928 (and (eq_attr "alternative" "2")
12929 (match_operand:MODEF 3 "div_operator" ""))
12930 (const_string "ssediv")
12931 (eq_attr "alternative" "2")
12932 (const_string "sseadd")
12933 (match_operand:MODEF 3 "mult_operator" "")
12934 (const_string "fmul")
12935 (match_operand:MODEF 3 "div_operator" "")
12936 (const_string "fdiv")
12938 (const_string "fop")))
12939 (set_attr "prefix" "orig,orig,maybe_vex")
12940 (set_attr "mode" "<MODE>")])
12942 (define_insn "*fop_<mode>_1_mixed"
12943 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12944 (match_operator:MODEF 3 "binary_fp_operator"
12945 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12946 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12947 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12948 && !COMMUTATIVE_ARITH_P (operands[3])
12949 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12950 "* return output_387_binary_op (insn, operands);"
12951 [(set (attr "type")
12952 (cond [(and (eq_attr "alternative" "2")
12953 (match_operand:MODEF 3 "mult_operator" ""))
12954 (const_string "ssemul")
12955 (and (eq_attr "alternative" "2")
12956 (match_operand:MODEF 3 "div_operator" ""))
12957 (const_string "ssediv")
12958 (eq_attr "alternative" "2")
12959 (const_string "sseadd")
12960 (match_operand:MODEF 3 "mult_operator" "")
12961 (const_string "fmul")
12962 (match_operand:MODEF 3 "div_operator" "")
12963 (const_string "fdiv")
12965 (const_string "fop")))
12966 (set_attr "mode" "<MODE>")])
12968 (define_insn "*rcpsf2_sse"
12969 [(set (match_operand:SF 0 "register_operand" "=x")
12970 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12973 "%vrcpss\t{%1, %d0|%d0, %1}"
12974 [(set_attr "type" "sse")
12975 (set_attr "atom_sse_attr" "rcp")
12976 (set_attr "prefix" "maybe_vex")
12977 (set_attr "mode" "SF")])
12979 (define_insn "*fop_<mode>_1_avx"
12980 [(set (match_operand:MODEF 0 "register_operand" "=x")
12981 (match_operator:MODEF 3 "binary_fp_operator"
12982 [(match_operand:MODEF 1 "register_operand" "x")
12983 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12984 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12985 && !COMMUTATIVE_ARITH_P (operands[3])"
12986 "* return output_387_binary_op (insn, operands);"
12987 [(set (attr "type")
12988 (cond [(match_operand:MODEF 3 "mult_operator" "")
12989 (const_string "ssemul")
12990 (match_operand:MODEF 3 "div_operator" "")
12991 (const_string "ssediv")
12993 (const_string "sseadd")))
12994 (set_attr "prefix" "vex")
12995 (set_attr "mode" "<MODE>")])
12997 (define_insn "*fop_<mode>_1_sse"
12998 [(set (match_operand:MODEF 0 "register_operand" "=x")
12999 (match_operator:MODEF 3 "binary_fp_operator"
13000 [(match_operand:MODEF 1 "register_operand" "0")
13001 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13002 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13003 && !COMMUTATIVE_ARITH_P (operands[3])"
13004 "* return output_387_binary_op (insn, operands);"
13005 [(set (attr "type")
13006 (cond [(match_operand:MODEF 3 "mult_operator" "")
13007 (const_string "ssemul")
13008 (match_operand:MODEF 3 "div_operator" "")
13009 (const_string "ssediv")
13011 (const_string "sseadd")))
13012 (set_attr "mode" "<MODE>")])
13014 ;; This pattern is not fully shadowed by the pattern above.
13015 (define_insn "*fop_<mode>_1_i387"
13016 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13017 (match_operator:MODEF 3 "binary_fp_operator"
13018 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13019 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13020 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13021 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13022 && !COMMUTATIVE_ARITH_P (operands[3])
13023 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13024 "* return output_387_binary_op (insn, operands);"
13025 [(set (attr "type")
13026 (cond [(match_operand:MODEF 3 "mult_operator" "")
13027 (const_string "fmul")
13028 (match_operand:MODEF 3 "div_operator" "")
13029 (const_string "fdiv")
13031 (const_string "fop")))
13032 (set_attr "mode" "<MODE>")])
13034 ;; ??? Add SSE splitters for these!
13035 (define_insn "*fop_<MODEF:mode>_2_i387"
13036 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13037 (match_operator:MODEF 3 "binary_fp_operator"
13039 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13040 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13041 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13042 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13043 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13044 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13045 [(set (attr "type")
13046 (cond [(match_operand:MODEF 3 "mult_operator" "")
13047 (const_string "fmul")
13048 (match_operand:MODEF 3 "div_operator" "")
13049 (const_string "fdiv")
13051 (const_string "fop")))
13052 (set_attr "fp_int_src" "true")
13053 (set_attr "mode" "<X87MODEI12:MODE>")])
13055 (define_insn "*fop_<MODEF:mode>_3_i387"
13056 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13057 (match_operator:MODEF 3 "binary_fp_operator"
13058 [(match_operand:MODEF 1 "register_operand" "0,0")
13060 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13061 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13062 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13063 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13064 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13065 [(set (attr "type")
13066 (cond [(match_operand:MODEF 3 "mult_operator" "")
13067 (const_string "fmul")
13068 (match_operand:MODEF 3 "div_operator" "")
13069 (const_string "fdiv")
13071 (const_string "fop")))
13072 (set_attr "fp_int_src" "true")
13073 (set_attr "mode" "<MODE>")])
13075 (define_insn "*fop_df_4_i387"
13076 [(set (match_operand:DF 0 "register_operand" "=f,f")
13077 (match_operator:DF 3 "binary_fp_operator"
13079 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13080 (match_operand:DF 2 "register_operand" "0,f")]))]
13081 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13082 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13083 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13084 "* return output_387_binary_op (insn, operands);"
13085 [(set (attr "type")
13086 (cond [(match_operand:DF 3 "mult_operator" "")
13087 (const_string "fmul")
13088 (match_operand:DF 3 "div_operator" "")
13089 (const_string "fdiv")
13091 (const_string "fop")))
13092 (set_attr "mode" "SF")])
13094 (define_insn "*fop_df_5_i387"
13095 [(set (match_operand:DF 0 "register_operand" "=f,f")
13096 (match_operator:DF 3 "binary_fp_operator"
13097 [(match_operand:DF 1 "register_operand" "0,f")
13099 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13100 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13101 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13102 "* return output_387_binary_op (insn, operands);"
13103 [(set (attr "type")
13104 (cond [(match_operand:DF 3 "mult_operator" "")
13105 (const_string "fmul")
13106 (match_operand:DF 3 "div_operator" "")
13107 (const_string "fdiv")
13109 (const_string "fop")))
13110 (set_attr "mode" "SF")])
13112 (define_insn "*fop_df_6_i387"
13113 [(set (match_operand:DF 0 "register_operand" "=f,f")
13114 (match_operator:DF 3 "binary_fp_operator"
13116 (match_operand:SF 1 "register_operand" "0,f"))
13118 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13119 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13120 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13121 "* return output_387_binary_op (insn, operands);"
13122 [(set (attr "type")
13123 (cond [(match_operand:DF 3 "mult_operator" "")
13124 (const_string "fmul")
13125 (match_operand:DF 3 "div_operator" "")
13126 (const_string "fdiv")
13128 (const_string "fop")))
13129 (set_attr "mode" "SF")])
13131 (define_insn "*fop_xf_comm_i387"
13132 [(set (match_operand:XF 0 "register_operand" "=f")
13133 (match_operator:XF 3 "binary_fp_operator"
13134 [(match_operand:XF 1 "register_operand" "%0")
13135 (match_operand:XF 2 "register_operand" "f")]))]
13137 && COMMUTATIVE_ARITH_P (operands[3])"
13138 "* return output_387_binary_op (insn, operands);"
13139 [(set (attr "type")
13140 (if_then_else (match_operand:XF 3 "mult_operator" "")
13141 (const_string "fmul")
13142 (const_string "fop")))
13143 (set_attr "mode" "XF")])
13145 (define_insn "*fop_xf_1_i387"
13146 [(set (match_operand:XF 0 "register_operand" "=f,f")
13147 (match_operator:XF 3 "binary_fp_operator"
13148 [(match_operand:XF 1 "register_operand" "0,f")
13149 (match_operand:XF 2 "register_operand" "f,0")]))]
13151 && !COMMUTATIVE_ARITH_P (operands[3])"
13152 "* return output_387_binary_op (insn, operands);"
13153 [(set (attr "type")
13154 (cond [(match_operand:XF 3 "mult_operator" "")
13155 (const_string "fmul")
13156 (match_operand:XF 3 "div_operator" "")
13157 (const_string "fdiv")
13159 (const_string "fop")))
13160 (set_attr "mode" "XF")])
13162 (define_insn "*fop_xf_2_i387"
13163 [(set (match_operand:XF 0 "register_operand" "=f,f")
13164 (match_operator:XF 3 "binary_fp_operator"
13166 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13167 (match_operand:XF 2 "register_operand" "0,0")]))]
13168 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13169 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13170 [(set (attr "type")
13171 (cond [(match_operand:XF 3 "mult_operator" "")
13172 (const_string "fmul")
13173 (match_operand:XF 3 "div_operator" "")
13174 (const_string "fdiv")
13176 (const_string "fop")))
13177 (set_attr "fp_int_src" "true")
13178 (set_attr "mode" "<MODE>")])
13180 (define_insn "*fop_xf_3_i387"
13181 [(set (match_operand:XF 0 "register_operand" "=f,f")
13182 (match_operator:XF 3 "binary_fp_operator"
13183 [(match_operand:XF 1 "register_operand" "0,0")
13185 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13186 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13187 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13188 [(set (attr "type")
13189 (cond [(match_operand:XF 3 "mult_operator" "")
13190 (const_string "fmul")
13191 (match_operand:XF 3 "div_operator" "")
13192 (const_string "fdiv")
13194 (const_string "fop")))
13195 (set_attr "fp_int_src" "true")
13196 (set_attr "mode" "<MODE>")])
13198 (define_insn "*fop_xf_4_i387"
13199 [(set (match_operand:XF 0 "register_operand" "=f,f")
13200 (match_operator:XF 3 "binary_fp_operator"
13202 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13203 (match_operand:XF 2 "register_operand" "0,f")]))]
13205 "* return output_387_binary_op (insn, operands);"
13206 [(set (attr "type")
13207 (cond [(match_operand:XF 3 "mult_operator" "")
13208 (const_string "fmul")
13209 (match_operand:XF 3 "div_operator" "")
13210 (const_string "fdiv")
13212 (const_string "fop")))
13213 (set_attr "mode" "<MODE>")])
13215 (define_insn "*fop_xf_5_i387"
13216 [(set (match_operand:XF 0 "register_operand" "=f,f")
13217 (match_operator:XF 3 "binary_fp_operator"
13218 [(match_operand:XF 1 "register_operand" "0,f")
13220 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13222 "* return output_387_binary_op (insn, operands);"
13223 [(set (attr "type")
13224 (cond [(match_operand:XF 3 "mult_operator" "")
13225 (const_string "fmul")
13226 (match_operand:XF 3 "div_operator" "")
13227 (const_string "fdiv")
13229 (const_string "fop")))
13230 (set_attr "mode" "<MODE>")])
13232 (define_insn "*fop_xf_6_i387"
13233 [(set (match_operand:XF 0 "register_operand" "=f,f")
13234 (match_operator:XF 3 "binary_fp_operator"
13236 (match_operand:MODEF 1 "register_operand" "0,f"))
13238 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13240 "* return output_387_binary_op (insn, operands);"
13241 [(set (attr "type")
13242 (cond [(match_operand:XF 3 "mult_operator" "")
13243 (const_string "fmul")
13244 (match_operand:XF 3 "div_operator" "")
13245 (const_string "fdiv")
13247 (const_string "fop")))
13248 (set_attr "mode" "<MODE>")])
13251 [(set (match_operand 0 "register_operand" "")
13252 (match_operator 3 "binary_fp_operator"
13253 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13254 (match_operand 2 "register_operand" "")]))]
13256 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13257 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13260 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13261 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13262 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13263 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13264 GET_MODE (operands[3]),
13267 ix86_free_from_memory (GET_MODE (operands[1]));
13272 [(set (match_operand 0 "register_operand" "")
13273 (match_operator 3 "binary_fp_operator"
13274 [(match_operand 1 "register_operand" "")
13275 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13277 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13278 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13281 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13282 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13283 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13284 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13285 GET_MODE (operands[3]),
13288 ix86_free_from_memory (GET_MODE (operands[2]));
13292 ;; FPU special functions.
13294 ;; This pattern implements a no-op XFmode truncation for
13295 ;; all fancy i386 XFmode math functions.
13297 (define_insn "truncxf<mode>2_i387_noop_unspec"
13298 [(set (match_operand:MODEF 0 "register_operand" "=f")
13299 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13300 UNSPEC_TRUNC_NOOP))]
13301 "TARGET_USE_FANCY_MATH_387"
13302 "* return output_387_reg_move (insn, operands);"
13303 [(set_attr "type" "fmov")
13304 (set_attr "mode" "<MODE>")])
13306 (define_insn "sqrtxf2"
13307 [(set (match_operand:XF 0 "register_operand" "=f")
13308 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13309 "TARGET_USE_FANCY_MATH_387"
13311 [(set_attr "type" "fpspc")
13312 (set_attr "mode" "XF")
13313 (set_attr "athlon_decode" "direct")
13314 (set_attr "amdfam10_decode" "direct")
13315 (set_attr "bdver1_decode" "direct")])
13317 (define_insn "sqrt_extend<mode>xf2_i387"
13318 [(set (match_operand:XF 0 "register_operand" "=f")
13321 (match_operand:MODEF 1 "register_operand" "0"))))]
13322 "TARGET_USE_FANCY_MATH_387"
13324 [(set_attr "type" "fpspc")
13325 (set_attr "mode" "XF")
13326 (set_attr "athlon_decode" "direct")
13327 (set_attr "amdfam10_decode" "direct")
13328 (set_attr "bdver1_decode" "direct")])
13330 (define_insn "*rsqrtsf2_sse"
13331 [(set (match_operand:SF 0 "register_operand" "=x")
13332 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13335 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13336 [(set_attr "type" "sse")
13337 (set_attr "atom_sse_attr" "rcp")
13338 (set_attr "prefix" "maybe_vex")
13339 (set_attr "mode" "SF")])
13341 (define_expand "rsqrtsf2"
13342 [(set (match_operand:SF 0 "register_operand" "")
13343 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13347 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13351 (define_insn "*sqrt<mode>2_sse"
13352 [(set (match_operand:MODEF 0 "register_operand" "=x")
13354 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13355 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13356 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13357 [(set_attr "type" "sse")
13358 (set_attr "atom_sse_attr" "sqrt")
13359 (set_attr "prefix" "maybe_vex")
13360 (set_attr "mode" "<MODE>")
13361 (set_attr "athlon_decode" "*")
13362 (set_attr "amdfam10_decode" "*")
13363 (set_attr "bdver1_decode" "*")])
13365 (define_expand "sqrt<mode>2"
13366 [(set (match_operand:MODEF 0 "register_operand" "")
13368 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13369 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13370 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13372 if (<MODE>mode == SFmode
13373 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13374 && flag_finite_math_only && !flag_trapping_math
13375 && flag_unsafe_math_optimizations)
13377 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13381 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13383 rtx op0 = gen_reg_rtx (XFmode);
13384 rtx op1 = force_reg (<MODE>mode, operands[1]);
13386 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13387 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13392 (define_insn "fpremxf4_i387"
13393 [(set (match_operand:XF 0 "register_operand" "=f")
13394 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13395 (match_operand:XF 3 "register_operand" "1")]
13397 (set (match_operand:XF 1 "register_operand" "=u")
13398 (unspec:XF [(match_dup 2) (match_dup 3)]
13400 (set (reg:CCFP FPSR_REG)
13401 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13403 "TARGET_USE_FANCY_MATH_387"
13405 [(set_attr "type" "fpspc")
13406 (set_attr "mode" "XF")])
13408 (define_expand "fmodxf3"
13409 [(use (match_operand:XF 0 "register_operand" ""))
13410 (use (match_operand:XF 1 "general_operand" ""))
13411 (use (match_operand:XF 2 "general_operand" ""))]
13412 "TARGET_USE_FANCY_MATH_387"
13414 rtx label = gen_label_rtx ();
13416 rtx op1 = gen_reg_rtx (XFmode);
13417 rtx op2 = gen_reg_rtx (XFmode);
13419 emit_move_insn (op2, operands[2]);
13420 emit_move_insn (op1, operands[1]);
13422 emit_label (label);
13423 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13424 ix86_emit_fp_unordered_jump (label);
13425 LABEL_NUSES (label) = 1;
13427 emit_move_insn (operands[0], op1);
13431 (define_expand "fmod<mode>3"
13432 [(use (match_operand:MODEF 0 "register_operand" ""))
13433 (use (match_operand:MODEF 1 "general_operand" ""))
13434 (use (match_operand:MODEF 2 "general_operand" ""))]
13435 "TARGET_USE_FANCY_MATH_387"
13437 rtx (*gen_truncxf) (rtx, rtx);
13439 rtx label = gen_label_rtx ();
13441 rtx op1 = gen_reg_rtx (XFmode);
13442 rtx op2 = gen_reg_rtx (XFmode);
13444 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13445 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13447 emit_label (label);
13448 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13449 ix86_emit_fp_unordered_jump (label);
13450 LABEL_NUSES (label) = 1;
13452 /* Truncate the result properly for strict SSE math. */
13453 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13454 && !TARGET_MIX_SSE_I387)
13455 gen_truncxf = gen_truncxf<mode>2;
13457 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13459 emit_insn (gen_truncxf (operands[0], op1));
13463 (define_insn "fprem1xf4_i387"
13464 [(set (match_operand:XF 0 "register_operand" "=f")
13465 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13466 (match_operand:XF 3 "register_operand" "1")]
13468 (set (match_operand:XF 1 "register_operand" "=u")
13469 (unspec:XF [(match_dup 2) (match_dup 3)]
13471 (set (reg:CCFP FPSR_REG)
13472 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13474 "TARGET_USE_FANCY_MATH_387"
13476 [(set_attr "type" "fpspc")
13477 (set_attr "mode" "XF")])
13479 (define_expand "remainderxf3"
13480 [(use (match_operand:XF 0 "register_operand" ""))
13481 (use (match_operand:XF 1 "general_operand" ""))
13482 (use (match_operand:XF 2 "general_operand" ""))]
13483 "TARGET_USE_FANCY_MATH_387"
13485 rtx label = gen_label_rtx ();
13487 rtx op1 = gen_reg_rtx (XFmode);
13488 rtx op2 = gen_reg_rtx (XFmode);
13490 emit_move_insn (op2, operands[2]);
13491 emit_move_insn (op1, operands[1]);
13493 emit_label (label);
13494 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13495 ix86_emit_fp_unordered_jump (label);
13496 LABEL_NUSES (label) = 1;
13498 emit_move_insn (operands[0], op1);
13502 (define_expand "remainder<mode>3"
13503 [(use (match_operand:MODEF 0 "register_operand" ""))
13504 (use (match_operand:MODEF 1 "general_operand" ""))
13505 (use (match_operand:MODEF 2 "general_operand" ""))]
13506 "TARGET_USE_FANCY_MATH_387"
13508 rtx (*gen_truncxf) (rtx, rtx);
13510 rtx label = gen_label_rtx ();
13512 rtx op1 = gen_reg_rtx (XFmode);
13513 rtx op2 = gen_reg_rtx (XFmode);
13515 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13516 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13518 emit_label (label);
13520 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13521 ix86_emit_fp_unordered_jump (label);
13522 LABEL_NUSES (label) = 1;
13524 /* Truncate the result properly for strict SSE math. */
13525 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13526 && !TARGET_MIX_SSE_I387)
13527 gen_truncxf = gen_truncxf<mode>2;
13529 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13531 emit_insn (gen_truncxf (operands[0], op1));
13535 (define_insn "*sinxf2_i387"
13536 [(set (match_operand:XF 0 "register_operand" "=f")
13537 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13538 "TARGET_USE_FANCY_MATH_387
13539 && flag_unsafe_math_optimizations"
13541 [(set_attr "type" "fpspc")
13542 (set_attr "mode" "XF")])
13544 (define_insn "*sin_extend<mode>xf2_i387"
13545 [(set (match_operand:XF 0 "register_operand" "=f")
13546 (unspec:XF [(float_extend:XF
13547 (match_operand:MODEF 1 "register_operand" "0"))]
13549 "TARGET_USE_FANCY_MATH_387
13550 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13551 || TARGET_MIX_SSE_I387)
13552 && flag_unsafe_math_optimizations"
13554 [(set_attr "type" "fpspc")
13555 (set_attr "mode" "XF")])
13557 (define_insn "*cosxf2_i387"
13558 [(set (match_operand:XF 0 "register_operand" "=f")
13559 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13560 "TARGET_USE_FANCY_MATH_387
13561 && flag_unsafe_math_optimizations"
13563 [(set_attr "type" "fpspc")
13564 (set_attr "mode" "XF")])
13566 (define_insn "*cos_extend<mode>xf2_i387"
13567 [(set (match_operand:XF 0 "register_operand" "=f")
13568 (unspec:XF [(float_extend:XF
13569 (match_operand:MODEF 1 "register_operand" "0"))]
13571 "TARGET_USE_FANCY_MATH_387
13572 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13573 || TARGET_MIX_SSE_I387)
13574 && flag_unsafe_math_optimizations"
13576 [(set_attr "type" "fpspc")
13577 (set_attr "mode" "XF")])
13579 ;; When sincos pattern is defined, sin and cos builtin functions will be
13580 ;; expanded to sincos pattern with one of its outputs left unused.
13581 ;; CSE pass will figure out if two sincos patterns can be combined,
13582 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13583 ;; depending on the unused output.
13585 (define_insn "sincosxf3"
13586 [(set (match_operand:XF 0 "register_operand" "=f")
13587 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13588 UNSPEC_SINCOS_COS))
13589 (set (match_operand:XF 1 "register_operand" "=u")
13590 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13591 "TARGET_USE_FANCY_MATH_387
13592 && flag_unsafe_math_optimizations"
13594 [(set_attr "type" "fpspc")
13595 (set_attr "mode" "XF")])
13598 [(set (match_operand:XF 0 "register_operand" "")
13599 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13600 UNSPEC_SINCOS_COS))
13601 (set (match_operand:XF 1 "register_operand" "")
13602 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13603 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13604 && !(reload_completed || reload_in_progress)"
13605 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13608 [(set (match_operand:XF 0 "register_operand" "")
13609 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13610 UNSPEC_SINCOS_COS))
13611 (set (match_operand:XF 1 "register_operand" "")
13612 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13613 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13614 && !(reload_completed || reload_in_progress)"
13615 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13617 (define_insn "sincos_extend<mode>xf3_i387"
13618 [(set (match_operand:XF 0 "register_operand" "=f")
13619 (unspec:XF [(float_extend:XF
13620 (match_operand:MODEF 2 "register_operand" "0"))]
13621 UNSPEC_SINCOS_COS))
13622 (set (match_operand:XF 1 "register_operand" "=u")
13623 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13624 "TARGET_USE_FANCY_MATH_387
13625 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13626 || TARGET_MIX_SSE_I387)
13627 && flag_unsafe_math_optimizations"
13629 [(set_attr "type" "fpspc")
13630 (set_attr "mode" "XF")])
13633 [(set (match_operand:XF 0 "register_operand" "")
13634 (unspec:XF [(float_extend:XF
13635 (match_operand:MODEF 2 "register_operand" ""))]
13636 UNSPEC_SINCOS_COS))
13637 (set (match_operand:XF 1 "register_operand" "")
13638 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13639 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13640 && !(reload_completed || reload_in_progress)"
13641 [(set (match_dup 1)
13642 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13645 [(set (match_operand:XF 0 "register_operand" "")
13646 (unspec:XF [(float_extend:XF
13647 (match_operand:MODEF 2 "register_operand" ""))]
13648 UNSPEC_SINCOS_COS))
13649 (set (match_operand:XF 1 "register_operand" "")
13650 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13651 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13652 && !(reload_completed || reload_in_progress)"
13653 [(set (match_dup 0)
13654 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13656 (define_expand "sincos<mode>3"
13657 [(use (match_operand:MODEF 0 "register_operand" ""))
13658 (use (match_operand:MODEF 1 "register_operand" ""))
13659 (use (match_operand:MODEF 2 "register_operand" ""))]
13660 "TARGET_USE_FANCY_MATH_387
13661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13662 || TARGET_MIX_SSE_I387)
13663 && flag_unsafe_math_optimizations"
13665 rtx op0 = gen_reg_rtx (XFmode);
13666 rtx op1 = gen_reg_rtx (XFmode);
13668 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13669 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13670 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13674 (define_insn "fptanxf4_i387"
13675 [(set (match_operand:XF 0 "register_operand" "=f")
13676 (match_operand:XF 3 "const_double_operand" "F"))
13677 (set (match_operand:XF 1 "register_operand" "=u")
13678 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13680 "TARGET_USE_FANCY_MATH_387
13681 && flag_unsafe_math_optimizations
13682 && standard_80387_constant_p (operands[3]) == 2"
13684 [(set_attr "type" "fpspc")
13685 (set_attr "mode" "XF")])
13687 (define_insn "fptan_extend<mode>xf4_i387"
13688 [(set (match_operand:MODEF 0 "register_operand" "=f")
13689 (match_operand:MODEF 3 "const_double_operand" "F"))
13690 (set (match_operand:XF 1 "register_operand" "=u")
13691 (unspec:XF [(float_extend:XF
13692 (match_operand:MODEF 2 "register_operand" "0"))]
13694 "TARGET_USE_FANCY_MATH_387
13695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13696 || TARGET_MIX_SSE_I387)
13697 && flag_unsafe_math_optimizations
13698 && standard_80387_constant_p (operands[3]) == 2"
13700 [(set_attr "type" "fpspc")
13701 (set_attr "mode" "XF")])
13703 (define_expand "tanxf2"
13704 [(use (match_operand:XF 0 "register_operand" ""))
13705 (use (match_operand:XF 1 "register_operand" ""))]
13706 "TARGET_USE_FANCY_MATH_387
13707 && flag_unsafe_math_optimizations"
13709 rtx one = gen_reg_rtx (XFmode);
13710 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13712 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13716 (define_expand "tan<mode>2"
13717 [(use (match_operand:MODEF 0 "register_operand" ""))
13718 (use (match_operand:MODEF 1 "register_operand" ""))]
13719 "TARGET_USE_FANCY_MATH_387
13720 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13721 || TARGET_MIX_SSE_I387)
13722 && flag_unsafe_math_optimizations"
13724 rtx op0 = gen_reg_rtx (XFmode);
13726 rtx one = gen_reg_rtx (<MODE>mode);
13727 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13729 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13730 operands[1], op2));
13731 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13735 (define_insn "*fpatanxf3_i387"
13736 [(set (match_operand:XF 0 "register_operand" "=f")
13737 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13738 (match_operand:XF 2 "register_operand" "u")]
13740 (clobber (match_scratch:XF 3 "=2"))]
13741 "TARGET_USE_FANCY_MATH_387
13742 && flag_unsafe_math_optimizations"
13744 [(set_attr "type" "fpspc")
13745 (set_attr "mode" "XF")])
13747 (define_insn "fpatan_extend<mode>xf3_i387"
13748 [(set (match_operand:XF 0 "register_operand" "=f")
13749 (unspec:XF [(float_extend:XF
13750 (match_operand:MODEF 1 "register_operand" "0"))
13752 (match_operand:MODEF 2 "register_operand" "u"))]
13754 (clobber (match_scratch:XF 3 "=2"))]
13755 "TARGET_USE_FANCY_MATH_387
13756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13757 || TARGET_MIX_SSE_I387)
13758 && flag_unsafe_math_optimizations"
13760 [(set_attr "type" "fpspc")
13761 (set_attr "mode" "XF")])
13763 (define_expand "atan2xf3"
13764 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13765 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13766 (match_operand:XF 1 "register_operand" "")]
13768 (clobber (match_scratch:XF 3 ""))])]
13769 "TARGET_USE_FANCY_MATH_387
13770 && flag_unsafe_math_optimizations")
13772 (define_expand "atan2<mode>3"
13773 [(use (match_operand:MODEF 0 "register_operand" ""))
13774 (use (match_operand:MODEF 1 "register_operand" ""))
13775 (use (match_operand:MODEF 2 "register_operand" ""))]
13776 "TARGET_USE_FANCY_MATH_387
13777 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13778 || TARGET_MIX_SSE_I387)
13779 && flag_unsafe_math_optimizations"
13781 rtx op0 = gen_reg_rtx (XFmode);
13783 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13784 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13788 (define_expand "atanxf2"
13789 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13790 (unspec:XF [(match_dup 2)
13791 (match_operand:XF 1 "register_operand" "")]
13793 (clobber (match_scratch:XF 3 ""))])]
13794 "TARGET_USE_FANCY_MATH_387
13795 && flag_unsafe_math_optimizations"
13797 operands[2] = gen_reg_rtx (XFmode);
13798 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13801 (define_expand "atan<mode>2"
13802 [(use (match_operand:MODEF 0 "register_operand" ""))
13803 (use (match_operand:MODEF 1 "register_operand" ""))]
13804 "TARGET_USE_FANCY_MATH_387
13805 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13806 || TARGET_MIX_SSE_I387)
13807 && flag_unsafe_math_optimizations"
13809 rtx op0 = gen_reg_rtx (XFmode);
13811 rtx op2 = gen_reg_rtx (<MODE>mode);
13812 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13814 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13815 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13819 (define_expand "asinxf2"
13820 [(set (match_dup 2)
13821 (mult:XF (match_operand:XF 1 "register_operand" "")
13823 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13824 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13825 (parallel [(set (match_operand:XF 0 "register_operand" "")
13826 (unspec:XF [(match_dup 5) (match_dup 1)]
13828 (clobber (match_scratch:XF 6 ""))])]
13829 "TARGET_USE_FANCY_MATH_387
13830 && flag_unsafe_math_optimizations"
13834 if (optimize_insn_for_size_p ())
13837 for (i = 2; i < 6; i++)
13838 operands[i] = gen_reg_rtx (XFmode);
13840 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13843 (define_expand "asin<mode>2"
13844 [(use (match_operand:MODEF 0 "register_operand" ""))
13845 (use (match_operand:MODEF 1 "general_operand" ""))]
13846 "TARGET_USE_FANCY_MATH_387
13847 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13848 || TARGET_MIX_SSE_I387)
13849 && flag_unsafe_math_optimizations"
13851 rtx op0 = gen_reg_rtx (XFmode);
13852 rtx op1 = gen_reg_rtx (XFmode);
13854 if (optimize_insn_for_size_p ())
13857 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13858 emit_insn (gen_asinxf2 (op0, op1));
13859 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13863 (define_expand "acosxf2"
13864 [(set (match_dup 2)
13865 (mult:XF (match_operand:XF 1 "register_operand" "")
13867 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13868 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13869 (parallel [(set (match_operand:XF 0 "register_operand" "")
13870 (unspec:XF [(match_dup 1) (match_dup 5)]
13872 (clobber (match_scratch:XF 6 ""))])]
13873 "TARGET_USE_FANCY_MATH_387
13874 && flag_unsafe_math_optimizations"
13878 if (optimize_insn_for_size_p ())
13881 for (i = 2; i < 6; i++)
13882 operands[i] = gen_reg_rtx (XFmode);
13884 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13887 (define_expand "acos<mode>2"
13888 [(use (match_operand:MODEF 0 "register_operand" ""))
13889 (use (match_operand:MODEF 1 "general_operand" ""))]
13890 "TARGET_USE_FANCY_MATH_387
13891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13892 || TARGET_MIX_SSE_I387)
13893 && flag_unsafe_math_optimizations"
13895 rtx op0 = gen_reg_rtx (XFmode);
13896 rtx op1 = gen_reg_rtx (XFmode);
13898 if (optimize_insn_for_size_p ())
13901 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13902 emit_insn (gen_acosxf2 (op0, op1));
13903 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13907 (define_insn "fyl2xxf3_i387"
13908 [(set (match_operand:XF 0 "register_operand" "=f")
13909 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13910 (match_operand:XF 2 "register_operand" "u")]
13912 (clobber (match_scratch:XF 3 "=2"))]
13913 "TARGET_USE_FANCY_MATH_387
13914 && flag_unsafe_math_optimizations"
13916 [(set_attr "type" "fpspc")
13917 (set_attr "mode" "XF")])
13919 (define_insn "fyl2x_extend<mode>xf3_i387"
13920 [(set (match_operand:XF 0 "register_operand" "=f")
13921 (unspec:XF [(float_extend:XF
13922 (match_operand:MODEF 1 "register_operand" "0"))
13923 (match_operand:XF 2 "register_operand" "u")]
13925 (clobber (match_scratch:XF 3 "=2"))]
13926 "TARGET_USE_FANCY_MATH_387
13927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13928 || TARGET_MIX_SSE_I387)
13929 && flag_unsafe_math_optimizations"
13931 [(set_attr "type" "fpspc")
13932 (set_attr "mode" "XF")])
13934 (define_expand "logxf2"
13935 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13936 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13937 (match_dup 2)] UNSPEC_FYL2X))
13938 (clobber (match_scratch:XF 3 ""))])]
13939 "TARGET_USE_FANCY_MATH_387
13940 && flag_unsafe_math_optimizations"
13942 operands[2] = gen_reg_rtx (XFmode);
13943 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13946 (define_expand "log<mode>2"
13947 [(use (match_operand:MODEF 0 "register_operand" ""))
13948 (use (match_operand:MODEF 1 "register_operand" ""))]
13949 "TARGET_USE_FANCY_MATH_387
13950 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13951 || TARGET_MIX_SSE_I387)
13952 && flag_unsafe_math_optimizations"
13954 rtx op0 = gen_reg_rtx (XFmode);
13956 rtx op2 = gen_reg_rtx (XFmode);
13957 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13959 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13960 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13964 (define_expand "log10xf2"
13965 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13966 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13967 (match_dup 2)] UNSPEC_FYL2X))
13968 (clobber (match_scratch:XF 3 ""))])]
13969 "TARGET_USE_FANCY_MATH_387
13970 && flag_unsafe_math_optimizations"
13972 operands[2] = gen_reg_rtx (XFmode);
13973 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13976 (define_expand "log10<mode>2"
13977 [(use (match_operand:MODEF 0 "register_operand" ""))
13978 (use (match_operand:MODEF 1 "register_operand" ""))]
13979 "TARGET_USE_FANCY_MATH_387
13980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13981 || TARGET_MIX_SSE_I387)
13982 && flag_unsafe_math_optimizations"
13984 rtx op0 = gen_reg_rtx (XFmode);
13986 rtx op2 = gen_reg_rtx (XFmode);
13987 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13989 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13990 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13994 (define_expand "log2xf2"
13995 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13996 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13997 (match_dup 2)] UNSPEC_FYL2X))
13998 (clobber (match_scratch:XF 3 ""))])]
13999 "TARGET_USE_FANCY_MATH_387
14000 && flag_unsafe_math_optimizations"
14002 operands[2] = gen_reg_rtx (XFmode);
14003 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14006 (define_expand "log2<mode>2"
14007 [(use (match_operand:MODEF 0 "register_operand" ""))
14008 (use (match_operand:MODEF 1 "register_operand" ""))]
14009 "TARGET_USE_FANCY_MATH_387
14010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011 || TARGET_MIX_SSE_I387)
14012 && flag_unsafe_math_optimizations"
14014 rtx op0 = gen_reg_rtx (XFmode);
14016 rtx op2 = gen_reg_rtx (XFmode);
14017 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14019 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14020 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14024 (define_insn "fyl2xp1xf3_i387"
14025 [(set (match_operand:XF 0 "register_operand" "=f")
14026 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14027 (match_operand:XF 2 "register_operand" "u")]
14029 (clobber (match_scratch:XF 3 "=2"))]
14030 "TARGET_USE_FANCY_MATH_387
14031 && flag_unsafe_math_optimizations"
14033 [(set_attr "type" "fpspc")
14034 (set_attr "mode" "XF")])
14036 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14037 [(set (match_operand:XF 0 "register_operand" "=f")
14038 (unspec:XF [(float_extend:XF
14039 (match_operand:MODEF 1 "register_operand" "0"))
14040 (match_operand:XF 2 "register_operand" "u")]
14042 (clobber (match_scratch:XF 3 "=2"))]
14043 "TARGET_USE_FANCY_MATH_387
14044 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14045 || TARGET_MIX_SSE_I387)
14046 && flag_unsafe_math_optimizations"
14048 [(set_attr "type" "fpspc")
14049 (set_attr "mode" "XF")])
14051 (define_expand "log1pxf2"
14052 [(use (match_operand:XF 0 "register_operand" ""))
14053 (use (match_operand:XF 1 "register_operand" ""))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && flag_unsafe_math_optimizations"
14057 if (optimize_insn_for_size_p ())
14060 ix86_emit_i387_log1p (operands[0], operands[1]);
14064 (define_expand "log1p<mode>2"
14065 [(use (match_operand:MODEF 0 "register_operand" ""))
14066 (use (match_operand:MODEF 1 "register_operand" ""))]
14067 "TARGET_USE_FANCY_MATH_387
14068 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14069 || TARGET_MIX_SSE_I387)
14070 && flag_unsafe_math_optimizations"
14074 if (optimize_insn_for_size_p ())
14077 op0 = gen_reg_rtx (XFmode);
14079 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14081 ix86_emit_i387_log1p (op0, operands[1]);
14082 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14086 (define_insn "fxtractxf3_i387"
14087 [(set (match_operand:XF 0 "register_operand" "=f")
14088 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14089 UNSPEC_XTRACT_FRACT))
14090 (set (match_operand:XF 1 "register_operand" "=u")
14091 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14092 "TARGET_USE_FANCY_MATH_387
14093 && flag_unsafe_math_optimizations"
14095 [(set_attr "type" "fpspc")
14096 (set_attr "mode" "XF")])
14098 (define_insn "fxtract_extend<mode>xf3_i387"
14099 [(set (match_operand:XF 0 "register_operand" "=f")
14100 (unspec:XF [(float_extend:XF
14101 (match_operand:MODEF 2 "register_operand" "0"))]
14102 UNSPEC_XTRACT_FRACT))
14103 (set (match_operand:XF 1 "register_operand" "=u")
14104 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14105 "TARGET_USE_FANCY_MATH_387
14106 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14107 || TARGET_MIX_SSE_I387)
14108 && flag_unsafe_math_optimizations"
14110 [(set_attr "type" "fpspc")
14111 (set_attr "mode" "XF")])
14113 (define_expand "logbxf2"
14114 [(parallel [(set (match_dup 2)
14115 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14116 UNSPEC_XTRACT_FRACT))
14117 (set (match_operand:XF 0 "register_operand" "")
14118 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14119 "TARGET_USE_FANCY_MATH_387
14120 && flag_unsafe_math_optimizations"
14121 "operands[2] = gen_reg_rtx (XFmode);")
14123 (define_expand "logb<mode>2"
14124 [(use (match_operand:MODEF 0 "register_operand" ""))
14125 (use (match_operand:MODEF 1 "register_operand" ""))]
14126 "TARGET_USE_FANCY_MATH_387
14127 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14128 || TARGET_MIX_SSE_I387)
14129 && flag_unsafe_math_optimizations"
14131 rtx op0 = gen_reg_rtx (XFmode);
14132 rtx op1 = gen_reg_rtx (XFmode);
14134 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14135 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14139 (define_expand "ilogbxf2"
14140 [(use (match_operand:SI 0 "register_operand" ""))
14141 (use (match_operand:XF 1 "register_operand" ""))]
14142 "TARGET_USE_FANCY_MATH_387
14143 && flag_unsafe_math_optimizations"
14147 if (optimize_insn_for_size_p ())
14150 op0 = gen_reg_rtx (XFmode);
14151 op1 = gen_reg_rtx (XFmode);
14153 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14154 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14158 (define_expand "ilogb<mode>2"
14159 [(use (match_operand:SI 0 "register_operand" ""))
14160 (use (match_operand:MODEF 1 "register_operand" ""))]
14161 "TARGET_USE_FANCY_MATH_387
14162 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14163 || TARGET_MIX_SSE_I387)
14164 && flag_unsafe_math_optimizations"
14168 if (optimize_insn_for_size_p ())
14171 op0 = gen_reg_rtx (XFmode);
14172 op1 = gen_reg_rtx (XFmode);
14174 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14175 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14179 (define_insn "*f2xm1xf2_i387"
14180 [(set (match_operand:XF 0 "register_operand" "=f")
14181 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14183 "TARGET_USE_FANCY_MATH_387
14184 && flag_unsafe_math_optimizations"
14186 [(set_attr "type" "fpspc")
14187 (set_attr "mode" "XF")])
14189 (define_insn "*fscalexf4_i387"
14190 [(set (match_operand:XF 0 "register_operand" "=f")
14191 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14192 (match_operand:XF 3 "register_operand" "1")]
14193 UNSPEC_FSCALE_FRACT))
14194 (set (match_operand:XF 1 "register_operand" "=u")
14195 (unspec:XF [(match_dup 2) (match_dup 3)]
14196 UNSPEC_FSCALE_EXP))]
14197 "TARGET_USE_FANCY_MATH_387
14198 && flag_unsafe_math_optimizations"
14200 [(set_attr "type" "fpspc")
14201 (set_attr "mode" "XF")])
14203 (define_expand "expNcorexf3"
14204 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14205 (match_operand:XF 2 "register_operand" "")))
14206 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14207 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14208 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14209 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14210 (parallel [(set (match_operand:XF 0 "register_operand" "")
14211 (unspec:XF [(match_dup 8) (match_dup 4)]
14212 UNSPEC_FSCALE_FRACT))
14214 (unspec:XF [(match_dup 8) (match_dup 4)]
14215 UNSPEC_FSCALE_EXP))])]
14216 "TARGET_USE_FANCY_MATH_387
14217 && flag_unsafe_math_optimizations"
14221 if (optimize_insn_for_size_p ())
14224 for (i = 3; i < 10; i++)
14225 operands[i] = gen_reg_rtx (XFmode);
14227 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14230 (define_expand "expxf2"
14231 [(use (match_operand:XF 0 "register_operand" ""))
14232 (use (match_operand:XF 1 "register_operand" ""))]
14233 "TARGET_USE_FANCY_MATH_387
14234 && flag_unsafe_math_optimizations"
14238 if (optimize_insn_for_size_p ())
14241 op2 = gen_reg_rtx (XFmode);
14242 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14244 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14248 (define_expand "exp<mode>2"
14249 [(use (match_operand:MODEF 0 "register_operand" ""))
14250 (use (match_operand:MODEF 1 "general_operand" ""))]
14251 "TARGET_USE_FANCY_MATH_387
14252 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14253 || TARGET_MIX_SSE_I387)
14254 && flag_unsafe_math_optimizations"
14258 if (optimize_insn_for_size_p ())
14261 op0 = gen_reg_rtx (XFmode);
14262 op1 = gen_reg_rtx (XFmode);
14264 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14265 emit_insn (gen_expxf2 (op0, op1));
14266 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14270 (define_expand "exp10xf2"
14271 [(use (match_operand:XF 0 "register_operand" ""))
14272 (use (match_operand:XF 1 "register_operand" ""))]
14273 "TARGET_USE_FANCY_MATH_387
14274 && flag_unsafe_math_optimizations"
14278 if (optimize_insn_for_size_p ())
14281 op2 = gen_reg_rtx (XFmode);
14282 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14284 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14288 (define_expand "exp10<mode>2"
14289 [(use (match_operand:MODEF 0 "register_operand" ""))
14290 (use (match_operand:MODEF 1 "general_operand" ""))]
14291 "TARGET_USE_FANCY_MATH_387
14292 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14293 || TARGET_MIX_SSE_I387)
14294 && flag_unsafe_math_optimizations"
14298 if (optimize_insn_for_size_p ())
14301 op0 = gen_reg_rtx (XFmode);
14302 op1 = gen_reg_rtx (XFmode);
14304 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14305 emit_insn (gen_exp10xf2 (op0, op1));
14306 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14310 (define_expand "exp2xf2"
14311 [(use (match_operand:XF 0 "register_operand" ""))
14312 (use (match_operand:XF 1 "register_operand" ""))]
14313 "TARGET_USE_FANCY_MATH_387
14314 && flag_unsafe_math_optimizations"
14318 if (optimize_insn_for_size_p ())
14321 op2 = gen_reg_rtx (XFmode);
14322 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14324 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14328 (define_expand "exp2<mode>2"
14329 [(use (match_operand:MODEF 0 "register_operand" ""))
14330 (use (match_operand:MODEF 1 "general_operand" ""))]
14331 "TARGET_USE_FANCY_MATH_387
14332 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14333 || TARGET_MIX_SSE_I387)
14334 && flag_unsafe_math_optimizations"
14338 if (optimize_insn_for_size_p ())
14341 op0 = gen_reg_rtx (XFmode);
14342 op1 = gen_reg_rtx (XFmode);
14344 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14345 emit_insn (gen_exp2xf2 (op0, op1));
14346 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14350 (define_expand "expm1xf2"
14351 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14353 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14354 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14355 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14356 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14357 (parallel [(set (match_dup 7)
14358 (unspec:XF [(match_dup 6) (match_dup 4)]
14359 UNSPEC_FSCALE_FRACT))
14361 (unspec:XF [(match_dup 6) (match_dup 4)]
14362 UNSPEC_FSCALE_EXP))])
14363 (parallel [(set (match_dup 10)
14364 (unspec:XF [(match_dup 9) (match_dup 8)]
14365 UNSPEC_FSCALE_FRACT))
14366 (set (match_dup 11)
14367 (unspec:XF [(match_dup 9) (match_dup 8)]
14368 UNSPEC_FSCALE_EXP))])
14369 (set (match_dup 12) (minus:XF (match_dup 10)
14370 (float_extend:XF (match_dup 13))))
14371 (set (match_operand:XF 0 "register_operand" "")
14372 (plus:XF (match_dup 12) (match_dup 7)))]
14373 "TARGET_USE_FANCY_MATH_387
14374 && flag_unsafe_math_optimizations"
14378 if (optimize_insn_for_size_p ())
14381 for (i = 2; i < 13; i++)
14382 operands[i] = gen_reg_rtx (XFmode);
14385 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14387 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14390 (define_expand "expm1<mode>2"
14391 [(use (match_operand:MODEF 0 "register_operand" ""))
14392 (use (match_operand:MODEF 1 "general_operand" ""))]
14393 "TARGET_USE_FANCY_MATH_387
14394 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14395 || TARGET_MIX_SSE_I387)
14396 && flag_unsafe_math_optimizations"
14400 if (optimize_insn_for_size_p ())
14403 op0 = gen_reg_rtx (XFmode);
14404 op1 = gen_reg_rtx (XFmode);
14406 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14407 emit_insn (gen_expm1xf2 (op0, op1));
14408 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14412 (define_expand "ldexpxf3"
14413 [(set (match_dup 3)
14414 (float:XF (match_operand:SI 2 "register_operand" "")))
14415 (parallel [(set (match_operand:XF 0 " register_operand" "")
14416 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14418 UNSPEC_FSCALE_FRACT))
14420 (unspec:XF [(match_dup 1) (match_dup 3)]
14421 UNSPEC_FSCALE_EXP))])]
14422 "TARGET_USE_FANCY_MATH_387
14423 && flag_unsafe_math_optimizations"
14425 if (optimize_insn_for_size_p ())
14428 operands[3] = gen_reg_rtx (XFmode);
14429 operands[4] = gen_reg_rtx (XFmode);
14432 (define_expand "ldexp<mode>3"
14433 [(use (match_operand:MODEF 0 "register_operand" ""))
14434 (use (match_operand:MODEF 1 "general_operand" ""))
14435 (use (match_operand:SI 2 "register_operand" ""))]
14436 "TARGET_USE_FANCY_MATH_387
14437 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14438 || TARGET_MIX_SSE_I387)
14439 && flag_unsafe_math_optimizations"
14443 if (optimize_insn_for_size_p ())
14446 op0 = gen_reg_rtx (XFmode);
14447 op1 = gen_reg_rtx (XFmode);
14449 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14450 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14451 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14455 (define_expand "scalbxf3"
14456 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14457 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14458 (match_operand:XF 2 "register_operand" "")]
14459 UNSPEC_FSCALE_FRACT))
14461 (unspec:XF [(match_dup 1) (match_dup 2)]
14462 UNSPEC_FSCALE_EXP))])]
14463 "TARGET_USE_FANCY_MATH_387
14464 && flag_unsafe_math_optimizations"
14466 if (optimize_insn_for_size_p ())
14469 operands[3] = gen_reg_rtx (XFmode);
14472 (define_expand "scalb<mode>3"
14473 [(use (match_operand:MODEF 0 "register_operand" ""))
14474 (use (match_operand:MODEF 1 "general_operand" ""))
14475 (use (match_operand:MODEF 2 "general_operand" ""))]
14476 "TARGET_USE_FANCY_MATH_387
14477 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14478 || TARGET_MIX_SSE_I387)
14479 && flag_unsafe_math_optimizations"
14483 if (optimize_insn_for_size_p ())
14486 op0 = gen_reg_rtx (XFmode);
14487 op1 = gen_reg_rtx (XFmode);
14488 op2 = gen_reg_rtx (XFmode);
14490 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14491 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14492 emit_insn (gen_scalbxf3 (op0, op1, op2));
14493 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14497 (define_expand "significandxf2"
14498 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14499 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14500 UNSPEC_XTRACT_FRACT))
14502 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14503 "TARGET_USE_FANCY_MATH_387
14504 && flag_unsafe_math_optimizations"
14505 "operands[2] = gen_reg_rtx (XFmode);")
14507 (define_expand "significand<mode>2"
14508 [(use (match_operand:MODEF 0 "register_operand" ""))
14509 (use (match_operand:MODEF 1 "register_operand" ""))]
14510 "TARGET_USE_FANCY_MATH_387
14511 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14512 || TARGET_MIX_SSE_I387)
14513 && flag_unsafe_math_optimizations"
14515 rtx op0 = gen_reg_rtx (XFmode);
14516 rtx op1 = gen_reg_rtx (XFmode);
14518 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14519 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14524 (define_insn "sse4_1_round<mode>2"
14525 [(set (match_operand:MODEF 0 "register_operand" "=x")
14526 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14527 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14530 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14531 [(set_attr "type" "ssecvt")
14532 (set_attr "prefix_extra" "1")
14533 (set_attr "prefix" "maybe_vex")
14534 (set_attr "mode" "<MODE>")])
14536 (define_insn "rintxf2"
14537 [(set (match_operand:XF 0 "register_operand" "=f")
14538 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14540 "TARGET_USE_FANCY_MATH_387
14541 && flag_unsafe_math_optimizations"
14543 [(set_attr "type" "fpspc")
14544 (set_attr "mode" "XF")])
14546 (define_expand "rint<mode>2"
14547 [(use (match_operand:MODEF 0 "register_operand" ""))
14548 (use (match_operand:MODEF 1 "register_operand" ""))]
14549 "(TARGET_USE_FANCY_MATH_387
14550 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14551 || TARGET_MIX_SSE_I387)
14552 && flag_unsafe_math_optimizations)
14553 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14554 && !flag_trapping_math)"
14556 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14557 && !flag_trapping_math)
14559 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14562 emit_insn (gen_sse4_1_round<mode>2
14563 (operands[0], operands[1], GEN_INT (0x04)));
14565 ix86_expand_rint (operand0, operand1);
14569 rtx op0 = gen_reg_rtx (XFmode);
14570 rtx op1 = gen_reg_rtx (XFmode);
14572 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14573 emit_insn (gen_rintxf2 (op0, op1));
14575 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14580 (define_expand "round<mode>2"
14581 [(match_operand:MODEF 0 "register_operand" "")
14582 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14583 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14584 && !flag_trapping_math && !flag_rounding_math"
14586 if (optimize_insn_for_size_p ())
14588 if (TARGET_64BIT || (<MODE>mode != DFmode))
14589 ix86_expand_round (operand0, operand1);
14591 ix86_expand_rounddf_32 (operand0, operand1);
14595 (define_insn_and_split "*fistdi2_1"
14596 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14597 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14599 "TARGET_USE_FANCY_MATH_387
14600 && can_create_pseudo_p ()"
14605 if (memory_operand (operands[0], VOIDmode))
14606 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14609 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14610 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14615 [(set_attr "type" "fpspc")
14616 (set_attr "mode" "DI")])
14618 (define_insn "fistdi2"
14619 [(set (match_operand:DI 0 "memory_operand" "=m")
14620 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14622 (clobber (match_scratch:XF 2 "=&1f"))]
14623 "TARGET_USE_FANCY_MATH_387"
14624 "* return output_fix_trunc (insn, operands, 0);"
14625 [(set_attr "type" "fpspc")
14626 (set_attr "mode" "DI")])
14628 (define_insn "fistdi2_with_temp"
14629 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14630 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14632 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14633 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14634 "TARGET_USE_FANCY_MATH_387"
14636 [(set_attr "type" "fpspc")
14637 (set_attr "mode" "DI")])
14640 [(set (match_operand:DI 0 "register_operand" "")
14641 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14643 (clobber (match_operand:DI 2 "memory_operand" ""))
14644 (clobber (match_scratch 3 ""))]
14646 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14647 (clobber (match_dup 3))])
14648 (set (match_dup 0) (match_dup 2))])
14651 [(set (match_operand:DI 0 "memory_operand" "")
14652 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14654 (clobber (match_operand:DI 2 "memory_operand" ""))
14655 (clobber (match_scratch 3 ""))]
14657 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14658 (clobber (match_dup 3))])])
14660 (define_insn_and_split "*fist<mode>2_1"
14661 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14662 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14664 "TARGET_USE_FANCY_MATH_387
14665 && can_create_pseudo_p ()"
14670 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14671 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14675 [(set_attr "type" "fpspc")
14676 (set_attr "mode" "<MODE>")])
14678 (define_insn "fist<mode>2"
14679 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14680 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14682 "TARGET_USE_FANCY_MATH_387"
14683 "* return output_fix_trunc (insn, operands, 0);"
14684 [(set_attr "type" "fpspc")
14685 (set_attr "mode" "<MODE>")])
14687 (define_insn "fist<mode>2_with_temp"
14688 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14689 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14691 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14692 "TARGET_USE_FANCY_MATH_387"
14694 [(set_attr "type" "fpspc")
14695 (set_attr "mode" "<MODE>")])
14698 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14699 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14701 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14703 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14704 (set (match_dup 0) (match_dup 2))])
14707 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14708 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14710 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14712 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14714 (define_expand "lrintxf<mode>2"
14715 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14716 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14718 "TARGET_USE_FANCY_MATH_387")
14720 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14721 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14722 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14723 UNSPEC_FIX_NOTRUNC))]
14724 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14725 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14727 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14728 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14729 (match_operand:MODEF 1 "register_operand" "")]
14730 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14731 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14732 && !flag_trapping_math && !flag_rounding_math"
14734 if (optimize_insn_for_size_p ())
14736 ix86_expand_lround (operand0, operand1);
14740 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14741 (define_insn_and_split "frndintxf2_floor"
14742 [(set (match_operand:XF 0 "register_operand" "")
14743 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14744 UNSPEC_FRNDINT_FLOOR))
14745 (clobber (reg:CC FLAGS_REG))]
14746 "TARGET_USE_FANCY_MATH_387
14747 && flag_unsafe_math_optimizations
14748 && can_create_pseudo_p ()"
14753 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14755 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14756 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14758 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14759 operands[2], operands[3]));
14762 [(set_attr "type" "frndint")
14763 (set_attr "i387_cw" "floor")
14764 (set_attr "mode" "XF")])
14766 (define_insn "frndintxf2_floor_i387"
14767 [(set (match_operand:XF 0 "register_operand" "=f")
14768 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14769 UNSPEC_FRNDINT_FLOOR))
14770 (use (match_operand:HI 2 "memory_operand" "m"))
14771 (use (match_operand:HI 3 "memory_operand" "m"))]
14772 "TARGET_USE_FANCY_MATH_387
14773 && flag_unsafe_math_optimizations"
14774 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14775 [(set_attr "type" "frndint")
14776 (set_attr "i387_cw" "floor")
14777 (set_attr "mode" "XF")])
14779 (define_expand "floorxf2"
14780 [(use (match_operand:XF 0 "register_operand" ""))
14781 (use (match_operand:XF 1 "register_operand" ""))]
14782 "TARGET_USE_FANCY_MATH_387
14783 && flag_unsafe_math_optimizations"
14785 if (optimize_insn_for_size_p ())
14787 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14791 (define_expand "floor<mode>2"
14792 [(use (match_operand:MODEF 0 "register_operand" ""))
14793 (use (match_operand:MODEF 1 "register_operand" ""))]
14794 "(TARGET_USE_FANCY_MATH_387
14795 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14796 || TARGET_MIX_SSE_I387)
14797 && flag_unsafe_math_optimizations)
14798 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14799 && !flag_trapping_math)"
14801 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14802 && !flag_trapping_math
14803 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14805 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14808 emit_insn (gen_sse4_1_round<mode>2
14809 (operands[0], operands[1], GEN_INT (0x01)));
14810 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14811 ix86_expand_floorceil (operand0, operand1, true);
14813 ix86_expand_floorceildf_32 (operand0, operand1, true);
14819 if (optimize_insn_for_size_p ())
14822 op0 = gen_reg_rtx (XFmode);
14823 op1 = gen_reg_rtx (XFmode);
14824 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14825 emit_insn (gen_frndintxf2_floor (op0, op1));
14827 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14832 (define_insn_and_split "*fist<mode>2_floor_1"
14833 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14834 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14835 UNSPEC_FIST_FLOOR))
14836 (clobber (reg:CC FLAGS_REG))]
14837 "TARGET_USE_FANCY_MATH_387
14838 && flag_unsafe_math_optimizations
14839 && can_create_pseudo_p ()"
14844 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14846 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14847 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14848 if (memory_operand (operands[0], VOIDmode))
14849 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14850 operands[2], operands[3]));
14853 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14854 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14855 operands[2], operands[3],
14860 [(set_attr "type" "fistp")
14861 (set_attr "i387_cw" "floor")
14862 (set_attr "mode" "<MODE>")])
14864 (define_insn "fistdi2_floor"
14865 [(set (match_operand:DI 0 "memory_operand" "=m")
14866 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14867 UNSPEC_FIST_FLOOR))
14868 (use (match_operand:HI 2 "memory_operand" "m"))
14869 (use (match_operand:HI 3 "memory_operand" "m"))
14870 (clobber (match_scratch:XF 4 "=&1f"))]
14871 "TARGET_USE_FANCY_MATH_387
14872 && flag_unsafe_math_optimizations"
14873 "* return output_fix_trunc (insn, operands, 0);"
14874 [(set_attr "type" "fistp")
14875 (set_attr "i387_cw" "floor")
14876 (set_attr "mode" "DI")])
14878 (define_insn "fistdi2_floor_with_temp"
14879 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14880 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14881 UNSPEC_FIST_FLOOR))
14882 (use (match_operand:HI 2 "memory_operand" "m,m"))
14883 (use (match_operand:HI 3 "memory_operand" "m,m"))
14884 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14885 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14886 "TARGET_USE_FANCY_MATH_387
14887 && flag_unsafe_math_optimizations"
14889 [(set_attr "type" "fistp")
14890 (set_attr "i387_cw" "floor")
14891 (set_attr "mode" "DI")])
14894 [(set (match_operand:DI 0 "register_operand" "")
14895 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14896 UNSPEC_FIST_FLOOR))
14897 (use (match_operand:HI 2 "memory_operand" ""))
14898 (use (match_operand:HI 3 "memory_operand" ""))
14899 (clobber (match_operand:DI 4 "memory_operand" ""))
14900 (clobber (match_scratch 5 ""))]
14902 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14903 (use (match_dup 2))
14904 (use (match_dup 3))
14905 (clobber (match_dup 5))])
14906 (set (match_dup 0) (match_dup 4))])
14909 [(set (match_operand:DI 0 "memory_operand" "")
14910 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14911 UNSPEC_FIST_FLOOR))
14912 (use (match_operand:HI 2 "memory_operand" ""))
14913 (use (match_operand:HI 3 "memory_operand" ""))
14914 (clobber (match_operand:DI 4 "memory_operand" ""))
14915 (clobber (match_scratch 5 ""))]
14917 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14918 (use (match_dup 2))
14919 (use (match_dup 3))
14920 (clobber (match_dup 5))])])
14922 (define_insn "fist<mode>2_floor"
14923 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14924 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14925 UNSPEC_FIST_FLOOR))
14926 (use (match_operand:HI 2 "memory_operand" "m"))
14927 (use (match_operand:HI 3 "memory_operand" "m"))]
14928 "TARGET_USE_FANCY_MATH_387
14929 && flag_unsafe_math_optimizations"
14930 "* return output_fix_trunc (insn, operands, 0);"
14931 [(set_attr "type" "fistp")
14932 (set_attr "i387_cw" "floor")
14933 (set_attr "mode" "<MODE>")])
14935 (define_insn "fist<mode>2_floor_with_temp"
14936 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14937 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14938 UNSPEC_FIST_FLOOR))
14939 (use (match_operand:HI 2 "memory_operand" "m,m"))
14940 (use (match_operand:HI 3 "memory_operand" "m,m"))
14941 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14942 "TARGET_USE_FANCY_MATH_387
14943 && flag_unsafe_math_optimizations"
14945 [(set_attr "type" "fistp")
14946 (set_attr "i387_cw" "floor")
14947 (set_attr "mode" "<MODE>")])
14950 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14951 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14952 UNSPEC_FIST_FLOOR))
14953 (use (match_operand:HI 2 "memory_operand" ""))
14954 (use (match_operand:HI 3 "memory_operand" ""))
14955 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14957 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14958 UNSPEC_FIST_FLOOR))
14959 (use (match_dup 2))
14960 (use (match_dup 3))])
14961 (set (match_dup 0) (match_dup 4))])
14964 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14965 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14966 UNSPEC_FIST_FLOOR))
14967 (use (match_operand:HI 2 "memory_operand" ""))
14968 (use (match_operand:HI 3 "memory_operand" ""))
14969 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14971 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14972 UNSPEC_FIST_FLOOR))
14973 (use (match_dup 2))
14974 (use (match_dup 3))])])
14976 (define_expand "lfloorxf<mode>2"
14977 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14978 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14979 UNSPEC_FIST_FLOOR))
14980 (clobber (reg:CC FLAGS_REG))])]
14981 "TARGET_USE_FANCY_MATH_387
14982 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14983 && flag_unsafe_math_optimizations")
14985 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14986 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14987 (match_operand:MODEF 1 "register_operand" "")]
14988 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14989 && !flag_trapping_math"
14991 if (TARGET_64BIT && optimize_insn_for_size_p ())
14993 ix86_expand_lfloorceil (operand0, operand1, true);
14997 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14998 (define_insn_and_split "frndintxf2_ceil"
14999 [(set (match_operand:XF 0 "register_operand" "")
15000 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15001 UNSPEC_FRNDINT_CEIL))
15002 (clobber (reg:CC FLAGS_REG))]
15003 "TARGET_USE_FANCY_MATH_387
15004 && flag_unsafe_math_optimizations
15005 && can_create_pseudo_p ()"
15010 ix86_optimize_mode_switching[I387_CEIL] = 1;
15012 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15013 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15015 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15016 operands[2], operands[3]));
15019 [(set_attr "type" "frndint")
15020 (set_attr "i387_cw" "ceil")
15021 (set_attr "mode" "XF")])
15023 (define_insn "frndintxf2_ceil_i387"
15024 [(set (match_operand:XF 0 "register_operand" "=f")
15025 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15026 UNSPEC_FRNDINT_CEIL))
15027 (use (match_operand:HI 2 "memory_operand" "m"))
15028 (use (match_operand:HI 3 "memory_operand" "m"))]
15029 "TARGET_USE_FANCY_MATH_387
15030 && flag_unsafe_math_optimizations"
15031 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15032 [(set_attr "type" "frndint")
15033 (set_attr "i387_cw" "ceil")
15034 (set_attr "mode" "XF")])
15036 (define_expand "ceilxf2"
15037 [(use (match_operand:XF 0 "register_operand" ""))
15038 (use (match_operand:XF 1 "register_operand" ""))]
15039 "TARGET_USE_FANCY_MATH_387
15040 && flag_unsafe_math_optimizations"
15042 if (optimize_insn_for_size_p ())
15044 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15048 (define_expand "ceil<mode>2"
15049 [(use (match_operand:MODEF 0 "register_operand" ""))
15050 (use (match_operand:MODEF 1 "register_operand" ""))]
15051 "(TARGET_USE_FANCY_MATH_387
15052 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15053 || TARGET_MIX_SSE_I387)
15054 && flag_unsafe_math_optimizations)
15055 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15056 && !flag_trapping_math)"
15058 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15059 && !flag_trapping_math
15060 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15063 emit_insn (gen_sse4_1_round<mode>2
15064 (operands[0], operands[1], GEN_INT (0x02)));
15065 else if (optimize_insn_for_size_p ())
15067 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15068 ix86_expand_floorceil (operand0, operand1, false);
15070 ix86_expand_floorceildf_32 (operand0, operand1, false);
15076 if (optimize_insn_for_size_p ())
15079 op0 = gen_reg_rtx (XFmode);
15080 op1 = gen_reg_rtx (XFmode);
15081 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15082 emit_insn (gen_frndintxf2_ceil (op0, op1));
15084 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15089 (define_insn_and_split "*fist<mode>2_ceil_1"
15090 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15091 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15093 (clobber (reg:CC FLAGS_REG))]
15094 "TARGET_USE_FANCY_MATH_387
15095 && flag_unsafe_math_optimizations
15096 && can_create_pseudo_p ()"
15101 ix86_optimize_mode_switching[I387_CEIL] = 1;
15103 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15104 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15105 if (memory_operand (operands[0], VOIDmode))
15106 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15107 operands[2], operands[3]));
15110 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15111 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15112 operands[2], operands[3],
15117 [(set_attr "type" "fistp")
15118 (set_attr "i387_cw" "ceil")
15119 (set_attr "mode" "<MODE>")])
15121 (define_insn "fistdi2_ceil"
15122 [(set (match_operand:DI 0 "memory_operand" "=m")
15123 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15125 (use (match_operand:HI 2 "memory_operand" "m"))
15126 (use (match_operand:HI 3 "memory_operand" "m"))
15127 (clobber (match_scratch:XF 4 "=&1f"))]
15128 "TARGET_USE_FANCY_MATH_387
15129 && flag_unsafe_math_optimizations"
15130 "* return output_fix_trunc (insn, operands, 0);"
15131 [(set_attr "type" "fistp")
15132 (set_attr "i387_cw" "ceil")
15133 (set_attr "mode" "DI")])
15135 (define_insn "fistdi2_ceil_with_temp"
15136 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15137 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15139 (use (match_operand:HI 2 "memory_operand" "m,m"))
15140 (use (match_operand:HI 3 "memory_operand" "m,m"))
15141 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15142 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15143 "TARGET_USE_FANCY_MATH_387
15144 && flag_unsafe_math_optimizations"
15146 [(set_attr "type" "fistp")
15147 (set_attr "i387_cw" "ceil")
15148 (set_attr "mode" "DI")])
15151 [(set (match_operand:DI 0 "register_operand" "")
15152 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15154 (use (match_operand:HI 2 "memory_operand" ""))
15155 (use (match_operand:HI 3 "memory_operand" ""))
15156 (clobber (match_operand:DI 4 "memory_operand" ""))
15157 (clobber (match_scratch 5 ""))]
15159 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15160 (use (match_dup 2))
15161 (use (match_dup 3))
15162 (clobber (match_dup 5))])
15163 (set (match_dup 0) (match_dup 4))])
15166 [(set (match_operand:DI 0 "memory_operand" "")
15167 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15169 (use (match_operand:HI 2 "memory_operand" ""))
15170 (use (match_operand:HI 3 "memory_operand" ""))
15171 (clobber (match_operand:DI 4 "memory_operand" ""))
15172 (clobber (match_scratch 5 ""))]
15174 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15175 (use (match_dup 2))
15176 (use (match_dup 3))
15177 (clobber (match_dup 5))])])
15179 (define_insn "fist<mode>2_ceil"
15180 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15181 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15183 (use (match_operand:HI 2 "memory_operand" "m"))
15184 (use (match_operand:HI 3 "memory_operand" "m"))]
15185 "TARGET_USE_FANCY_MATH_387
15186 && flag_unsafe_math_optimizations"
15187 "* return output_fix_trunc (insn, operands, 0);"
15188 [(set_attr "type" "fistp")
15189 (set_attr "i387_cw" "ceil")
15190 (set_attr "mode" "<MODE>")])
15192 (define_insn "fist<mode>2_ceil_with_temp"
15193 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15194 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15196 (use (match_operand:HI 2 "memory_operand" "m,m"))
15197 (use (match_operand:HI 3 "memory_operand" "m,m"))
15198 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15199 "TARGET_USE_FANCY_MATH_387
15200 && flag_unsafe_math_optimizations"
15202 [(set_attr "type" "fistp")
15203 (set_attr "i387_cw" "ceil")
15204 (set_attr "mode" "<MODE>")])
15207 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15208 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15210 (use (match_operand:HI 2 "memory_operand" ""))
15211 (use (match_operand:HI 3 "memory_operand" ""))
15212 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15214 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15216 (use (match_dup 2))
15217 (use (match_dup 3))])
15218 (set (match_dup 0) (match_dup 4))])
15221 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15222 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15224 (use (match_operand:HI 2 "memory_operand" ""))
15225 (use (match_operand:HI 3 "memory_operand" ""))
15226 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15228 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15230 (use (match_dup 2))
15231 (use (match_dup 3))])])
15233 (define_expand "lceilxf<mode>2"
15234 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15235 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15237 (clobber (reg:CC FLAGS_REG))])]
15238 "TARGET_USE_FANCY_MATH_387
15239 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15240 && flag_unsafe_math_optimizations")
15242 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15243 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15244 (match_operand:MODEF 1 "register_operand" "")]
15245 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15246 && !flag_trapping_math"
15248 ix86_expand_lfloorceil (operand0, operand1, false);
15252 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15253 (define_insn_and_split "frndintxf2_trunc"
15254 [(set (match_operand:XF 0 "register_operand" "")
15255 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15256 UNSPEC_FRNDINT_TRUNC))
15257 (clobber (reg:CC FLAGS_REG))]
15258 "TARGET_USE_FANCY_MATH_387
15259 && flag_unsafe_math_optimizations
15260 && can_create_pseudo_p ()"
15265 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15267 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15268 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15270 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15271 operands[2], operands[3]));
15274 [(set_attr "type" "frndint")
15275 (set_attr "i387_cw" "trunc")
15276 (set_attr "mode" "XF")])
15278 (define_insn "frndintxf2_trunc_i387"
15279 [(set (match_operand:XF 0 "register_operand" "=f")
15280 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15281 UNSPEC_FRNDINT_TRUNC))
15282 (use (match_operand:HI 2 "memory_operand" "m"))
15283 (use (match_operand:HI 3 "memory_operand" "m"))]
15284 "TARGET_USE_FANCY_MATH_387
15285 && flag_unsafe_math_optimizations"
15286 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15287 [(set_attr "type" "frndint")
15288 (set_attr "i387_cw" "trunc")
15289 (set_attr "mode" "XF")])
15291 (define_expand "btruncxf2"
15292 [(use (match_operand:XF 0 "register_operand" ""))
15293 (use (match_operand:XF 1 "register_operand" ""))]
15294 "TARGET_USE_FANCY_MATH_387
15295 && flag_unsafe_math_optimizations"
15297 if (optimize_insn_for_size_p ())
15299 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15303 (define_expand "btrunc<mode>2"
15304 [(use (match_operand:MODEF 0 "register_operand" ""))
15305 (use (match_operand:MODEF 1 "register_operand" ""))]
15306 "(TARGET_USE_FANCY_MATH_387
15307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15308 || TARGET_MIX_SSE_I387)
15309 && flag_unsafe_math_optimizations)
15310 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15311 && !flag_trapping_math)"
15313 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15314 && !flag_trapping_math
15315 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15318 emit_insn (gen_sse4_1_round<mode>2
15319 (operands[0], operands[1], GEN_INT (0x03)));
15320 else if (optimize_insn_for_size_p ())
15322 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15323 ix86_expand_trunc (operand0, operand1);
15325 ix86_expand_truncdf_32 (operand0, operand1);
15331 if (optimize_insn_for_size_p ())
15334 op0 = gen_reg_rtx (XFmode);
15335 op1 = gen_reg_rtx (XFmode);
15336 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15337 emit_insn (gen_frndintxf2_trunc (op0, op1));
15339 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15344 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15345 (define_insn_and_split "frndintxf2_mask_pm"
15346 [(set (match_operand:XF 0 "register_operand" "")
15347 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15348 UNSPEC_FRNDINT_MASK_PM))
15349 (clobber (reg:CC FLAGS_REG))]
15350 "TARGET_USE_FANCY_MATH_387
15351 && flag_unsafe_math_optimizations
15352 && can_create_pseudo_p ()"
15357 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15359 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15360 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15362 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15363 operands[2], operands[3]));
15366 [(set_attr "type" "frndint")
15367 (set_attr "i387_cw" "mask_pm")
15368 (set_attr "mode" "XF")])
15370 (define_insn "frndintxf2_mask_pm_i387"
15371 [(set (match_operand:XF 0 "register_operand" "=f")
15372 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15373 UNSPEC_FRNDINT_MASK_PM))
15374 (use (match_operand:HI 2 "memory_operand" "m"))
15375 (use (match_operand:HI 3 "memory_operand" "m"))]
15376 "TARGET_USE_FANCY_MATH_387
15377 && flag_unsafe_math_optimizations"
15378 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15379 [(set_attr "type" "frndint")
15380 (set_attr "i387_cw" "mask_pm")
15381 (set_attr "mode" "XF")])
15383 (define_expand "nearbyintxf2"
15384 [(use (match_operand:XF 0 "register_operand" ""))
15385 (use (match_operand:XF 1 "register_operand" ""))]
15386 "TARGET_USE_FANCY_MATH_387
15387 && flag_unsafe_math_optimizations"
15389 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15393 (define_expand "nearbyint<mode>2"
15394 [(use (match_operand:MODEF 0 "register_operand" ""))
15395 (use (match_operand:MODEF 1 "register_operand" ""))]
15396 "TARGET_USE_FANCY_MATH_387
15397 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15398 || TARGET_MIX_SSE_I387)
15399 && flag_unsafe_math_optimizations"
15401 rtx op0 = gen_reg_rtx (XFmode);
15402 rtx op1 = gen_reg_rtx (XFmode);
15404 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15405 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15407 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15411 (define_insn "fxam<mode>2_i387"
15412 [(set (match_operand:HI 0 "register_operand" "=a")
15414 [(match_operand:X87MODEF 1 "register_operand" "f")]
15416 "TARGET_USE_FANCY_MATH_387"
15417 "fxam\n\tfnstsw\t%0"
15418 [(set_attr "type" "multi")
15419 (set_attr "length" "4")
15420 (set_attr "unit" "i387")
15421 (set_attr "mode" "<MODE>")])
15423 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15424 [(set (match_operand:HI 0 "register_operand" "")
15426 [(match_operand:MODEF 1 "memory_operand" "")]
15428 "TARGET_USE_FANCY_MATH_387
15429 && can_create_pseudo_p ()"
15432 [(set (match_dup 2)(match_dup 1))
15434 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15436 operands[2] = gen_reg_rtx (<MODE>mode);
15438 MEM_VOLATILE_P (operands[1]) = 1;
15440 [(set_attr "type" "multi")
15441 (set_attr "unit" "i387")
15442 (set_attr "mode" "<MODE>")])
15444 (define_expand "isinfxf2"
15445 [(use (match_operand:SI 0 "register_operand" ""))
15446 (use (match_operand:XF 1 "register_operand" ""))]
15447 "TARGET_USE_FANCY_MATH_387
15448 && TARGET_C99_FUNCTIONS"
15450 rtx mask = GEN_INT (0x45);
15451 rtx val = GEN_INT (0x05);
15455 rtx scratch = gen_reg_rtx (HImode);
15456 rtx res = gen_reg_rtx (QImode);
15458 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15460 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15461 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15462 cond = gen_rtx_fmt_ee (EQ, QImode,
15463 gen_rtx_REG (CCmode, FLAGS_REG),
15465 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15466 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15470 (define_expand "isinf<mode>2"
15471 [(use (match_operand:SI 0 "register_operand" ""))
15472 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15473 "TARGET_USE_FANCY_MATH_387
15474 && TARGET_C99_FUNCTIONS
15475 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15477 rtx mask = GEN_INT (0x45);
15478 rtx val = GEN_INT (0x05);
15482 rtx scratch = gen_reg_rtx (HImode);
15483 rtx res = gen_reg_rtx (QImode);
15485 /* Remove excess precision by forcing value through memory. */
15486 if (memory_operand (operands[1], VOIDmode))
15487 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15490 enum ix86_stack_slot slot = (virtuals_instantiated
15493 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15495 emit_move_insn (temp, operands[1]);
15496 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15499 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15500 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15501 cond = gen_rtx_fmt_ee (EQ, QImode,
15502 gen_rtx_REG (CCmode, FLAGS_REG),
15504 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15505 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15509 (define_expand "signbitxf2"
15510 [(use (match_operand:SI 0 "register_operand" ""))
15511 (use (match_operand:XF 1 "register_operand" ""))]
15512 "TARGET_USE_FANCY_MATH_387"
15514 rtx scratch = gen_reg_rtx (HImode);
15516 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15517 emit_insn (gen_andsi3 (operands[0],
15518 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15522 (define_insn "movmsk_df"
15523 [(set (match_operand:SI 0 "register_operand" "=r")
15525 [(match_operand:DF 1 "register_operand" "x")]
15527 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15528 "%vmovmskpd\t{%1, %0|%0, %1}"
15529 [(set_attr "type" "ssemov")
15530 (set_attr "prefix" "maybe_vex")
15531 (set_attr "mode" "DF")])
15533 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15534 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15535 (define_expand "signbitdf2"
15536 [(use (match_operand:SI 0 "register_operand" ""))
15537 (use (match_operand:DF 1 "register_operand" ""))]
15538 "TARGET_USE_FANCY_MATH_387
15539 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15541 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15543 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15544 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15548 rtx scratch = gen_reg_rtx (HImode);
15550 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15551 emit_insn (gen_andsi3 (operands[0],
15552 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15557 (define_expand "signbitsf2"
15558 [(use (match_operand:SI 0 "register_operand" ""))
15559 (use (match_operand:SF 1 "register_operand" ""))]
15560 "TARGET_USE_FANCY_MATH_387
15561 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15563 rtx scratch = gen_reg_rtx (HImode);
15565 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15566 emit_insn (gen_andsi3 (operands[0],
15567 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15571 ;; Block operation instructions
15574 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15577 [(set_attr "length" "1")
15578 (set_attr "length_immediate" "0")
15579 (set_attr "modrm" "0")])
15581 (define_expand "movmem<mode>"
15582 [(use (match_operand:BLK 0 "memory_operand" ""))
15583 (use (match_operand:BLK 1 "memory_operand" ""))
15584 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15585 (use (match_operand:SWI48 3 "const_int_operand" ""))
15586 (use (match_operand:SI 4 "const_int_operand" ""))
15587 (use (match_operand:SI 5 "const_int_operand" ""))]
15590 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15591 operands[4], operands[5]))
15597 ;; Most CPUs don't like single string operations
15598 ;; Handle this case here to simplify previous expander.
15600 (define_expand "strmov"
15601 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15602 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15603 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15604 (clobber (reg:CC FLAGS_REG))])
15605 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15606 (clobber (reg:CC FLAGS_REG))])]
15609 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15611 /* If .md ever supports :P for Pmode, these can be directly
15612 in the pattern above. */
15613 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15614 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15616 /* Can't use this if the user has appropriated esi or edi. */
15617 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15618 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15620 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15621 operands[2], operands[3],
15622 operands[5], operands[6]));
15626 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15629 (define_expand "strmov_singleop"
15630 [(parallel [(set (match_operand 1 "memory_operand" "")
15631 (match_operand 3 "memory_operand" ""))
15632 (set (match_operand 0 "register_operand" "")
15633 (match_operand 4 "" ""))
15634 (set (match_operand 2 "register_operand" "")
15635 (match_operand 5 "" ""))])]
15637 "ix86_current_function_needs_cld = 1;")
15639 (define_insn "*strmovdi_rex_1"
15640 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15641 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15642 (set (match_operand:DI 0 "register_operand" "=D")
15643 (plus:DI (match_dup 2)
15645 (set (match_operand:DI 1 "register_operand" "=S")
15646 (plus:DI (match_dup 3)
15650 [(set_attr "type" "str")
15651 (set_attr "memory" "both")
15652 (set_attr "mode" "DI")])
15654 (define_insn "*strmovsi_1"
15655 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15656 (mem:SI (match_operand:P 3 "register_operand" "1")))
15657 (set (match_operand:P 0 "register_operand" "=D")
15658 (plus:P (match_dup 2)
15660 (set (match_operand:P 1 "register_operand" "=S")
15661 (plus:P (match_dup 3)
15665 [(set_attr "type" "str")
15666 (set_attr "memory" "both")
15667 (set_attr "mode" "SI")])
15669 (define_insn "*strmovhi_1"
15670 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15671 (mem:HI (match_operand:P 3 "register_operand" "1")))
15672 (set (match_operand:P 0 "register_operand" "=D")
15673 (plus:P (match_dup 2)
15675 (set (match_operand:P 1 "register_operand" "=S")
15676 (plus:P (match_dup 3)
15680 [(set_attr "type" "str")
15681 (set_attr "memory" "both")
15682 (set_attr "mode" "HI")])
15684 (define_insn "*strmovqi_1"
15685 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15686 (mem:QI (match_operand:P 3 "register_operand" "1")))
15687 (set (match_operand:P 0 "register_operand" "=D")
15688 (plus:P (match_dup 2)
15690 (set (match_operand:P 1 "register_operand" "=S")
15691 (plus:P (match_dup 3)
15695 [(set_attr "type" "str")
15696 (set_attr "memory" "both")
15697 (set (attr "prefix_rex")
15699 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15701 (const_string "*")))
15702 (set_attr "mode" "QI")])
15704 (define_expand "rep_mov"
15705 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15706 (set (match_operand 0 "register_operand" "")
15707 (match_operand 5 "" ""))
15708 (set (match_operand 2 "register_operand" "")
15709 (match_operand 6 "" ""))
15710 (set (match_operand 1 "memory_operand" "")
15711 (match_operand 3 "memory_operand" ""))
15712 (use (match_dup 4))])]
15714 "ix86_current_function_needs_cld = 1;")
15716 (define_insn "*rep_movdi_rex64"
15717 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15718 (set (match_operand:DI 0 "register_operand" "=D")
15719 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15721 (match_operand:DI 3 "register_operand" "0")))
15722 (set (match_operand:DI 1 "register_operand" "=S")
15723 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15724 (match_operand:DI 4 "register_operand" "1")))
15725 (set (mem:BLK (match_dup 3))
15726 (mem:BLK (match_dup 4)))
15727 (use (match_dup 5))]
15730 [(set_attr "type" "str")
15731 (set_attr "prefix_rep" "1")
15732 (set_attr "memory" "both")
15733 (set_attr "mode" "DI")])
15735 (define_insn "*rep_movsi"
15736 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15737 (set (match_operand:P 0 "register_operand" "=D")
15738 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15740 (match_operand:P 3 "register_operand" "0")))
15741 (set (match_operand:P 1 "register_operand" "=S")
15742 (plus:P (ashift:P (match_dup 5) (const_int 2))
15743 (match_operand:P 4 "register_operand" "1")))
15744 (set (mem:BLK (match_dup 3))
15745 (mem:BLK (match_dup 4)))
15746 (use (match_dup 5))]
15748 "rep{%;} movs{l|d}"
15749 [(set_attr "type" "str")
15750 (set_attr "prefix_rep" "1")
15751 (set_attr "memory" "both")
15752 (set_attr "mode" "SI")])
15754 (define_insn "*rep_movqi"
15755 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15756 (set (match_operand:P 0 "register_operand" "=D")
15757 (plus:P (match_operand:P 3 "register_operand" "0")
15758 (match_operand:P 5 "register_operand" "2")))
15759 (set (match_operand:P 1 "register_operand" "=S")
15760 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15761 (set (mem:BLK (match_dup 3))
15762 (mem:BLK (match_dup 4)))
15763 (use (match_dup 5))]
15766 [(set_attr "type" "str")
15767 (set_attr "prefix_rep" "1")
15768 (set_attr "memory" "both")
15769 (set_attr "mode" "QI")])
15771 (define_expand "setmem<mode>"
15772 [(use (match_operand:BLK 0 "memory_operand" ""))
15773 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15774 (use (match_operand 2 "const_int_operand" ""))
15775 (use (match_operand 3 "const_int_operand" ""))
15776 (use (match_operand:SI 4 "const_int_operand" ""))
15777 (use (match_operand:SI 5 "const_int_operand" ""))]
15780 if (ix86_expand_setmem (operands[0], operands[1],
15781 operands[2], operands[3],
15782 operands[4], operands[5]))
15788 ;; Most CPUs don't like single string operations
15789 ;; Handle this case here to simplify previous expander.
15791 (define_expand "strset"
15792 [(set (match_operand 1 "memory_operand" "")
15793 (match_operand 2 "register_operand" ""))
15794 (parallel [(set (match_operand 0 "register_operand" "")
15796 (clobber (reg:CC FLAGS_REG))])]
15799 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15800 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15802 /* If .md ever supports :P for Pmode, this can be directly
15803 in the pattern above. */
15804 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15805 GEN_INT (GET_MODE_SIZE (GET_MODE
15807 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15809 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15815 (define_expand "strset_singleop"
15816 [(parallel [(set (match_operand 1 "memory_operand" "")
15817 (match_operand 2 "register_operand" ""))
15818 (set (match_operand 0 "register_operand" "")
15819 (match_operand 3 "" ""))])]
15821 "ix86_current_function_needs_cld = 1;")
15823 (define_insn "*strsetdi_rex_1"
15824 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15825 (match_operand:DI 2 "register_operand" "a"))
15826 (set (match_operand:DI 0 "register_operand" "=D")
15827 (plus:DI (match_dup 1)
15831 [(set_attr "type" "str")
15832 (set_attr "memory" "store")
15833 (set_attr "mode" "DI")])
15835 (define_insn "*strsetsi_1"
15836 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15837 (match_operand:SI 2 "register_operand" "a"))
15838 (set (match_operand:P 0 "register_operand" "=D")
15839 (plus:P (match_dup 1)
15843 [(set_attr "type" "str")
15844 (set_attr "memory" "store")
15845 (set_attr "mode" "SI")])
15847 (define_insn "*strsethi_1"
15848 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15849 (match_operand:HI 2 "register_operand" "a"))
15850 (set (match_operand:P 0 "register_operand" "=D")
15851 (plus:P (match_dup 1)
15855 [(set_attr "type" "str")
15856 (set_attr "memory" "store")
15857 (set_attr "mode" "HI")])
15859 (define_insn "*strsetqi_1"
15860 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15861 (match_operand:QI 2 "register_operand" "a"))
15862 (set (match_operand:P 0 "register_operand" "=D")
15863 (plus:P (match_dup 1)
15867 [(set_attr "type" "str")
15868 (set_attr "memory" "store")
15869 (set (attr "prefix_rex")
15871 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15873 (const_string "*")))
15874 (set_attr "mode" "QI")])
15876 (define_expand "rep_stos"
15877 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15878 (set (match_operand 0 "register_operand" "")
15879 (match_operand 4 "" ""))
15880 (set (match_operand 2 "memory_operand" "") (const_int 0))
15881 (use (match_operand 3 "register_operand" ""))
15882 (use (match_dup 1))])]
15884 "ix86_current_function_needs_cld = 1;")
15886 (define_insn "*rep_stosdi_rex64"
15887 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15888 (set (match_operand:DI 0 "register_operand" "=D")
15889 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15891 (match_operand:DI 3 "register_operand" "0")))
15892 (set (mem:BLK (match_dup 3))
15894 (use (match_operand:DI 2 "register_operand" "a"))
15895 (use (match_dup 4))]
15898 [(set_attr "type" "str")
15899 (set_attr "prefix_rep" "1")
15900 (set_attr "memory" "store")
15901 (set_attr "mode" "DI")])
15903 (define_insn "*rep_stossi"
15904 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15905 (set (match_operand:P 0 "register_operand" "=D")
15906 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15908 (match_operand:P 3 "register_operand" "0")))
15909 (set (mem:BLK (match_dup 3))
15911 (use (match_operand:SI 2 "register_operand" "a"))
15912 (use (match_dup 4))]
15914 "rep{%;} stos{l|d}"
15915 [(set_attr "type" "str")
15916 (set_attr "prefix_rep" "1")
15917 (set_attr "memory" "store")
15918 (set_attr "mode" "SI")])
15920 (define_insn "*rep_stosqi"
15921 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15922 (set (match_operand:P 0 "register_operand" "=D")
15923 (plus:P (match_operand:P 3 "register_operand" "0")
15924 (match_operand:P 4 "register_operand" "1")))
15925 (set (mem:BLK (match_dup 3))
15927 (use (match_operand:QI 2 "register_operand" "a"))
15928 (use (match_dup 4))]
15931 [(set_attr "type" "str")
15932 (set_attr "prefix_rep" "1")
15933 (set_attr "memory" "store")
15934 (set (attr "prefix_rex")
15936 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15938 (const_string "*")))
15939 (set_attr "mode" "QI")])
15941 (define_expand "cmpstrnsi"
15942 [(set (match_operand:SI 0 "register_operand" "")
15943 (compare:SI (match_operand:BLK 1 "general_operand" "")
15944 (match_operand:BLK 2 "general_operand" "")))
15945 (use (match_operand 3 "general_operand" ""))
15946 (use (match_operand 4 "immediate_operand" ""))]
15949 rtx addr1, addr2, out, outlow, count, countreg, align;
15951 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15954 /* Can't use this if the user has appropriated esi or edi. */
15955 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15960 out = gen_reg_rtx (SImode);
15962 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15963 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15964 if (addr1 != XEXP (operands[1], 0))
15965 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15966 if (addr2 != XEXP (operands[2], 0))
15967 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15969 count = operands[3];
15970 countreg = ix86_zero_extend_to_Pmode (count);
15972 /* %%% Iff we are testing strict equality, we can use known alignment
15973 to good advantage. This may be possible with combine, particularly
15974 once cc0 is dead. */
15975 align = operands[4];
15977 if (CONST_INT_P (count))
15979 if (INTVAL (count) == 0)
15981 emit_move_insn (operands[0], const0_rtx);
15984 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15985 operands[1], operands[2]));
15989 rtx (*gen_cmp) (rtx, rtx);
15991 gen_cmp = (TARGET_64BIT
15992 ? gen_cmpdi_1 : gen_cmpsi_1);
15994 emit_insn (gen_cmp (countreg, countreg));
15995 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15996 operands[1], operands[2]));
15999 outlow = gen_lowpart (QImode, out);
16000 emit_insn (gen_cmpintqi (outlow));
16001 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16003 if (operands[0] != out)
16004 emit_move_insn (operands[0], out);
16009 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16011 (define_expand "cmpintqi"
16012 [(set (match_dup 1)
16013 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16015 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16016 (parallel [(set (match_operand:QI 0 "register_operand" "")
16017 (minus:QI (match_dup 1)
16019 (clobber (reg:CC FLAGS_REG))])]
16022 operands[1] = gen_reg_rtx (QImode);
16023 operands[2] = gen_reg_rtx (QImode);
16026 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16027 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16029 (define_expand "cmpstrnqi_nz_1"
16030 [(parallel [(set (reg:CC FLAGS_REG)
16031 (compare:CC (match_operand 4 "memory_operand" "")
16032 (match_operand 5 "memory_operand" "")))
16033 (use (match_operand 2 "register_operand" ""))
16034 (use (match_operand:SI 3 "immediate_operand" ""))
16035 (clobber (match_operand 0 "register_operand" ""))
16036 (clobber (match_operand 1 "register_operand" ""))
16037 (clobber (match_dup 2))])]
16039 "ix86_current_function_needs_cld = 1;")
16041 (define_insn "*cmpstrnqi_nz_1"
16042 [(set (reg:CC FLAGS_REG)
16043 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16044 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16045 (use (match_operand:P 6 "register_operand" "2"))
16046 (use (match_operand:SI 3 "immediate_operand" "i"))
16047 (clobber (match_operand:P 0 "register_operand" "=S"))
16048 (clobber (match_operand:P 1 "register_operand" "=D"))
16049 (clobber (match_operand:P 2 "register_operand" "=c"))]
16052 [(set_attr "type" "str")
16053 (set_attr "mode" "QI")
16054 (set (attr "prefix_rex")
16056 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16058 (const_string "*")))
16059 (set_attr "prefix_rep" "1")])
16061 ;; The same, but the count is not known to not be zero.
16063 (define_expand "cmpstrnqi_1"
16064 [(parallel [(set (reg:CC FLAGS_REG)
16065 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16067 (compare:CC (match_operand 4 "memory_operand" "")
16068 (match_operand 5 "memory_operand" ""))
16070 (use (match_operand:SI 3 "immediate_operand" ""))
16071 (use (reg:CC FLAGS_REG))
16072 (clobber (match_operand 0 "register_operand" ""))
16073 (clobber (match_operand 1 "register_operand" ""))
16074 (clobber (match_dup 2))])]
16076 "ix86_current_function_needs_cld = 1;")
16078 (define_insn "*cmpstrnqi_1"
16079 [(set (reg:CC FLAGS_REG)
16080 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16082 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16083 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16085 (use (match_operand:SI 3 "immediate_operand" "i"))
16086 (use (reg:CC FLAGS_REG))
16087 (clobber (match_operand:P 0 "register_operand" "=S"))
16088 (clobber (match_operand:P 1 "register_operand" "=D"))
16089 (clobber (match_operand:P 2 "register_operand" "=c"))]
16092 [(set_attr "type" "str")
16093 (set_attr "mode" "QI")
16094 (set (attr "prefix_rex")
16096 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16098 (const_string "*")))
16099 (set_attr "prefix_rep" "1")])
16101 (define_expand "strlen<mode>"
16102 [(set (match_operand:SWI48x 0 "register_operand" "")
16103 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16104 (match_operand:QI 2 "immediate_operand" "")
16105 (match_operand 3 "immediate_operand" "")]
16109 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16115 (define_expand "strlenqi_1"
16116 [(parallel [(set (match_operand 0 "register_operand" "")
16117 (match_operand 2 "" ""))
16118 (clobber (match_operand 1 "register_operand" ""))
16119 (clobber (reg:CC FLAGS_REG))])]
16121 "ix86_current_function_needs_cld = 1;")
16123 (define_insn "*strlenqi_1"
16124 [(set (match_operand:P 0 "register_operand" "=&c")
16125 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16126 (match_operand:QI 2 "register_operand" "a")
16127 (match_operand:P 3 "immediate_operand" "i")
16128 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16129 (clobber (match_operand:P 1 "register_operand" "=D"))
16130 (clobber (reg:CC FLAGS_REG))]
16133 [(set_attr "type" "str")
16134 (set_attr "mode" "QI")
16135 (set (attr "prefix_rex")
16137 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16139 (const_string "*")))
16140 (set_attr "prefix_rep" "1")])
16142 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16143 ;; handled in combine, but it is not currently up to the task.
16144 ;; When used for their truth value, the cmpstrn* expanders generate
16153 ;; The intermediate three instructions are unnecessary.
16155 ;; This one handles cmpstrn*_nz_1...
16158 (set (reg:CC FLAGS_REG)
16159 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16160 (mem:BLK (match_operand 5 "register_operand" ""))))
16161 (use (match_operand 6 "register_operand" ""))
16162 (use (match_operand:SI 3 "immediate_operand" ""))
16163 (clobber (match_operand 0 "register_operand" ""))
16164 (clobber (match_operand 1 "register_operand" ""))
16165 (clobber (match_operand 2 "register_operand" ""))])
16166 (set (match_operand:QI 7 "register_operand" "")
16167 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16168 (set (match_operand:QI 8 "register_operand" "")
16169 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16170 (set (reg FLAGS_REG)
16171 (compare (match_dup 7) (match_dup 8)))
16173 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16175 (set (reg:CC FLAGS_REG)
16176 (compare:CC (mem:BLK (match_dup 4))
16177 (mem:BLK (match_dup 5))))
16178 (use (match_dup 6))
16179 (use (match_dup 3))
16180 (clobber (match_dup 0))
16181 (clobber (match_dup 1))
16182 (clobber (match_dup 2))])])
16184 ;; ...and this one handles cmpstrn*_1.
16187 (set (reg:CC FLAGS_REG)
16188 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16190 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16191 (mem:BLK (match_operand 5 "register_operand" "")))
16193 (use (match_operand:SI 3 "immediate_operand" ""))
16194 (use (reg:CC FLAGS_REG))
16195 (clobber (match_operand 0 "register_operand" ""))
16196 (clobber (match_operand 1 "register_operand" ""))
16197 (clobber (match_operand 2 "register_operand" ""))])
16198 (set (match_operand:QI 7 "register_operand" "")
16199 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16200 (set (match_operand:QI 8 "register_operand" "")
16201 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16202 (set (reg FLAGS_REG)
16203 (compare (match_dup 7) (match_dup 8)))
16205 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16207 (set (reg:CC FLAGS_REG)
16208 (if_then_else:CC (ne (match_dup 6)
16210 (compare:CC (mem:BLK (match_dup 4))
16211 (mem:BLK (match_dup 5)))
16213 (use (match_dup 3))
16214 (use (reg:CC FLAGS_REG))
16215 (clobber (match_dup 0))
16216 (clobber (match_dup 1))
16217 (clobber (match_dup 2))])])
16219 ;; Conditional move instructions.
16221 (define_expand "mov<mode>cc"
16222 [(set (match_operand:SWIM 0 "register_operand" "")
16223 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16224 (match_operand:SWIM 2 "general_operand" "")
16225 (match_operand:SWIM 3 "general_operand" "")))]
16227 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16229 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16230 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16231 ;; So just document what we're doing explicitly.
16233 (define_expand "x86_mov<mode>cc_0_m1"
16235 [(set (match_operand:SWI48 0 "register_operand" "")
16236 (if_then_else:SWI48
16237 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16238 [(match_operand 1 "flags_reg_operand" "")
16242 (clobber (reg:CC FLAGS_REG))])])
16244 (define_insn "*x86_mov<mode>cc_0_m1"
16245 [(set (match_operand:SWI48 0 "register_operand" "=r")
16246 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16247 [(reg FLAGS_REG) (const_int 0)])
16250 (clobber (reg:CC FLAGS_REG))]
16252 "sbb{<imodesuffix>}\t%0, %0"
16253 ; Since we don't have the proper number of operands for an alu insn,
16254 ; fill in all the blanks.
16255 [(set_attr "type" "alu")
16256 (set_attr "use_carry" "1")
16257 (set_attr "pent_pair" "pu")
16258 (set_attr "memory" "none")
16259 (set_attr "imm_disp" "false")
16260 (set_attr "mode" "<MODE>")
16261 (set_attr "length_immediate" "0")])
16263 (define_insn "*x86_mov<mode>cc_0_m1_se"
16264 [(set (match_operand:SWI48 0 "register_operand" "=r")
16265 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16266 [(reg FLAGS_REG) (const_int 0)])
16269 (clobber (reg:CC FLAGS_REG))]
16271 "sbb{<imodesuffix>}\t%0, %0"
16272 [(set_attr "type" "alu")
16273 (set_attr "use_carry" "1")
16274 (set_attr "pent_pair" "pu")
16275 (set_attr "memory" "none")
16276 (set_attr "imm_disp" "false")
16277 (set_attr "mode" "<MODE>")
16278 (set_attr "length_immediate" "0")])
16280 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16281 [(set (match_operand:SWI48 0 "register_operand" "=r")
16282 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16283 [(reg FLAGS_REG) (const_int 0)])))]
16285 "sbb{<imodesuffix>}\t%0, %0"
16286 [(set_attr "type" "alu")
16287 (set_attr "use_carry" "1")
16288 (set_attr "pent_pair" "pu")
16289 (set_attr "memory" "none")
16290 (set_attr "imm_disp" "false")
16291 (set_attr "mode" "<MODE>")
16292 (set_attr "length_immediate" "0")])
16294 (define_insn "*mov<mode>cc_noc"
16295 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16296 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16297 [(reg FLAGS_REG) (const_int 0)])
16298 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16299 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16300 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16302 cmov%O2%C1\t{%2, %0|%0, %2}
16303 cmov%O2%c1\t{%3, %0|%0, %3}"
16304 [(set_attr "type" "icmov")
16305 (set_attr "mode" "<MODE>")])
16307 (define_insn_and_split "*movqicc_noc"
16308 [(set (match_operand:QI 0 "register_operand" "=r,r")
16309 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16310 [(match_operand 4 "flags_reg_operand" "")
16312 (match_operand:QI 2 "register_operand" "r,0")
16313 (match_operand:QI 3 "register_operand" "0,r")))]
16314 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16316 "&& reload_completed"
16317 [(set (match_dup 0)
16318 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16321 "operands[0] = gen_lowpart (SImode, operands[0]);
16322 operands[2] = gen_lowpart (SImode, operands[2]);
16323 operands[3] = gen_lowpart (SImode, operands[3]);"
16324 [(set_attr "type" "icmov")
16325 (set_attr "mode" "SI")])
16327 (define_expand "mov<mode>cc"
16328 [(set (match_operand:X87MODEF 0 "register_operand" "")
16329 (if_then_else:X87MODEF
16330 (match_operand 1 "ix86_fp_comparison_operator" "")
16331 (match_operand:X87MODEF 2 "register_operand" "")
16332 (match_operand:X87MODEF 3 "register_operand" "")))]
16333 "(TARGET_80387 && TARGET_CMOVE)
16334 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16335 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16337 (define_insn "*movxfcc_1"
16338 [(set (match_operand:XF 0 "register_operand" "=f,f")
16339 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16340 [(reg FLAGS_REG) (const_int 0)])
16341 (match_operand:XF 2 "register_operand" "f,0")
16342 (match_operand:XF 3 "register_operand" "0,f")))]
16343 "TARGET_80387 && TARGET_CMOVE"
16345 fcmov%F1\t{%2, %0|%0, %2}
16346 fcmov%f1\t{%3, %0|%0, %3}"
16347 [(set_attr "type" "fcmov")
16348 (set_attr "mode" "XF")])
16350 (define_insn "*movdfcc_1_rex64"
16351 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16352 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16353 [(reg FLAGS_REG) (const_int 0)])
16354 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16355 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16356 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16357 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16359 fcmov%F1\t{%2, %0|%0, %2}
16360 fcmov%f1\t{%3, %0|%0, %3}
16361 cmov%O2%C1\t{%2, %0|%0, %2}
16362 cmov%O2%c1\t{%3, %0|%0, %3}"
16363 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16364 (set_attr "mode" "DF,DF,DI,DI")])
16366 (define_insn "*movdfcc_1"
16367 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16368 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16369 [(reg FLAGS_REG) (const_int 0)])
16370 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16371 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16372 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16373 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16375 fcmov%F1\t{%2, %0|%0, %2}
16376 fcmov%f1\t{%3, %0|%0, %3}
16379 [(set_attr "type" "fcmov,fcmov,multi,multi")
16380 (set_attr "mode" "DF,DF,DI,DI")])
16383 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16384 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16385 [(match_operand 4 "flags_reg_operand" "")
16387 (match_operand:DF 2 "nonimmediate_operand" "")
16388 (match_operand:DF 3 "nonimmediate_operand" "")))]
16389 "!TARGET_64BIT && reload_completed"
16390 [(set (match_dup 2)
16391 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16395 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16399 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16400 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16403 (define_insn "*movsfcc_1_387"
16404 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16405 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16406 [(reg FLAGS_REG) (const_int 0)])
16407 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16408 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16409 "TARGET_80387 && TARGET_CMOVE
16410 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16412 fcmov%F1\t{%2, %0|%0, %2}
16413 fcmov%f1\t{%3, %0|%0, %3}
16414 cmov%O2%C1\t{%2, %0|%0, %2}
16415 cmov%O2%c1\t{%3, %0|%0, %3}"
16416 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16417 (set_attr "mode" "SF,SF,SI,SI")])
16419 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16420 ;; the scalar versions to have only XMM registers as operands.
16422 ;; XOP conditional move
16423 (define_insn "*xop_pcmov_<mode>"
16424 [(set (match_operand:MODEF 0 "register_operand" "=x")
16425 (if_then_else:MODEF
16426 (match_operand:MODEF 1 "register_operand" "x")
16427 (match_operand:MODEF 2 "register_operand" "x")
16428 (match_operand:MODEF 3 "register_operand" "x")))]
16430 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16431 [(set_attr "type" "sse4arg")])
16433 ;; These versions of the min/max patterns are intentionally ignorant of
16434 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16435 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16436 ;; are undefined in this condition, we're certain this is correct.
16438 (define_insn "*avx_<code><mode>3"
16439 [(set (match_operand:MODEF 0 "register_operand" "=x")
16441 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16442 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16443 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16444 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16445 [(set_attr "type" "sseadd")
16446 (set_attr "prefix" "vex")
16447 (set_attr "mode" "<MODE>")])
16449 (define_insn "<code><mode>3"
16450 [(set (match_operand:MODEF 0 "register_operand" "=x")
16452 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16453 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16454 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16455 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16456 [(set_attr "type" "sseadd")
16457 (set_attr "mode" "<MODE>")])
16459 ;; These versions of the min/max patterns implement exactly the operations
16460 ;; min = (op1 < op2 ? op1 : op2)
16461 ;; max = (!(op1 < op2) ? op1 : op2)
16462 ;; Their operands are not commutative, and thus they may be used in the
16463 ;; presence of -0.0 and NaN.
16465 (define_insn "*avx_ieee_smin<mode>3"
16466 [(set (match_operand:MODEF 0 "register_operand" "=x")
16468 [(match_operand:MODEF 1 "register_operand" "x")
16469 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16471 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16472 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16473 [(set_attr "type" "sseadd")
16474 (set_attr "prefix" "vex")
16475 (set_attr "mode" "<MODE>")])
16477 (define_insn "*ieee_smin<mode>3"
16478 [(set (match_operand:MODEF 0 "register_operand" "=x")
16480 [(match_operand:MODEF 1 "register_operand" "0")
16481 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16483 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16484 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16485 [(set_attr "type" "sseadd")
16486 (set_attr "mode" "<MODE>")])
16488 (define_insn "*avx_ieee_smax<mode>3"
16489 [(set (match_operand:MODEF 0 "register_operand" "=x")
16491 [(match_operand:MODEF 1 "register_operand" "0")
16492 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16494 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16495 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16496 [(set_attr "type" "sseadd")
16497 (set_attr "prefix" "vex")
16498 (set_attr "mode" "<MODE>")])
16500 (define_insn "*ieee_smax<mode>3"
16501 [(set (match_operand:MODEF 0 "register_operand" "=x")
16503 [(match_operand:MODEF 1 "register_operand" "0")
16504 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16506 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16507 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16508 [(set_attr "type" "sseadd")
16509 (set_attr "mode" "<MODE>")])
16511 ;; Make two stack loads independent:
16513 ;; fld %st(0) -> fld bb
16514 ;; fmul bb fmul %st(1), %st
16516 ;; Actually we only match the last two instructions for simplicity.
16518 [(set (match_operand 0 "fp_register_operand" "")
16519 (match_operand 1 "fp_register_operand" ""))
16521 (match_operator 2 "binary_fp_operator"
16523 (match_operand 3 "memory_operand" "")]))]
16524 "REGNO (operands[0]) != REGNO (operands[1])"
16525 [(set (match_dup 0) (match_dup 3))
16526 (set (match_dup 0) (match_dup 4))]
16528 ;; The % modifier is not operational anymore in peephole2's, so we have to
16529 ;; swap the operands manually in the case of addition and multiplication.
16530 "if (COMMUTATIVE_ARITH_P (operands[2]))
16531 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16532 GET_MODE (operands[2]),
16533 operands[0], operands[1]);
16535 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16536 GET_MODE (operands[2]),
16537 operands[1], operands[0]);")
16539 ;; Conditional addition patterns
16540 (define_expand "add<mode>cc"
16541 [(match_operand:SWI 0 "register_operand" "")
16542 (match_operand 1 "ordered_comparison_operator" "")
16543 (match_operand:SWI 2 "register_operand" "")
16544 (match_operand:SWI 3 "const_int_operand" "")]
16546 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16548 ;; Misc patterns (?)
16550 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16551 ;; Otherwise there will be nothing to keep
16553 ;; [(set (reg ebp) (reg esp))]
16554 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16555 ;; (clobber (eflags)]
16556 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16558 ;; in proper program order.
16560 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16561 [(set (match_operand:P 0 "register_operand" "=r,r")
16562 (plus:P (match_operand:P 1 "register_operand" "0,r")
16563 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16564 (clobber (reg:CC FLAGS_REG))
16565 (clobber (mem:BLK (scratch)))]
16568 switch (get_attr_type (insn))
16571 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16574 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16575 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16576 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16578 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16581 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16582 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16585 [(set (attr "type")
16586 (cond [(and (eq_attr "alternative" "0")
16587 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16588 (const_string "alu")
16589 (match_operand:<MODE> 2 "const0_operand" "")
16590 (const_string "imov")
16592 (const_string "lea")))
16593 (set (attr "length_immediate")
16594 (cond [(eq_attr "type" "imov")
16596 (and (eq_attr "type" "alu")
16597 (match_operand 2 "const128_operand" ""))
16600 (const_string "*")))
16601 (set_attr "mode" "<MODE>")])
16603 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16604 [(set (match_operand:P 0 "register_operand" "=r")
16605 (minus:P (match_operand:P 1 "register_operand" "0")
16606 (match_operand:P 2 "register_operand" "r")))
16607 (clobber (reg:CC FLAGS_REG))
16608 (clobber (mem:BLK (scratch)))]
16610 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16611 [(set_attr "type" "alu")
16612 (set_attr "mode" "<MODE>")])
16614 (define_insn "allocate_stack_worker_probe_<mode>"
16615 [(set (match_operand:P 0 "register_operand" "=a")
16616 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16617 UNSPECV_STACK_PROBE))
16618 (clobber (reg:CC FLAGS_REG))]
16619 "ix86_target_stack_probe ()"
16620 "call\t___chkstk_ms"
16621 [(set_attr "type" "multi")
16622 (set_attr "length" "5")])
16624 (define_expand "allocate_stack"
16625 [(match_operand 0 "register_operand" "")
16626 (match_operand 1 "general_operand" "")]
16627 "ix86_target_stack_probe ()"
16631 #ifndef CHECK_STACK_LIMIT
16632 #define CHECK_STACK_LIMIT 0
16635 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16636 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16638 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16639 stack_pointer_rtx, 0, OPTAB_DIRECT);
16640 if (x != stack_pointer_rtx)
16641 emit_move_insn (stack_pointer_rtx, x);
16645 x = copy_to_mode_reg (Pmode, operands[1]);
16647 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16649 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16650 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16651 stack_pointer_rtx, 0, OPTAB_DIRECT);
16652 if (x != stack_pointer_rtx)
16653 emit_move_insn (stack_pointer_rtx, x);
16656 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16660 ;; Use IOR for stack probes, this is shorter.
16661 (define_expand "probe_stack"
16662 [(match_operand 0 "memory_operand" "")]
16665 rtx (*gen_ior3) (rtx, rtx, rtx);
16667 gen_ior3 = (GET_MODE (operands[0]) == DImode
16668 ? gen_iordi3 : gen_iorsi3);
16670 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16674 (define_insn "adjust_stack_and_probe<mode>"
16675 [(set (match_operand:P 0 "register_operand" "=r")
16676 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16677 UNSPECV_PROBE_STACK_RANGE))
16678 (set (reg:P SP_REG)
16679 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16680 (clobber (reg:CC FLAGS_REG))
16681 (clobber (mem:BLK (scratch)))]
16683 "* return output_adjust_stack_and_probe (operands[0]);"
16684 [(set_attr "type" "multi")])
16686 (define_insn "probe_stack_range<mode>"
16687 [(set (match_operand:P 0 "register_operand" "=r")
16688 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16689 (match_operand:P 2 "const_int_operand" "n")]
16690 UNSPECV_PROBE_STACK_RANGE))
16691 (clobber (reg:CC FLAGS_REG))]
16693 "* return output_probe_stack_range (operands[0], operands[2]);"
16694 [(set_attr "type" "multi")])
16696 (define_expand "builtin_setjmp_receiver"
16697 [(label_ref (match_operand 0 "" ""))]
16698 "!TARGET_64BIT && flag_pic"
16704 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16705 rtx label_rtx = gen_label_rtx ();
16706 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16707 xops[0] = xops[1] = picreg;
16708 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16709 ix86_expand_binary_operator (MINUS, SImode, xops);
16713 emit_insn (gen_set_got (pic_offset_table_rtx));
16717 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16720 [(set (match_operand 0 "register_operand" "")
16721 (match_operator 3 "promotable_binary_operator"
16722 [(match_operand 1 "register_operand" "")
16723 (match_operand 2 "aligned_operand" "")]))
16724 (clobber (reg:CC FLAGS_REG))]
16725 "! TARGET_PARTIAL_REG_STALL && reload_completed
16726 && ((GET_MODE (operands[0]) == HImode
16727 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16728 /* ??? next two lines just !satisfies_constraint_K (...) */
16729 || !CONST_INT_P (operands[2])
16730 || satisfies_constraint_K (operands[2])))
16731 || (GET_MODE (operands[0]) == QImode
16732 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16733 [(parallel [(set (match_dup 0)
16734 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16735 (clobber (reg:CC FLAGS_REG))])]
16736 "operands[0] = gen_lowpart (SImode, operands[0]);
16737 operands[1] = gen_lowpart (SImode, operands[1]);
16738 if (GET_CODE (operands[3]) != ASHIFT)
16739 operands[2] = gen_lowpart (SImode, operands[2]);
16740 PUT_MODE (operands[3], SImode);")
16742 ; Promote the QImode tests, as i386 has encoding of the AND
16743 ; instruction with 32-bit sign-extended immediate and thus the
16744 ; instruction size is unchanged, except in the %eax case for
16745 ; which it is increased by one byte, hence the ! optimize_size.
16747 [(set (match_operand 0 "flags_reg_operand" "")
16748 (match_operator 2 "compare_operator"
16749 [(and (match_operand 3 "aligned_operand" "")
16750 (match_operand 4 "const_int_operand" ""))
16752 (set (match_operand 1 "register_operand" "")
16753 (and (match_dup 3) (match_dup 4)))]
16754 "! TARGET_PARTIAL_REG_STALL && reload_completed
16755 && optimize_insn_for_speed_p ()
16756 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16757 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16758 /* Ensure that the operand will remain sign-extended immediate. */
16759 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16760 [(parallel [(set (match_dup 0)
16761 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16764 (and:SI (match_dup 3) (match_dup 4)))])]
16767 = gen_int_mode (INTVAL (operands[4])
16768 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16769 operands[1] = gen_lowpart (SImode, operands[1]);
16770 operands[3] = gen_lowpart (SImode, operands[3]);
16773 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16774 ; the TEST instruction with 32-bit sign-extended immediate and thus
16775 ; the instruction size would at least double, which is not what we
16776 ; want even with ! optimize_size.
16778 [(set (match_operand 0 "flags_reg_operand" "")
16779 (match_operator 1 "compare_operator"
16780 [(and (match_operand:HI 2 "aligned_operand" "")
16781 (match_operand:HI 3 "const_int_operand" ""))
16783 "! TARGET_PARTIAL_REG_STALL && reload_completed
16784 && ! TARGET_FAST_PREFIX
16785 && optimize_insn_for_speed_p ()
16786 /* Ensure that the operand will remain sign-extended immediate. */
16787 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16788 [(set (match_dup 0)
16789 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16793 = gen_int_mode (INTVAL (operands[3])
16794 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16795 operands[2] = gen_lowpart (SImode, operands[2]);
16799 [(set (match_operand 0 "register_operand" "")
16800 (neg (match_operand 1 "register_operand" "")))
16801 (clobber (reg:CC FLAGS_REG))]
16802 "! TARGET_PARTIAL_REG_STALL && reload_completed
16803 && (GET_MODE (operands[0]) == HImode
16804 || (GET_MODE (operands[0]) == QImode
16805 && (TARGET_PROMOTE_QImode
16806 || optimize_insn_for_size_p ())))"
16807 [(parallel [(set (match_dup 0)
16808 (neg:SI (match_dup 1)))
16809 (clobber (reg:CC FLAGS_REG))])]
16810 "operands[0] = gen_lowpart (SImode, operands[0]);
16811 operands[1] = gen_lowpart (SImode, operands[1]);")
16814 [(set (match_operand 0 "register_operand" "")
16815 (not (match_operand 1 "register_operand" "")))]
16816 "! TARGET_PARTIAL_REG_STALL && reload_completed
16817 && (GET_MODE (operands[0]) == HImode
16818 || (GET_MODE (operands[0]) == QImode
16819 && (TARGET_PROMOTE_QImode
16820 || optimize_insn_for_size_p ())))"
16821 [(set (match_dup 0)
16822 (not:SI (match_dup 1)))]
16823 "operands[0] = gen_lowpart (SImode, operands[0]);
16824 operands[1] = gen_lowpart (SImode, operands[1]);")
16827 [(set (match_operand 0 "register_operand" "")
16828 (if_then_else (match_operator 1 "ordered_comparison_operator"
16829 [(reg FLAGS_REG) (const_int 0)])
16830 (match_operand 2 "register_operand" "")
16831 (match_operand 3 "register_operand" "")))]
16832 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16833 && (GET_MODE (operands[0]) == HImode
16834 || (GET_MODE (operands[0]) == QImode
16835 && (TARGET_PROMOTE_QImode
16836 || optimize_insn_for_size_p ())))"
16837 [(set (match_dup 0)
16838 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16839 "operands[0] = gen_lowpart (SImode, operands[0]);
16840 operands[2] = gen_lowpart (SImode, operands[2]);
16841 operands[3] = gen_lowpart (SImode, operands[3]);")
16843 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16844 ;; transform a complex memory operation into two memory to register operations.
16846 ;; Don't push memory operands
16848 [(set (match_operand:SWI 0 "push_operand" "")
16849 (match_operand:SWI 1 "memory_operand" ""))
16850 (match_scratch:SWI 2 "<r>")]
16851 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16852 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16853 [(set (match_dup 2) (match_dup 1))
16854 (set (match_dup 0) (match_dup 2))])
16856 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16859 [(set (match_operand:SF 0 "push_operand" "")
16860 (match_operand:SF 1 "memory_operand" ""))
16861 (match_scratch:SF 2 "r")]
16862 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16863 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16864 [(set (match_dup 2) (match_dup 1))
16865 (set (match_dup 0) (match_dup 2))])
16867 ;; Don't move an immediate directly to memory when the instruction
16870 [(match_scratch:SWI124 1 "<r>")
16871 (set (match_operand:SWI124 0 "memory_operand" "")
16873 "optimize_insn_for_speed_p ()
16874 && !TARGET_USE_MOV0
16875 && TARGET_SPLIT_LONG_MOVES
16876 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16877 && peep2_regno_dead_p (0, FLAGS_REG)"
16878 [(parallel [(set (match_dup 2) (const_int 0))
16879 (clobber (reg:CC FLAGS_REG))])
16880 (set (match_dup 0) (match_dup 1))]
16881 "operands[2] = gen_lowpart (SImode, operands[1]);")
16884 [(match_scratch:SWI124 2 "<r>")
16885 (set (match_operand:SWI124 0 "memory_operand" "")
16886 (match_operand:SWI124 1 "immediate_operand" ""))]
16887 "optimize_insn_for_speed_p ()
16888 && TARGET_SPLIT_LONG_MOVES
16889 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16890 [(set (match_dup 2) (match_dup 1))
16891 (set (match_dup 0) (match_dup 2))])
16893 ;; Don't compare memory with zero, load and use a test instead.
16895 [(set (match_operand 0 "flags_reg_operand" "")
16896 (match_operator 1 "compare_operator"
16897 [(match_operand:SI 2 "memory_operand" "")
16899 (match_scratch:SI 3 "r")]
16900 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16901 [(set (match_dup 3) (match_dup 2))
16902 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16904 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16905 ;; Don't split NOTs with a displacement operand, because resulting XOR
16906 ;; will not be pairable anyway.
16908 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16909 ;; represented using a modRM byte. The XOR replacement is long decoded,
16910 ;; so this split helps here as well.
16912 ;; Note: Can't do this as a regular split because we can't get proper
16913 ;; lifetime information then.
16916 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16917 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16918 "optimize_insn_for_speed_p ()
16919 && ((TARGET_NOT_UNPAIRABLE
16920 && (!MEM_P (operands[0])
16921 || !memory_displacement_operand (operands[0], <MODE>mode)))
16922 || (TARGET_NOT_VECTORMODE
16923 && long_memory_operand (operands[0], <MODE>mode)))
16924 && peep2_regno_dead_p (0, FLAGS_REG)"
16925 [(parallel [(set (match_dup 0)
16926 (xor:SWI124 (match_dup 1) (const_int -1)))
16927 (clobber (reg:CC FLAGS_REG))])])
16929 ;; Non pairable "test imm, reg" instructions can be translated to
16930 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16931 ;; byte opcode instead of two, have a short form for byte operands),
16932 ;; so do it for other CPUs as well. Given that the value was dead,
16933 ;; this should not create any new dependencies. Pass on the sub-word
16934 ;; versions if we're concerned about partial register stalls.
16937 [(set (match_operand 0 "flags_reg_operand" "")
16938 (match_operator 1 "compare_operator"
16939 [(and:SI (match_operand:SI 2 "register_operand" "")
16940 (match_operand:SI 3 "immediate_operand" ""))
16942 "ix86_match_ccmode (insn, CCNOmode)
16943 && (true_regnum (operands[2]) != AX_REG
16944 || satisfies_constraint_K (operands[3]))
16945 && peep2_reg_dead_p (1, operands[2])"
16947 [(set (match_dup 0)
16948 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16951 (and:SI (match_dup 2) (match_dup 3)))])])
16953 ;; We don't need to handle HImode case, because it will be promoted to SImode
16954 ;; on ! TARGET_PARTIAL_REG_STALL
16957 [(set (match_operand 0 "flags_reg_operand" "")
16958 (match_operator 1 "compare_operator"
16959 [(and:QI (match_operand:QI 2 "register_operand" "")
16960 (match_operand:QI 3 "immediate_operand" ""))
16962 "! TARGET_PARTIAL_REG_STALL
16963 && ix86_match_ccmode (insn, CCNOmode)
16964 && true_regnum (operands[2]) != AX_REG
16965 && peep2_reg_dead_p (1, operands[2])"
16967 [(set (match_dup 0)
16968 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16971 (and:QI (match_dup 2) (match_dup 3)))])])
16974 [(set (match_operand 0 "flags_reg_operand" "")
16975 (match_operator 1 "compare_operator"
16978 (match_operand 2 "ext_register_operand" "")
16981 (match_operand 3 "const_int_operand" ""))
16983 "! TARGET_PARTIAL_REG_STALL
16984 && ix86_match_ccmode (insn, CCNOmode)
16985 && true_regnum (operands[2]) != AX_REG
16986 && peep2_reg_dead_p (1, operands[2])"
16987 [(parallel [(set (match_dup 0)
16996 (set (zero_extract:SI (match_dup 2)
17004 (match_dup 3)))])])
17006 ;; Don't do logical operations with memory inputs.
17008 [(match_scratch:SI 2 "r")
17009 (parallel [(set (match_operand:SI 0 "register_operand" "")
17010 (match_operator:SI 3 "arith_or_logical_operator"
17012 (match_operand:SI 1 "memory_operand" "")]))
17013 (clobber (reg:CC FLAGS_REG))])]
17014 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17015 [(set (match_dup 2) (match_dup 1))
17016 (parallel [(set (match_dup 0)
17017 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17018 (clobber (reg:CC FLAGS_REG))])])
17021 [(match_scratch:SI 2 "r")
17022 (parallel [(set (match_operand:SI 0 "register_operand" "")
17023 (match_operator:SI 3 "arith_or_logical_operator"
17024 [(match_operand:SI 1 "memory_operand" "")
17026 (clobber (reg:CC FLAGS_REG))])]
17027 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17028 [(set (match_dup 2) (match_dup 1))
17029 (parallel [(set (match_dup 0)
17030 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17031 (clobber (reg:CC FLAGS_REG))])])
17033 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17034 ;; refers to the destination of the load!
17037 [(set (match_operand:SI 0 "register_operand" "")
17038 (match_operand:SI 1 "register_operand" ""))
17039 (parallel [(set (match_dup 0)
17040 (match_operator:SI 3 "commutative_operator"
17042 (match_operand:SI 2 "memory_operand" "")]))
17043 (clobber (reg:CC FLAGS_REG))])]
17044 "REGNO (operands[0]) != REGNO (operands[1])
17045 && GENERAL_REGNO_P (REGNO (operands[0]))
17046 && GENERAL_REGNO_P (REGNO (operands[1]))"
17047 [(set (match_dup 0) (match_dup 4))
17048 (parallel [(set (match_dup 0)
17049 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17050 (clobber (reg:CC FLAGS_REG))])]
17051 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17054 [(set (match_operand 0 "register_operand" "")
17055 (match_operand 1 "register_operand" ""))
17057 (match_operator 3 "commutative_operator"
17059 (match_operand 2 "memory_operand" "")]))]
17060 "REGNO (operands[0]) != REGNO (operands[1])
17061 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17062 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17063 [(set (match_dup 0) (match_dup 2))
17065 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17067 ; Don't do logical operations with memory outputs
17069 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17070 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17071 ; the same decoder scheduling characteristics as the original.
17074 [(match_scratch:SI 2 "r")
17075 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17076 (match_operator:SI 3 "arith_or_logical_operator"
17078 (match_operand:SI 1 "nonmemory_operand" "")]))
17079 (clobber (reg:CC FLAGS_REG))])]
17080 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17081 /* Do not split stack checking probes. */
17082 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17083 [(set (match_dup 2) (match_dup 0))
17084 (parallel [(set (match_dup 2)
17085 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17086 (clobber (reg:CC FLAGS_REG))])
17087 (set (match_dup 0) (match_dup 2))])
17090 [(match_scratch:SI 2 "r")
17091 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17092 (match_operator:SI 3 "arith_or_logical_operator"
17093 [(match_operand:SI 1 "nonmemory_operand" "")
17095 (clobber (reg:CC FLAGS_REG))])]
17096 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17097 /* Do not split stack checking probes. */
17098 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17099 [(set (match_dup 2) (match_dup 0))
17100 (parallel [(set (match_dup 2)
17101 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17102 (clobber (reg:CC FLAGS_REG))])
17103 (set (match_dup 0) (match_dup 2))])
17105 ;; Attempt to always use XOR for zeroing registers.
17107 [(set (match_operand 0 "register_operand" "")
17108 (match_operand 1 "const0_operand" ""))]
17109 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17110 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17111 && GENERAL_REG_P (operands[0])
17112 && peep2_regno_dead_p (0, FLAGS_REG)"
17113 [(parallel [(set (match_dup 0) (const_int 0))
17114 (clobber (reg:CC FLAGS_REG))])]
17115 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17118 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17120 "(GET_MODE (operands[0]) == QImode
17121 || GET_MODE (operands[0]) == HImode)
17122 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17123 && peep2_regno_dead_p (0, FLAGS_REG)"
17124 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17125 (clobber (reg:CC FLAGS_REG))])])
17127 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17129 [(set (match_operand:SWI248 0 "register_operand" "")
17131 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17132 && peep2_regno_dead_p (0, FLAGS_REG)"
17133 [(parallel [(set (match_dup 0) (const_int -1))
17134 (clobber (reg:CC FLAGS_REG))])]
17136 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17137 operands[0] = gen_lowpart (SImode, operands[0]);
17140 ;; Attempt to convert simple lea to add/shift.
17141 ;; These can be created by move expanders.
17144 [(set (match_operand:SWI48 0 "register_operand" "")
17145 (plus:SWI48 (match_dup 0)
17146 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17147 "peep2_regno_dead_p (0, FLAGS_REG)"
17148 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17149 (clobber (reg:CC FLAGS_REG))])])
17152 [(set (match_operand:SI 0 "register_operand" "")
17153 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17154 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17156 && peep2_regno_dead_p (0, FLAGS_REG)
17157 && REGNO (operands[0]) == REGNO (operands[1])"
17158 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17159 (clobber (reg:CC FLAGS_REG))])]
17160 "operands[2] = gen_lowpart (SImode, operands[2]);")
17163 [(set (match_operand:SWI48 0 "register_operand" "")
17164 (mult:SWI48 (match_dup 0)
17165 (match_operand:SWI48 1 "const_int_operand" "")))]
17166 "exact_log2 (INTVAL (operands[1])) >= 0
17167 && peep2_regno_dead_p (0, FLAGS_REG)"
17168 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17169 (clobber (reg:CC FLAGS_REG))])]
17170 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17173 [(set (match_operand:SI 0 "register_operand" "")
17174 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17175 (match_operand:DI 2 "const_int_operand" "")) 0))]
17177 && exact_log2 (INTVAL (operands[2])) >= 0
17178 && REGNO (operands[0]) == REGNO (operands[1])
17179 && peep2_regno_dead_p (0, FLAGS_REG)"
17180 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17181 (clobber (reg:CC FLAGS_REG))])]
17182 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17184 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17185 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17186 ;; On many CPUs it is also faster, since special hardware to avoid esp
17187 ;; dependencies is present.
17189 ;; While some of these conversions may be done using splitters, we use
17190 ;; peepholes in order to allow combine_stack_adjustments pass to see
17191 ;; nonobfuscated RTL.
17193 ;; Convert prologue esp subtractions to push.
17194 ;; We need register to push. In order to keep verify_flow_info happy we have
17196 ;; - use scratch and clobber it in order to avoid dependencies
17197 ;; - use already live register
17198 ;; We can't use the second way right now, since there is no reliable way how to
17199 ;; verify that given register is live. First choice will also most likely in
17200 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17201 ;; call clobbered registers are dead. We may want to use base pointer as an
17202 ;; alternative when no register is available later.
17205 [(match_scratch:P 1 "r")
17206 (parallel [(set (reg:P SP_REG)
17207 (plus:P (reg:P SP_REG)
17208 (match_operand:P 0 "const_int_operand" "")))
17209 (clobber (reg:CC FLAGS_REG))
17210 (clobber (mem:BLK (scratch)))])]
17211 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17212 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17213 [(clobber (match_dup 1))
17214 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17215 (clobber (mem:BLK (scratch)))])])
17218 [(match_scratch:P 1 "r")
17219 (parallel [(set (reg:P SP_REG)
17220 (plus:P (reg:P SP_REG)
17221 (match_operand:P 0 "const_int_operand" "")))
17222 (clobber (reg:CC FLAGS_REG))
17223 (clobber (mem:BLK (scratch)))])]
17224 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17225 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17226 [(clobber (match_dup 1))
17227 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17228 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17229 (clobber (mem:BLK (scratch)))])])
17231 ;; Convert esp subtractions to push.
17233 [(match_scratch:P 1 "r")
17234 (parallel [(set (reg:P SP_REG)
17235 (plus:P (reg:P SP_REG)
17236 (match_operand:P 0 "const_int_operand" "")))
17237 (clobber (reg:CC FLAGS_REG))])]
17238 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17239 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17240 [(clobber (match_dup 1))
17241 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17244 [(match_scratch:P 1 "r")
17245 (parallel [(set (reg:P SP_REG)
17246 (plus:P (reg:P SP_REG)
17247 (match_operand:P 0 "const_int_operand" "")))
17248 (clobber (reg:CC FLAGS_REG))])]
17249 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17250 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17251 [(clobber (match_dup 1))
17252 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17253 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17255 ;; Convert epilogue deallocator to pop.
17257 [(match_scratch:P 1 "r")
17258 (parallel [(set (reg:P SP_REG)
17259 (plus:P (reg:P SP_REG)
17260 (match_operand:P 0 "const_int_operand" "")))
17261 (clobber (reg:CC FLAGS_REG))
17262 (clobber (mem:BLK (scratch)))])]
17263 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17264 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17265 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17266 (clobber (mem:BLK (scratch)))])])
17268 ;; Two pops case is tricky, since pop causes dependency
17269 ;; on destination register. We use two registers if available.
17271 [(match_scratch:P 1 "r")
17272 (match_scratch:P 2 "r")
17273 (parallel [(set (reg:P SP_REG)
17274 (plus:P (reg:P SP_REG)
17275 (match_operand:P 0 "const_int_operand" "")))
17276 (clobber (reg:CC FLAGS_REG))
17277 (clobber (mem:BLK (scratch)))])]
17278 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17279 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17280 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17281 (clobber (mem:BLK (scratch)))])
17282 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17285 [(match_scratch:P 1 "r")
17286 (parallel [(set (reg:P SP_REG)
17287 (plus:P (reg:P SP_REG)
17288 (match_operand:P 0 "const_int_operand" "")))
17289 (clobber (reg:CC FLAGS_REG))
17290 (clobber (mem:BLK (scratch)))])]
17291 "optimize_insn_for_size_p ()
17292 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17293 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17294 (clobber (mem:BLK (scratch)))])
17295 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17297 ;; Convert esp additions to pop.
17299 [(match_scratch:P 1 "r")
17300 (parallel [(set (reg:P SP_REG)
17301 (plus:P (reg:P SP_REG)
17302 (match_operand:P 0 "const_int_operand" "")))
17303 (clobber (reg:CC FLAGS_REG))])]
17304 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17305 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17307 ;; Two pops case is tricky, since pop causes dependency
17308 ;; on destination register. We use two registers if available.
17310 [(match_scratch:P 1 "r")
17311 (match_scratch:P 2 "r")
17312 (parallel [(set (reg:P SP_REG)
17313 (plus:P (reg:P SP_REG)
17314 (match_operand:P 0 "const_int_operand" "")))
17315 (clobber (reg:CC FLAGS_REG))])]
17316 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17317 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17318 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17321 [(match_scratch:P 1 "r")
17322 (parallel [(set (reg:P SP_REG)
17323 (plus:P (reg:P SP_REG)
17324 (match_operand:P 0 "const_int_operand" "")))
17325 (clobber (reg:CC FLAGS_REG))])]
17326 "optimize_insn_for_size_p ()
17327 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17328 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17329 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17331 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17332 ;; required and register dies. Similarly for 128 to -128.
17334 [(set (match_operand 0 "flags_reg_operand" "")
17335 (match_operator 1 "compare_operator"
17336 [(match_operand 2 "register_operand" "")
17337 (match_operand 3 "const_int_operand" "")]))]
17338 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17339 && incdec_operand (operands[3], GET_MODE (operands[3])))
17340 || (!TARGET_FUSE_CMP_AND_BRANCH
17341 && INTVAL (operands[3]) == 128))
17342 && ix86_match_ccmode (insn, CCGCmode)
17343 && peep2_reg_dead_p (1, operands[2])"
17344 [(parallel [(set (match_dup 0)
17345 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17346 (clobber (match_dup 2))])])
17348 ;; Convert imul by three, five and nine into lea
17351 [(set (match_operand:SWI48 0 "register_operand" "")
17352 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17353 (match_operand:SWI48 2 "const_int_operand" "")))
17354 (clobber (reg:CC FLAGS_REG))])]
17355 "INTVAL (operands[2]) == 3
17356 || INTVAL (operands[2]) == 5
17357 || INTVAL (operands[2]) == 9"
17358 [(set (match_dup 0)
17359 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17361 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17365 [(set (match_operand:SWI48 0 "register_operand" "")
17366 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17367 (match_operand:SWI48 2 "const_int_operand" "")))
17368 (clobber (reg:CC FLAGS_REG))])]
17369 "optimize_insn_for_speed_p ()
17370 && (INTVAL (operands[2]) == 3
17371 || INTVAL (operands[2]) == 5
17372 || INTVAL (operands[2]) == 9)"
17373 [(set (match_dup 0) (match_dup 1))
17375 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17377 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17379 ;; imul $32bit_imm, mem, reg is vector decoded, while
17380 ;; imul $32bit_imm, reg, reg is direct decoded.
17382 [(match_scratch:SWI48 3 "r")
17383 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17384 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17385 (match_operand:SWI48 2 "immediate_operand" "")))
17386 (clobber (reg:CC FLAGS_REG))])]
17387 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17388 && !satisfies_constraint_K (operands[2])"
17389 [(set (match_dup 3) (match_dup 1))
17390 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17391 (clobber (reg:CC FLAGS_REG))])])
17394 [(match_scratch:SI 3 "r")
17395 (parallel [(set (match_operand:DI 0 "register_operand" "")
17397 (mult:SI (match_operand:SI 1 "memory_operand" "")
17398 (match_operand:SI 2 "immediate_operand" ""))))
17399 (clobber (reg:CC FLAGS_REG))])]
17401 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17402 && !satisfies_constraint_K (operands[2])"
17403 [(set (match_dup 3) (match_dup 1))
17404 (parallel [(set (match_dup 0)
17405 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17406 (clobber (reg:CC FLAGS_REG))])])
17408 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17409 ;; Convert it into imul reg, reg
17410 ;; It would be better to force assembler to encode instruction using long
17411 ;; immediate, but there is apparently no way to do so.
17413 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17415 (match_operand:SWI248 1 "nonimmediate_operand" "")
17416 (match_operand:SWI248 2 "const_int_operand" "")))
17417 (clobber (reg:CC FLAGS_REG))])
17418 (match_scratch:SWI248 3 "r")]
17419 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17420 && satisfies_constraint_K (operands[2])"
17421 [(set (match_dup 3) (match_dup 2))
17422 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17423 (clobber (reg:CC FLAGS_REG))])]
17425 if (!rtx_equal_p (operands[0], operands[1]))
17426 emit_move_insn (operands[0], operands[1]);
17429 ;; After splitting up read-modify operations, array accesses with memory
17430 ;; operands might end up in form:
17432 ;; movl 4(%esp), %edx
17434 ;; instead of pre-splitting:
17436 ;; addl 4(%esp), %eax
17438 ;; movl 4(%esp), %edx
17439 ;; leal (%edx,%eax,4), %eax
17442 [(match_scratch:P 5 "r")
17443 (parallel [(set (match_operand 0 "register_operand" "")
17444 (ashift (match_operand 1 "register_operand" "")
17445 (match_operand 2 "const_int_operand" "")))
17446 (clobber (reg:CC FLAGS_REG))])
17447 (parallel [(set (match_operand 3 "register_operand" "")
17448 (plus (match_dup 0)
17449 (match_operand 4 "x86_64_general_operand" "")))
17450 (clobber (reg:CC FLAGS_REG))])]
17451 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17452 /* Validate MODE for lea. */
17453 && ((!TARGET_PARTIAL_REG_STALL
17454 && (GET_MODE (operands[0]) == QImode
17455 || GET_MODE (operands[0]) == HImode))
17456 || GET_MODE (operands[0]) == SImode
17457 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17458 && (rtx_equal_p (operands[0], operands[3])
17459 || peep2_reg_dead_p (2, operands[0]))
17460 /* We reorder load and the shift. */
17461 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17462 [(set (match_dup 5) (match_dup 4))
17463 (set (match_dup 0) (match_dup 1))]
17465 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17466 int scale = 1 << INTVAL (operands[2]);
17467 rtx index = gen_lowpart (Pmode, operands[1]);
17468 rtx base = gen_lowpart (Pmode, operands[5]);
17469 rtx dest = gen_lowpart (mode, operands[3]);
17471 operands[1] = gen_rtx_PLUS (Pmode, base,
17472 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17473 operands[5] = base;
17476 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17477 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17479 operands[0] = dest;
17482 ;; Call-value patterns last so that the wildcard operand does not
17483 ;; disrupt insn-recog's switch tables.
17485 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17487 [(set (match_operand 0 "" "")
17488 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17489 (match_operand:SI 2 "" "")))
17490 (set (reg:SI SP_REG)
17491 (plus:SI (reg:SI SP_REG)
17492 (match_operand:SI 3 "immediate_operand" "")))])
17493 (unspec [(match_operand 4 "const_int_operand" "")]
17494 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17495 "TARGET_VZEROUPPER && !TARGET_64BIT"
17497 "&& reload_completed"
17499 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17500 [(set_attr "type" "callv")])
17502 (define_insn "*call_value_pop_0"
17503 [(set (match_operand 0 "" "")
17504 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17505 (match_operand:SI 2 "" "")))
17506 (set (reg:SI SP_REG)
17507 (plus:SI (reg:SI SP_REG)
17508 (match_operand:SI 3 "immediate_operand" "")))]
17510 { return ix86_output_call_insn (insn, operands[1], 1); }
17511 [(set_attr "type" "callv")])
17513 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17515 [(set (match_operand 0 "" "")
17516 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17517 (match_operand:SI 2 "" "")))
17518 (set (reg:SI SP_REG)
17519 (plus:SI (reg:SI SP_REG)
17520 (match_operand:SI 3 "immediate_operand" "i")))])
17521 (unspec [(match_operand 4 "const_int_operand" "")]
17522 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17523 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17525 "&& reload_completed"
17527 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17528 [(set_attr "type" "callv")])
17530 (define_insn "*call_value_pop_1"
17531 [(set (match_operand 0 "" "")
17532 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17533 (match_operand:SI 2 "" "")))
17534 (set (reg:SI SP_REG)
17535 (plus:SI (reg:SI SP_REG)
17536 (match_operand:SI 3 "immediate_operand" "i")))]
17537 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17538 { return ix86_output_call_insn (insn, operands[1], 1); }
17539 [(set_attr "type" "callv")])
17541 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17543 [(set (match_operand 0 "" "")
17544 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17545 (match_operand:SI 2 "" "")))
17546 (set (reg:SI SP_REG)
17547 (plus:SI (reg:SI SP_REG)
17548 (match_operand:SI 3 "immediate_operand" "i,i")))])
17549 (unspec [(match_operand 4 "const_int_operand" "")]
17550 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17551 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17553 "&& reload_completed"
17555 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17556 [(set_attr "type" "callv")])
17558 (define_insn "*sibcall_value_pop_1"
17559 [(set (match_operand 0 "" "")
17560 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17561 (match_operand:SI 2 "" "")))
17562 (set (reg:SI SP_REG)
17563 (plus:SI (reg:SI SP_REG)
17564 (match_operand:SI 3 "immediate_operand" "i,i")))]
17565 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17566 { return ix86_output_call_insn (insn, operands[1], 1); }
17567 [(set_attr "type" "callv")])
17569 (define_insn_and_split "*call_value_0_vzeroupper"
17570 [(set (match_operand 0 "" "")
17571 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17572 (match_operand:SI 2 "" "")))
17573 (unspec [(match_operand 3 "const_int_operand" "")]
17574 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17575 "TARGET_VZEROUPPER && !TARGET_64BIT"
17577 "&& reload_completed"
17579 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17580 [(set_attr "type" "callv")])
17582 (define_insn "*call_value_0"
17583 [(set (match_operand 0 "" "")
17584 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17585 (match_operand:SI 2 "" "")))]
17587 { return ix86_output_call_insn (insn, operands[1], 1); }
17588 [(set_attr "type" "callv")])
17590 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17591 [(set (match_operand 0 "" "")
17592 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17593 (match_operand:DI 2 "const_int_operand" "")))
17594 (unspec [(match_operand 3 "const_int_operand" "")]
17595 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17596 "TARGET_VZEROUPPER && TARGET_64BIT"
17598 "&& reload_completed"
17600 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17601 [(set_attr "type" "callv")])
17603 (define_insn "*call_value_0_rex64"
17604 [(set (match_operand 0 "" "")
17605 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17606 (match_operand:DI 2 "const_int_operand" "")))]
17608 { return ix86_output_call_insn (insn, operands[1], 1); }
17609 [(set_attr "type" "callv")])
17611 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17613 [(set (match_operand 0 "" "")
17614 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17615 (match_operand:DI 2 "const_int_operand" "")))
17616 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17617 (clobber (reg:TI XMM6_REG))
17618 (clobber (reg:TI XMM7_REG))
17619 (clobber (reg:TI XMM8_REG))
17620 (clobber (reg:TI XMM9_REG))
17621 (clobber (reg:TI XMM10_REG))
17622 (clobber (reg:TI XMM11_REG))
17623 (clobber (reg:TI XMM12_REG))
17624 (clobber (reg:TI XMM13_REG))
17625 (clobber (reg:TI XMM14_REG))
17626 (clobber (reg:TI XMM15_REG))
17627 (clobber (reg:DI SI_REG))
17628 (clobber (reg:DI DI_REG))])
17629 (unspec [(match_operand 3 "const_int_operand" "")]
17630 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17631 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17633 "&& reload_completed"
17635 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17636 [(set_attr "type" "callv")])
17638 (define_insn "*call_value_0_rex64_ms_sysv"
17639 [(set (match_operand 0 "" "")
17640 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17641 (match_operand:DI 2 "const_int_operand" "")))
17642 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17643 (clobber (reg:TI XMM6_REG))
17644 (clobber (reg:TI XMM7_REG))
17645 (clobber (reg:TI XMM8_REG))
17646 (clobber (reg:TI XMM9_REG))
17647 (clobber (reg:TI XMM10_REG))
17648 (clobber (reg:TI XMM11_REG))
17649 (clobber (reg:TI XMM12_REG))
17650 (clobber (reg:TI XMM13_REG))
17651 (clobber (reg:TI XMM14_REG))
17652 (clobber (reg:TI XMM15_REG))
17653 (clobber (reg:DI SI_REG))
17654 (clobber (reg:DI DI_REG))]
17655 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17656 { return ix86_output_call_insn (insn, operands[1], 1); }
17657 [(set_attr "type" "callv")])
17659 (define_insn_and_split "*call_value_1_vzeroupper"
17660 [(set (match_operand 0 "" "")
17661 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17662 (match_operand:SI 2 "" "")))
17663 (unspec [(match_operand 3 "const_int_operand" "")]
17664 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17665 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17667 "&& reload_completed"
17669 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17670 [(set_attr "type" "callv")])
17672 (define_insn "*call_value_1"
17673 [(set (match_operand 0 "" "")
17674 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17675 (match_operand:SI 2 "" "")))]
17676 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17677 { return ix86_output_call_insn (insn, operands[1], 1); }
17678 [(set_attr "type" "callv")])
17680 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17681 [(set (match_operand 0 "" "")
17682 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17683 (match_operand:SI 2 "" "")))
17684 (unspec [(match_operand 3 "const_int_operand" "")]
17685 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17686 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17688 "&& reload_completed"
17690 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17691 [(set_attr "type" "callv")])
17693 (define_insn "*sibcall_value_1"
17694 [(set (match_operand 0 "" "")
17695 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17696 (match_operand:SI 2 "" "")))]
17697 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17698 { return ix86_output_call_insn (insn, operands[1], 1); }
17699 [(set_attr "type" "callv")])
17701 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17702 [(set (match_operand 0 "" "")
17703 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17704 (match_operand:DI 2 "" "")))
17705 (unspec [(match_operand 3 "const_int_operand" "")]
17706 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17707 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17708 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17710 "&& reload_completed"
17712 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17713 [(set_attr "type" "callv")])
17715 (define_insn "*call_value_1_rex64"
17716 [(set (match_operand 0 "" "")
17717 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17718 (match_operand:DI 2 "" "")))]
17719 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17720 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17721 { return ix86_output_call_insn (insn, operands[1], 1); }
17722 [(set_attr "type" "callv")])
17724 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17726 [(set (match_operand 0 "" "")
17727 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17728 (match_operand:DI 2 "" "")))
17729 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17730 (clobber (reg:TI XMM6_REG))
17731 (clobber (reg:TI XMM7_REG))
17732 (clobber (reg:TI XMM8_REG))
17733 (clobber (reg:TI XMM9_REG))
17734 (clobber (reg:TI XMM10_REG))
17735 (clobber (reg:TI XMM11_REG))
17736 (clobber (reg:TI XMM12_REG))
17737 (clobber (reg:TI XMM13_REG))
17738 (clobber (reg:TI XMM14_REG))
17739 (clobber (reg:TI XMM15_REG))
17740 (clobber (reg:DI SI_REG))
17741 (clobber (reg:DI DI_REG))])
17742 (unspec [(match_operand 3 "const_int_operand" "")]
17743 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17744 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17746 "&& reload_completed"
17748 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17749 [(set_attr "type" "callv")])
17751 (define_insn "*call_value_1_rex64_ms_sysv"
17752 [(set (match_operand 0 "" "")
17753 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17754 (match_operand:DI 2 "" "")))
17755 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17756 (clobber (reg:TI XMM6_REG))
17757 (clobber (reg:TI XMM7_REG))
17758 (clobber (reg:TI XMM8_REG))
17759 (clobber (reg:TI XMM9_REG))
17760 (clobber (reg:TI XMM10_REG))
17761 (clobber (reg:TI XMM11_REG))
17762 (clobber (reg:TI XMM12_REG))
17763 (clobber (reg:TI XMM13_REG))
17764 (clobber (reg:TI XMM14_REG))
17765 (clobber (reg:TI XMM15_REG))
17766 (clobber (reg:DI SI_REG))
17767 (clobber (reg:DI DI_REG))]
17768 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17769 { return ix86_output_call_insn (insn, operands[1], 1); }
17770 [(set_attr "type" "callv")])
17772 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17773 [(set (match_operand 0 "" "")
17774 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17775 (match_operand:DI 2 "" "")))
17776 (unspec [(match_operand 3 "const_int_operand" "")]
17777 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17778 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17780 "&& reload_completed"
17782 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17783 [(set_attr "type" "callv")])
17785 (define_insn "*call_value_1_rex64_large"
17786 [(set (match_operand 0 "" "")
17787 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17788 (match_operand:DI 2 "" "")))]
17789 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17790 { return ix86_output_call_insn (insn, operands[1], 1); }
17791 [(set_attr "type" "callv")])
17793 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17794 [(set (match_operand 0 "" "")
17795 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17796 (match_operand:DI 2 "" "")))
17797 (unspec [(match_operand 3 "const_int_operand" "")]
17798 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17799 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17801 "&& reload_completed"
17803 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17804 [(set_attr "type" "callv")])
17806 (define_insn "*sibcall_value_1_rex64"
17807 [(set (match_operand 0 "" "")
17808 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17809 (match_operand:DI 2 "" "")))]
17810 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17811 { return ix86_output_call_insn (insn, operands[1], 1); }
17812 [(set_attr "type" "callv")])
17814 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17815 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17816 ;; caught for use by garbage collectors and the like. Using an insn that
17817 ;; maps to SIGILL makes it more likely the program will rightfully die.
17818 ;; Keeping with tradition, "6" is in honor of #UD.
17819 (define_insn "trap"
17820 [(trap_if (const_int 1) (const_int 6))]
17822 { return ASM_SHORT "0x0b0f"; }
17823 [(set_attr "length" "2")])
17825 (define_expand "prefetch"
17826 [(prefetch (match_operand 0 "address_operand" "")
17827 (match_operand:SI 1 "const_int_operand" "")
17828 (match_operand:SI 2 "const_int_operand" ""))]
17829 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17831 int rw = INTVAL (operands[1]);
17832 int locality = INTVAL (operands[2]);
17834 gcc_assert (rw == 0 || rw == 1);
17835 gcc_assert (locality >= 0 && locality <= 3);
17836 gcc_assert (GET_MODE (operands[0]) == Pmode
17837 || GET_MODE (operands[0]) == VOIDmode);
17839 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17840 supported by SSE counterpart or the SSE prefetch is not available
17841 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17843 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17844 operands[2] = GEN_INT (3);
17846 operands[1] = const0_rtx;
17849 (define_insn "*prefetch_sse_<mode>"
17850 [(prefetch (match_operand:P 0 "address_operand" "p")
17852 (match_operand:SI 1 "const_int_operand" ""))]
17853 "TARGET_PREFETCH_SSE"
17855 static const char * const patterns[4] = {
17856 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17859 int locality = INTVAL (operands[1]);
17860 gcc_assert (locality >= 0 && locality <= 3);
17862 return patterns[locality];
17864 [(set_attr "type" "sse")
17865 (set_attr "atom_sse_attr" "prefetch")
17866 (set (attr "length_address")
17867 (symbol_ref "memory_address_length (operands[0])"))
17868 (set_attr "memory" "none")])
17870 (define_insn "*prefetch_3dnow_<mode>"
17871 [(prefetch (match_operand:P 0 "address_operand" "p")
17872 (match_operand:SI 1 "const_int_operand" "n")
17876 if (INTVAL (operands[1]) == 0)
17877 return "prefetch\t%a0";
17879 return "prefetchw\t%a0";
17881 [(set_attr "type" "mmx")
17882 (set (attr "length_address")
17883 (symbol_ref "memory_address_length (operands[0])"))
17884 (set_attr "memory" "none")])
17886 (define_expand "stack_protect_set"
17887 [(match_operand 0 "memory_operand" "")
17888 (match_operand 1 "memory_operand" "")]
17891 rtx (*insn)(rtx, rtx);
17893 #ifdef TARGET_THREAD_SSP_OFFSET
17894 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17895 insn = (TARGET_64BIT
17896 ? gen_stack_tls_protect_set_di
17897 : gen_stack_tls_protect_set_si);
17899 insn = (TARGET_64BIT
17900 ? gen_stack_protect_set_di
17901 : gen_stack_protect_set_si);
17904 emit_insn (insn (operands[0], operands[1]));
17908 (define_insn "stack_protect_set_<mode>"
17909 [(set (match_operand:P 0 "memory_operand" "=m")
17910 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17911 (set (match_scratch:P 2 "=&r") (const_int 0))
17912 (clobber (reg:CC FLAGS_REG))]
17914 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17915 [(set_attr "type" "multi")])
17917 (define_insn "stack_tls_protect_set_<mode>"
17918 [(set (match_operand:P 0 "memory_operand" "=m")
17919 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17920 UNSPEC_SP_TLS_SET))
17921 (set (match_scratch:P 2 "=&r") (const_int 0))
17922 (clobber (reg:CC FLAGS_REG))]
17924 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17925 [(set_attr "type" "multi")])
17927 (define_expand "stack_protect_test"
17928 [(match_operand 0 "memory_operand" "")
17929 (match_operand 1 "memory_operand" "")
17930 (match_operand 2 "" "")]
17933 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17935 rtx (*insn)(rtx, rtx, rtx);
17937 #ifdef TARGET_THREAD_SSP_OFFSET
17938 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17939 insn = (TARGET_64BIT
17940 ? gen_stack_tls_protect_test_di
17941 : gen_stack_tls_protect_test_si);
17943 insn = (TARGET_64BIT
17944 ? gen_stack_protect_test_di
17945 : gen_stack_protect_test_si);
17948 emit_insn (insn (flags, operands[0], operands[1]));
17950 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17951 flags, const0_rtx, operands[2]));
17955 (define_insn "stack_protect_test_<mode>"
17956 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17957 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17958 (match_operand:P 2 "memory_operand" "m")]
17960 (clobber (match_scratch:P 3 "=&r"))]
17962 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17963 [(set_attr "type" "multi")])
17965 (define_insn "stack_tls_protect_test_<mode>"
17966 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17967 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17968 (match_operand:P 2 "const_int_operand" "i")]
17969 UNSPEC_SP_TLS_TEST))
17970 (clobber (match_scratch:P 3 "=r"))]
17972 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17973 [(set_attr "type" "multi")])
17975 (define_insn "sse4_2_crc32<mode>"
17976 [(set (match_operand:SI 0 "register_operand" "=r")
17978 [(match_operand:SI 1 "register_operand" "0")
17979 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17981 "TARGET_SSE4_2 || TARGET_CRC32"
17982 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17983 [(set_attr "type" "sselog1")
17984 (set_attr "prefix_rep" "1")
17985 (set_attr "prefix_extra" "1")
17986 (set (attr "prefix_data16")
17987 (if_then_else (match_operand:HI 2 "" "")
17989 (const_string "*")))
17990 (set (attr "prefix_rex")
17991 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17993 (const_string "*")))
17994 (set_attr "mode" "SI")])
17996 (define_insn "sse4_2_crc32di"
17997 [(set (match_operand:DI 0 "register_operand" "=r")
17999 [(match_operand:DI 1 "register_operand" "0")
18000 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18002 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18003 "crc32{q}\t{%2, %0|%0, %2}"
18004 [(set_attr "type" "sselog1")
18005 (set_attr "prefix_rep" "1")
18006 (set_attr "prefix_extra" "1")
18007 (set_attr "mode" "DI")])
18009 (define_expand "rdpmc"
18010 [(match_operand:DI 0 "register_operand" "")
18011 (match_operand:SI 1 "register_operand" "")]
18014 rtx reg = gen_reg_rtx (DImode);
18017 /* Force operand 1 into ECX. */
18018 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18019 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18020 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18025 rtvec vec = rtvec_alloc (2);
18026 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18027 rtx upper = gen_reg_rtx (DImode);
18028 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18029 gen_rtvec (1, const0_rtx),
18031 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18032 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18034 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18035 NULL, 1, OPTAB_DIRECT);
18036 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18040 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18041 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18045 (define_insn "*rdpmc"
18046 [(set (match_operand:DI 0 "register_operand" "=A")
18047 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18051 [(set_attr "type" "other")
18052 (set_attr "length" "2")])
18054 (define_insn "*rdpmc_rex64"
18055 [(set (match_operand:DI 0 "register_operand" "=a")
18056 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18058 (set (match_operand:DI 1 "register_operand" "=d")
18059 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18062 [(set_attr "type" "other")
18063 (set_attr "length" "2")])
18065 (define_expand "rdtsc"
18066 [(set (match_operand:DI 0 "register_operand" "")
18067 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18072 rtvec vec = rtvec_alloc (2);
18073 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18074 rtx upper = gen_reg_rtx (DImode);
18075 rtx lower = gen_reg_rtx (DImode);
18076 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18077 gen_rtvec (1, const0_rtx),
18079 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18080 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18082 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18083 NULL, 1, OPTAB_DIRECT);
18084 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18086 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18091 (define_insn "*rdtsc"
18092 [(set (match_operand:DI 0 "register_operand" "=A")
18093 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18096 [(set_attr "type" "other")
18097 (set_attr "length" "2")])
18099 (define_insn "*rdtsc_rex64"
18100 [(set (match_operand:DI 0 "register_operand" "=a")
18101 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18102 (set (match_operand:DI 1 "register_operand" "=d")
18103 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18106 [(set_attr "type" "other")
18107 (set_attr "length" "2")])
18109 (define_expand "rdtscp"
18110 [(match_operand:DI 0 "register_operand" "")
18111 (match_operand:SI 1 "memory_operand" "")]
18114 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18115 gen_rtvec (1, const0_rtx),
18117 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18118 gen_rtvec (1, const0_rtx),
18120 rtx reg = gen_reg_rtx (DImode);
18121 rtx tmp = gen_reg_rtx (SImode);
18125 rtvec vec = rtvec_alloc (3);
18126 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18127 rtx upper = gen_reg_rtx (DImode);
18128 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18129 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18130 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18132 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18133 NULL, 1, OPTAB_DIRECT);
18134 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18139 rtvec vec = rtvec_alloc (2);
18140 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18141 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18142 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18145 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18146 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18150 (define_insn "*rdtscp"
18151 [(set (match_operand:DI 0 "register_operand" "=A")
18152 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18153 (set (match_operand:SI 1 "register_operand" "=c")
18154 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18157 [(set_attr "type" "other")
18158 (set_attr "length" "3")])
18160 (define_insn "*rdtscp_rex64"
18161 [(set (match_operand:DI 0 "register_operand" "=a")
18162 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18163 (set (match_operand:DI 1 "register_operand" "=d")
18164 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18165 (set (match_operand:SI 2 "register_operand" "=c")
18166 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18169 [(set_attr "type" "other")
18170 (set_attr "length" "3")])
18172 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18174 ;; LWP instructions
18176 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18178 (define_expand "lwp_llwpcb"
18179 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18180 UNSPECV_LLWP_INTRINSIC)]
18183 (define_insn "*lwp_llwpcb<mode>1"
18184 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18185 UNSPECV_LLWP_INTRINSIC)]
18188 [(set_attr "type" "lwp")
18189 (set_attr "mode" "<MODE>")
18190 (set_attr "length" "5")])
18192 (define_expand "lwp_slwpcb"
18193 [(set (match_operand 0 "register_operand" "=r")
18194 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18198 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18200 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18204 (define_insn "lwp_slwpcb<mode>"
18205 [(set (match_operand:P 0 "register_operand" "=r")
18206 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18209 [(set_attr "type" "lwp")
18210 (set_attr "mode" "<MODE>")
18211 (set_attr "length" "5")])
18213 (define_expand "lwp_lwpval<mode>3"
18214 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18215 (match_operand:SI 2 "nonimmediate_operand" "rm")
18216 (match_operand:SI 3 "const_int_operand" "i")]
18217 UNSPECV_LWPVAL_INTRINSIC)]
18219 "/* Avoid unused variable warning. */
18222 (define_insn "*lwp_lwpval<mode>3_1"
18223 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18224 (match_operand:SI 1 "nonimmediate_operand" "rm")
18225 (match_operand:SI 2 "const_int_operand" "i")]
18226 UNSPECV_LWPVAL_INTRINSIC)]
18228 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18229 [(set_attr "type" "lwp")
18230 (set_attr "mode" "<MODE>")
18231 (set (attr "length")
18232 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18234 (define_expand "lwp_lwpins<mode>3"
18235 [(set (reg:CCC FLAGS_REG)
18236 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18237 (match_operand:SI 2 "nonimmediate_operand" "rm")
18238 (match_operand:SI 3 "const_int_operand" "i")]
18239 UNSPECV_LWPINS_INTRINSIC))
18240 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18241 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18244 (define_insn "*lwp_lwpins<mode>3_1"
18245 [(set (reg:CCC FLAGS_REG)
18246 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18247 (match_operand:SI 1 "nonimmediate_operand" "rm")
18248 (match_operand:SI 2 "const_int_operand" "i")]
18249 UNSPECV_LWPINS_INTRINSIC))]
18251 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18252 [(set_attr "type" "lwp")
18253 (set_attr "mode" "<MODE>")
18254 (set (attr "length")
18255 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18257 (define_insn "rdfsbase<mode>"
18258 [(set (match_operand:SWI48 0 "register_operand" "=r")
18259 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18260 "TARGET_64BIT && TARGET_FSGSBASE"
18262 [(set_attr "type" "other")
18263 (set_attr "prefix_extra" "2")])
18265 (define_insn "rdgsbase<mode>"
18266 [(set (match_operand:SWI48 0 "register_operand" "=r")
18267 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18268 "TARGET_64BIT && TARGET_FSGSBASE"
18270 [(set_attr "type" "other")
18271 (set_attr "prefix_extra" "2")])
18273 (define_insn "wrfsbase<mode>"
18274 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18276 "TARGET_64BIT && TARGET_FSGSBASE"
18278 [(set_attr "type" "other")
18279 (set_attr "prefix_extra" "2")])
18281 (define_insn "wrgsbase<mode>"
18282 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18284 "TARGET_64BIT && TARGET_FSGSBASE"
18286 [(set_attr "type" "other")
18287 (set_attr "prefix_extra" "2")])
18289 (define_insn "rdrand<mode>_1"
18290 [(set (match_operand:SWI248 0 "register_operand" "=r")
18291 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18292 (set (reg:CCC FLAGS_REG)
18293 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18296 [(set_attr "type" "other")
18297 (set_attr "prefix_extra" "1")])
18301 (include "sync.md")