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
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 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
67 [; Relocation specifiers
78 (UNSPEC_MACHOPIC_OFFSET 10)
81 (UNSPEC_STACK_ALLOC 11)
83 (UNSPEC_SSE_PROLOGUE_SAVE 13)
87 (UNSPEC_SET_GOT_OFFSET 17)
88 (UNSPEC_MEMORY_BLOCKAGE 18)
93 (UNSPEC_TLS_LD_BASE 22)
96 ; Other random patterns
101 (UNSPEC_ADD_CARRY 34)
104 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
105 (UNSPEC_TRUNC_NOOP 39)
107 ; For SSE/MMX support:
108 (UNSPEC_FIX_NOTRUNC 40)
125 (UNSPEC_MS_TO_SYSV_CALL 48)
127 ; Generic math support
129 (UNSPEC_IEEE_MIN 51) ; not commutative
130 (UNSPEC_IEEE_MAX 52) ; not commutative
145 (UNSPEC_FRNDINT_FLOOR 70)
146 (UNSPEC_FRNDINT_CEIL 71)
147 (UNSPEC_FRNDINT_TRUNC 72)
148 (UNSPEC_FRNDINT_MASK_PM 73)
149 (UNSPEC_FIST_FLOOR 74)
150 (UNSPEC_FIST_CEIL 75)
152 ; x87 Double output FP
153 (UNSPEC_SINCOS_COS 80)
154 (UNSPEC_SINCOS_SIN 81)
155 (UNSPEC_XTRACT_FRACT 84)
156 (UNSPEC_XTRACT_EXP 85)
157 (UNSPEC_FSCALE_FRACT 86)
158 (UNSPEC_FSCALE_EXP 87)
170 (UNSPEC_SP_TLS_SET 102)
171 (UNSPEC_SP_TLS_TEST 103)
181 (UNSPEC_INSERTQI 132)
186 (UNSPEC_INSERTPS 135)
188 (UNSPEC_MOVNTDQA 137)
190 (UNSPEC_PHMINPOSUW 139)
196 (UNSPEC_PCMPESTR 144)
197 (UNSPEC_PCMPISTR 145)
200 (UNSPEC_FMA4_INTRINSIC 150)
201 (UNSPEC_FMA4_FMADDSUB 151)
202 (UNSPEC_FMA4_FMSUBADD 152)
203 (UNSPEC_XOP_UNSIGNED_CMP 151)
204 (UNSPEC_XOP_TRUEFALSE 152)
205 (UNSPEC_XOP_PERMUTE 153)
207 (UNSPEC_LLWP_INTRINSIC 155)
208 (UNSPEC_SLWP_INTRINSIC 156)
209 (UNSPECV_LWPVAL_INTRINSIC 157)
210 (UNSPECV_LWPINS_INTRINSIC 158)
214 (UNSPEC_AESENCLAST 160)
216 (UNSPEC_AESDECLAST 162)
218 (UNSPEC_AESKEYGENASSIST 164)
226 (UNSPEC_VPERMIL2F128 168)
227 (UNSPEC_MASKLOAD 169)
228 (UNSPEC_MASKSTORE 170)
234 [(UNSPECV_BLOCKAGE 0)
235 (UNSPECV_STACK_PROBE 1)
247 (UNSPECV_PROLOGUE_USE 14)
249 (UNSPECV_VZEROALL 16)
250 (UNSPECV_VZEROUPPER 17)
254 (UNSPECV_VSWAPMOV 21)
257 ;; Constants to represent pcomtrue/pcomfalse variants
267 ;; Constants used in the XOP pperm instruction
269 [(PPERM_SRC 0x00) /* copy source */
270 (PPERM_INVERT 0x20) /* invert source */
271 (PPERM_REVERSE 0x40) /* bit reverse source */
272 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
273 (PPERM_ZERO 0x80) /* all 0's */
274 (PPERM_ONES 0xa0) /* all 1's */
275 (PPERM_SIGN 0xc0) /* propagate sign bit */
276 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
277 (PPERM_SRC1 0x00) /* use first source byte */
278 (PPERM_SRC2 0x10) /* use second source byte */
281 ;; Registers by name.
334 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
337 ;; In C guard expressions, put expressions which may be compile-time
338 ;; constants first. This allows for better optimization. For
339 ;; example, write "TARGET_64BIT && reload_completed", not
340 ;; "reload_completed && TARGET_64BIT".
344 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
346 (const (symbol_ref "ix86_schedule")))
348 ;; A basic instruction type. Refinements due to arguments to be
349 ;; provided in other attributes.
352 alu,alu1,negnot,imov,imovx,lea,
353 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
354 icmp,test,ibr,setcc,icmov,
355 push,pop,call,callv,leave,
357 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
358 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
359 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
360 ssemuladd,sse4arg,lwp,
361 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
362 (const_string "other"))
364 ;; Main data type used by the insn
366 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
367 (const_string "unknown"))
369 ;; The CPU unit operations uses.
370 (define_attr "unit" "integer,i387,sse,mmx,unknown"
371 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
372 (const_string "i387")
373 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
374 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
375 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
377 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
379 (eq_attr "type" "other")
380 (const_string "unknown")]
381 (const_string "integer")))
383 ;; The (bounding maximum) length of an instruction immediate.
384 (define_attr "length_immediate" ""
385 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
388 (eq_attr "unit" "i387,sse,mmx")
390 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
392 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
393 (eq_attr "type" "imov,test")
394 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
395 (eq_attr "type" "call")
396 (if_then_else (match_operand 0 "constant_call_address_operand" "")
399 (eq_attr "type" "callv")
400 (if_then_else (match_operand 1 "constant_call_address_operand" "")
403 ;; We don't know the size before shorten_branches. Expect
404 ;; the instruction to fit for better scheduling.
405 (eq_attr "type" "ibr")
408 (symbol_ref "/* Update immediate_length and other attributes! */
409 gcc_unreachable (),1")))
411 ;; The (bounding maximum) length of an instruction address.
412 (define_attr "length_address" ""
413 (cond [(eq_attr "type" "str,other,multi,fxch")
415 (and (eq_attr "type" "call")
416 (match_operand 0 "constant_call_address_operand" ""))
418 (and (eq_attr "type" "callv")
419 (match_operand 1 "constant_call_address_operand" ""))
422 (symbol_ref "ix86_attr_length_address_default (insn)")))
424 ;; Set when length prefix is used.
425 (define_attr "prefix_data16" ""
426 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
428 (eq_attr "mode" "HI")
430 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
435 ;; Set when string REP prefix is used.
436 (define_attr "prefix_rep" ""
437 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
444 ;; Set when 0f opcode prefix is used.
445 (define_attr "prefix_0f" ""
447 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
448 (eq_attr "unit" "sse,mmx"))
452 ;; Set when REX opcode prefix is used.
453 (define_attr "prefix_rex" ""
454 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
456 (and (eq_attr "mode" "DI")
457 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
458 (eq_attr "unit" "!mmx")))
460 (and (eq_attr "mode" "QI")
461 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
464 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
467 (and (eq_attr "type" "imovx")
468 (match_operand:QI 1 "ext_QIreg_operand" ""))
473 ;; There are also additional prefixes in 3DNOW, SSSE3.
474 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
475 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
476 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
477 (define_attr "prefix_extra" ""
478 (cond [(eq_attr "type" "ssemuladd,sse4arg")
480 (eq_attr "type" "sseiadd1,ssecvt1")
485 ;; Prefix used: original, VEX or maybe VEX.
486 (define_attr "prefix" "orig,vex,maybe_vex"
487 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
489 (const_string "orig")))
491 ;; VEX W bit is used.
492 (define_attr "prefix_vex_w" "" (const_int 0))
494 ;; The length of VEX prefix
495 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
496 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
497 ;; still prefix_0f 1, with prefix_extra 1.
498 (define_attr "length_vex" ""
499 (if_then_else (and (eq_attr "prefix_0f" "1")
500 (eq_attr "prefix_extra" "0"))
501 (if_then_else (eq_attr "prefix_vex_w" "1")
502 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
503 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
504 (if_then_else (eq_attr "prefix_vex_w" "1")
505 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
506 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
508 ;; Set when modrm byte is used.
509 (define_attr "modrm" ""
510 (cond [(eq_attr "type" "str,leave")
512 (eq_attr "unit" "i387")
514 (and (eq_attr "type" "incdec")
515 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
516 (ior (match_operand:SI 1 "register_operand" "")
517 (match_operand:HI 1 "register_operand" ""))))
519 (and (eq_attr "type" "push")
520 (not (match_operand 1 "memory_operand" "")))
522 (and (eq_attr "type" "pop")
523 (not (match_operand 0 "memory_operand" "")))
525 (and (eq_attr "type" "imov")
526 (and (not (eq_attr "mode" "DI"))
527 (ior (and (match_operand 0 "register_operand" "")
528 (match_operand 1 "immediate_operand" ""))
529 (ior (and (match_operand 0 "ax_reg_operand" "")
530 (match_operand 1 "memory_displacement_only_operand" ""))
531 (and (match_operand 0 "memory_displacement_only_operand" "")
532 (match_operand 1 "ax_reg_operand" ""))))))
534 (and (eq_attr "type" "call")
535 (match_operand 0 "constant_call_address_operand" ""))
537 (and (eq_attr "type" "callv")
538 (match_operand 1 "constant_call_address_operand" ""))
540 (and (eq_attr "type" "alu,alu1,icmp,test")
541 (match_operand 0 "ax_reg_operand" ""))
542 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
546 ;; The (bounding maximum) length of an instruction in bytes.
547 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
548 ;; Later we may want to split them and compute proper length as for
550 (define_attr "length" ""
551 (cond [(eq_attr "type" "other,multi,fistp,frndint")
553 (eq_attr "type" "fcmp")
555 (eq_attr "unit" "i387")
557 (plus (attr "prefix_data16")
558 (attr "length_address")))
559 (ior (eq_attr "prefix" "vex")
560 (and (eq_attr "prefix" "maybe_vex")
561 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
562 (plus (attr "length_vex")
563 (plus (attr "length_immediate")
565 (attr "length_address"))))]
566 (plus (plus (attr "modrm")
567 (plus (attr "prefix_0f")
568 (plus (attr "prefix_rex")
569 (plus (attr "prefix_extra")
571 (plus (attr "prefix_rep")
572 (plus (attr "prefix_data16")
573 (plus (attr "length_immediate")
574 (attr "length_address")))))))
576 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
577 ;; `store' if there is a simple memory reference therein, or `unknown'
578 ;; if the instruction is complex.
580 (define_attr "memory" "none,load,store,both,unknown"
581 (cond [(eq_attr "type" "other,multi,str")
582 (const_string "unknown")
583 (eq_attr "type" "lea,fcmov,fpspc")
584 (const_string "none")
585 (eq_attr "type" "fistp,leave")
586 (const_string "both")
587 (eq_attr "type" "frndint")
588 (const_string "load")
589 (eq_attr "type" "push")
590 (if_then_else (match_operand 1 "memory_operand" "")
591 (const_string "both")
592 (const_string "store"))
593 (eq_attr "type" "pop")
594 (if_then_else (match_operand 0 "memory_operand" "")
595 (const_string "both")
596 (const_string "load"))
597 (eq_attr "type" "setcc")
598 (if_then_else (match_operand 0 "memory_operand" "")
599 (const_string "store")
600 (const_string "none"))
601 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
602 (if_then_else (ior (match_operand 0 "memory_operand" "")
603 (match_operand 1 "memory_operand" ""))
604 (const_string "load")
605 (const_string "none"))
606 (eq_attr "type" "ibr")
607 (if_then_else (match_operand 0 "memory_operand" "")
608 (const_string "load")
609 (const_string "none"))
610 (eq_attr "type" "call")
611 (if_then_else (match_operand 0 "constant_call_address_operand" "")
612 (const_string "none")
613 (const_string "load"))
614 (eq_attr "type" "callv")
615 (if_then_else (match_operand 1 "constant_call_address_operand" "")
616 (const_string "none")
617 (const_string "load"))
618 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
619 (match_operand 1 "memory_operand" ""))
620 (const_string "both")
621 (and (match_operand 0 "memory_operand" "")
622 (match_operand 1 "memory_operand" ""))
623 (const_string "both")
624 (match_operand 0 "memory_operand" "")
625 (const_string "store")
626 (match_operand 1 "memory_operand" "")
627 (const_string "load")
629 "!alu1,negnot,ishift1,
630 imov,imovx,icmp,test,bitmanip,
632 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
633 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
634 (match_operand 2 "memory_operand" ""))
635 (const_string "load")
636 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
637 (match_operand 3 "memory_operand" ""))
638 (const_string "load")
640 (const_string "none")))
642 ;; Indicates if an instruction has both an immediate and a displacement.
644 (define_attr "imm_disp" "false,true,unknown"
645 (cond [(eq_attr "type" "other,multi")
646 (const_string "unknown")
647 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
648 (and (match_operand 0 "memory_displacement_operand" "")
649 (match_operand 1 "immediate_operand" "")))
650 (const_string "true")
651 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
652 (and (match_operand 0 "memory_displacement_operand" "")
653 (match_operand 2 "immediate_operand" "")))
654 (const_string "true")
656 (const_string "false")))
658 ;; Indicates if an FP operation has an integer source.
660 (define_attr "fp_int_src" "false,true"
661 (const_string "false"))
663 ;; Defines rounding mode of an FP operation.
665 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
666 (const_string "any"))
668 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
669 (define_attr "use_carry" "0,1" (const_string "0"))
671 ;; Define attribute to indicate unaligned ssemov insns
672 (define_attr "movu" "0,1" (const_string "0"))
674 ;; Describe a user's asm statement.
675 (define_asm_attributes
676 [(set_attr "length" "128")
677 (set_attr "type" "multi")])
679 ;; All integer comparison codes.
680 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
682 ;; All floating-point comparison codes.
683 (define_code_iterator fp_cond [unordered ordered
684 uneq unge ungt unle unlt ltgt ])
686 (define_code_iterator plusminus [plus minus])
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697 [(plus "add") (ss_plus "adds") (us_plus "addus")
698 (minus "sub") (ss_minus "subs") (us_minus "subus")])
700 ;; Mark commutative operators as such in constraints.
701 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
702 (minus "") (ss_minus "") (us_minus "")])
704 ;; Mapping of signed max and min
705 (define_code_iterator smaxmin [smax smin])
707 ;; Mapping of unsigned max and min
708 (define_code_iterator umaxmin [umax umin])
710 ;; Mapping of signed/unsigned max and min
711 (define_code_iterator maxmin [smax smin umax umin])
713 ;; Base name for integer and FP insn mnemonic
714 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
715 (umax "maxu") (umin "minu")])
716 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
718 ;; Mapping of parallel logic operators
719 (define_code_iterator plogic [and ior xor])
721 ;; Base name for insn mnemonic.
722 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
724 ;; Mapping of abs neg operators
725 (define_code_iterator absneg [abs neg])
727 ;; Base name for x87 insn mnemonic.
728 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
730 ;; Used in signed and unsigned widening multiplications.
731 (define_code_iterator any_extend [sign_extend zero_extend])
733 ;; Used in signed and unsigned divisions.
734 (define_code_iterator any_div [div udiv])
736 ;; Various insn prefixes for signed and unsigned operations.
737 (define_code_attr u [(sign_extend "") (zero_extend "u")
738 (div "") (udiv "u")])
739 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
741 ;; Instruction prefix for signed and unsigned operations.
742 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
743 (div "i") (udiv "")])
745 ;; All single word integer modes.
746 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
748 ;; Single word integer modes without QImode.
749 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
751 ;; Single word integer modes without QImode and HImode.
752 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
754 ;; All math-dependant single and double word integer modes.
755 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
756 (HI "TARGET_HIMODE_MATH")
757 SI DI (TI "TARGET_64BIT")])
759 ;; Math-dependant single word integer modes.
760 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
761 (HI "TARGET_HIMODE_MATH")
762 SI (DI "TARGET_64BIT")])
764 ;; Math-dependant single word integer modes without QImode.
765 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
766 SI (DI "TARGET_64BIT")])
768 ;; Half mode for double word integer modes.
769 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
770 (DI "TARGET_64BIT")])
772 ;; Double word integer modes.
773 (define_mode_attr DWI [(SI "DI") (DI "TI")])
774 (define_mode_attr dwi [(SI "di") (DI "ti")])
776 ;; Instruction suffix for integer modes.
777 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
779 ;; Register class for integer modes.
780 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
782 ;; Immediate operand constraint for integer modes.
783 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
785 ;; General operand constraint for word modes.
786 (define_mode_attr g [(SI "g") (DI "rme")])
788 ;; Immediate operand constraint for double integer modes.
789 (define_mode_attr di [(SI "iF") (DI "e")])
791 ;; General operand predicate for integer modes.
792 (define_mode_attr general_operand
793 [(QI "general_operand")
794 (HI "general_operand")
795 (SI "general_operand")
796 (DI "x86_64_general_operand")
797 (TI "x86_64_general_operand")])
799 ;; SSE and x87 SFmode and DFmode floating point modes
800 (define_mode_iterator MODEF [SF DF])
802 ;; All x87 floating point modes
803 (define_mode_iterator X87MODEF [SF DF XF])
805 ;; All integer modes handled by x87 fisttp operator.
806 (define_mode_iterator X87MODEI [HI SI DI])
808 ;; All integer modes handled by integer x87 operators.
809 (define_mode_iterator X87MODEI12 [HI SI])
811 ;; All integer modes handled by SSE cvtts?2si* operators.
812 (define_mode_iterator SSEMODEI24 [SI DI])
814 ;; SSE asm suffix for floating point modes
815 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
817 ;; SSE vector mode corresponding to a scalar mode
818 (define_mode_attr ssevecmode
819 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
821 ;; Instruction suffix for REX 64bit operators.
822 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
824 ;; This mode iterator allows :P to be used for patterns that operate on
825 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
826 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
828 ;; Scheduling descriptions
830 (include "pentium.md")
833 (include "athlon.md")
838 ;; Operand and operator predicates and constraints
840 (include "predicates.md")
841 (include "constraints.md")
844 ;; Compare and branch/compare and store instructions.
846 (define_expand "cbranchti4"
847 [(set (reg:CC FLAGS_REG)
848 (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
849 (match_operand:TI 2 "x86_64_general_operand" "")))
850 (set (pc) (if_then_else
851 (match_operator 0 "comparison_operator"
854 (label_ref (match_operand 3 "" ""))
858 if (MEM_P (operands[1]) && MEM_P (operands[2]))
859 operands[1] = force_reg (TImode, operands[1]);
860 ix86_compare_op0 = operands[1];
861 ix86_compare_op1 = operands[2];
862 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
866 (define_expand "cbranchdi4"
867 [(set (reg:CC FLAGS_REG)
868 (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
869 (match_operand:DI 2 "x86_64_general_operand" "")))
870 (set (pc) (if_then_else
871 (match_operator 0 "comparison_operator"
874 (label_ref (match_operand 3 "" ""))
878 if (MEM_P (operands[1]) && MEM_P (operands[2]))
879 operands[1] = force_reg (DImode, operands[1]);
880 ix86_compare_op0 = operands[1];
881 ix86_compare_op1 = operands[2];
882 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
886 (define_expand "cstoredi4"
887 [(set (reg:CC FLAGS_REG)
888 (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
889 (match_operand:DI 3 "x86_64_general_operand" "")))
890 (set (match_operand:QI 0 "register_operand" "")
891 (match_operator 1 "comparison_operator"
896 if (MEM_P (operands[2]) && MEM_P (operands[3]))
897 operands[2] = force_reg (DImode, operands[2]);
898 ix86_compare_op0 = operands[2];
899 ix86_compare_op1 = operands[3];
900 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
904 (define_expand "cbranchsi4"
905 [(set (reg:CC FLAGS_REG)
906 (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
907 (match_operand:SI 2 "general_operand" "")))
908 (set (pc) (if_then_else
909 (match_operator 0 "comparison_operator"
912 (label_ref (match_operand 3 "" ""))
916 if (MEM_P (operands[1]) && MEM_P (operands[2]))
917 operands[1] = force_reg (SImode, operands[1]);
918 ix86_compare_op0 = operands[1];
919 ix86_compare_op1 = operands[2];
920 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
924 (define_expand "cstoresi4"
925 [(set (reg:CC FLAGS_REG)
926 (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
927 (match_operand:SI 3 "general_operand" "")))
928 (set (match_operand:QI 0 "register_operand" "")
929 (match_operator 1 "comparison_operator"
934 if (MEM_P (operands[2]) && MEM_P (operands[3]))
935 operands[2] = force_reg (SImode, operands[2]);
936 ix86_compare_op0 = operands[2];
937 ix86_compare_op1 = operands[3];
938 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
942 (define_expand "cbranchhi4"
943 [(set (reg:CC FLAGS_REG)
944 (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
945 (match_operand:HI 2 "general_operand" "")))
946 (set (pc) (if_then_else
947 (match_operator 0 "comparison_operator"
950 (label_ref (match_operand 3 "" ""))
954 if (MEM_P (operands[1]) && MEM_P (operands[2]))
955 operands[1] = force_reg (HImode, operands[1]);
956 ix86_compare_op0 = operands[1];
957 ix86_compare_op1 = operands[2];
958 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
962 (define_expand "cstorehi4"
963 [(set (reg:CC FLAGS_REG)
964 (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
965 (match_operand:HI 3 "general_operand" "")))
966 (set (match_operand:QI 0 "register_operand" "")
967 (match_operator 1 "comparison_operator"
972 if (MEM_P (operands[2]) && MEM_P (operands[3]))
973 operands[2] = force_reg (HImode, operands[2]);
974 ix86_compare_op0 = operands[2];
975 ix86_compare_op1 = operands[3];
976 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
981 (define_expand "cbranchqi4"
982 [(set (reg:CC FLAGS_REG)
983 (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
984 (match_operand:QI 2 "general_operand" "")))
985 (set (pc) (if_then_else
986 (match_operator 0 "comparison_operator"
989 (label_ref (match_operand 3 "" ""))
993 if (MEM_P (operands[1]) && MEM_P (operands[2]))
994 operands[1] = force_reg (QImode, operands[1]);
995 ix86_compare_op0 = operands[1];
996 ix86_compare_op1 = operands[2];
997 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1002 (define_expand "cstoreqi4"
1003 [(set (reg:CC FLAGS_REG)
1004 (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
1005 (match_operand:QI 3 "general_operand" "")))
1006 (set (match_operand:QI 0 "register_operand" "")
1007 (match_operator 1 "comparison_operator"
1012 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1013 operands[2] = force_reg (QImode, operands[2]);
1014 ix86_compare_op0 = operands[2];
1015 ix86_compare_op1 = operands[3];
1016 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1021 (define_insn "cmpdi_ccno_1_rex64"
1022 [(set (reg FLAGS_REG)
1023 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
1024 (match_operand:DI 1 "const0_operand" "")))]
1025 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1028 cmp{q}\t{%1, %0|%0, %1}"
1029 [(set_attr "type" "test,icmp")
1030 (set_attr "length_immediate" "0,1")
1031 (set_attr "mode" "DI")])
1033 (define_insn "*cmpdi_minus_1_rex64"
1034 [(set (reg FLAGS_REG)
1035 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
1036 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
1038 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
1039 "cmp{q}\t{%1, %0|%0, %1}"
1040 [(set_attr "type" "icmp")
1041 (set_attr "mode" "DI")])
1043 (define_expand "cmpdi_1_rex64"
1044 [(set (reg:CC FLAGS_REG)
1045 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1046 (match_operand:DI 1 "general_operand" "")))]
1050 (define_insn "cmpdi_1_insn_rex64"
1051 [(set (reg FLAGS_REG)
1052 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1053 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1054 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1055 "cmp{q}\t{%1, %0|%0, %1}"
1056 [(set_attr "type" "icmp")
1057 (set_attr "mode" "DI")])
1060 (define_insn "*cmpsi_ccno_1"
1061 [(set (reg FLAGS_REG)
1062 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1063 (match_operand:SI 1 "const0_operand" "")))]
1064 "ix86_match_ccmode (insn, CCNOmode)"
1067 cmp{l}\t{%1, %0|%0, %1}"
1068 [(set_attr "type" "test,icmp")
1069 (set_attr "length_immediate" "0,1")
1070 (set_attr "mode" "SI")])
1072 (define_insn "*cmpsi_minus_1"
1073 [(set (reg FLAGS_REG)
1074 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1075 (match_operand:SI 1 "general_operand" "ri,mr"))
1077 "ix86_match_ccmode (insn, CCGOCmode)"
1078 "cmp{l}\t{%1, %0|%0, %1}"
1079 [(set_attr "type" "icmp")
1080 (set_attr "mode" "SI")])
1082 (define_expand "cmpsi_1"
1083 [(set (reg:CC FLAGS_REG)
1084 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
1085 (match_operand:SI 1 "general_operand" "")))]
1089 (define_insn "*cmpsi_1_insn"
1090 [(set (reg FLAGS_REG)
1091 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1092 (match_operand:SI 1 "general_operand" "ri,mr")))]
1093 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1094 && ix86_match_ccmode (insn, CCmode)"
1095 "cmp{l}\t{%1, %0|%0, %1}"
1096 [(set_attr "type" "icmp")
1097 (set_attr "mode" "SI")])
1099 (define_insn "*cmphi_ccno_1"
1100 [(set (reg FLAGS_REG)
1101 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1102 (match_operand:HI 1 "const0_operand" "")))]
1103 "ix86_match_ccmode (insn, CCNOmode)"
1106 cmp{w}\t{%1, %0|%0, %1}"
1107 [(set_attr "type" "test,icmp")
1108 (set_attr "length_immediate" "0,1")
1109 (set_attr "mode" "HI")])
1111 (define_insn "*cmphi_minus_1"
1112 [(set (reg FLAGS_REG)
1113 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1114 (match_operand:HI 1 "general_operand" "rn,mr"))
1116 "ix86_match_ccmode (insn, CCGOCmode)"
1117 "cmp{w}\t{%1, %0|%0, %1}"
1118 [(set_attr "type" "icmp")
1119 (set_attr "mode" "HI")])
1121 (define_insn "*cmphi_1"
1122 [(set (reg FLAGS_REG)
1123 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1124 (match_operand:HI 1 "general_operand" "rn,mr")))]
1125 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1126 && ix86_match_ccmode (insn, CCmode)"
1127 "cmp{w}\t{%1, %0|%0, %1}"
1128 [(set_attr "type" "icmp")
1129 (set_attr "mode" "HI")])
1131 (define_insn "*cmpqi_ccno_1"
1132 [(set (reg FLAGS_REG)
1133 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1134 (match_operand:QI 1 "const0_operand" "")))]
1135 "ix86_match_ccmode (insn, CCNOmode)"
1138 cmp{b}\t{$0, %0|%0, 0}"
1139 [(set_attr "type" "test,icmp")
1140 (set_attr "length_immediate" "0,1")
1141 (set_attr "mode" "QI")])
1143 (define_insn "*cmpqi_1"
1144 [(set (reg FLAGS_REG)
1145 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1146 (match_operand:QI 1 "general_operand" "qn,mq")))]
1147 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1148 && ix86_match_ccmode (insn, CCmode)"
1149 "cmp{b}\t{%1, %0|%0, %1}"
1150 [(set_attr "type" "icmp")
1151 (set_attr "mode" "QI")])
1153 (define_insn "*cmpqi_minus_1"
1154 [(set (reg FLAGS_REG)
1155 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1156 (match_operand:QI 1 "general_operand" "qn,mq"))
1158 "ix86_match_ccmode (insn, CCGOCmode)"
1159 "cmp{b}\t{%1, %0|%0, %1}"
1160 [(set_attr "type" "icmp")
1161 (set_attr "mode" "QI")])
1163 (define_insn "*cmpqi_ext_1"
1164 [(set (reg FLAGS_REG)
1166 (match_operand:QI 0 "general_operand" "Qm")
1169 (match_operand 1 "ext_register_operand" "Q")
1171 (const_int 8)) 0)))]
1172 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1173 "cmp{b}\t{%h1, %0|%0, %h1}"
1174 [(set_attr "type" "icmp")
1175 (set_attr "mode" "QI")])
1177 (define_insn "*cmpqi_ext_1_rex64"
1178 [(set (reg FLAGS_REG)
1180 (match_operand:QI 0 "register_operand" "Q")
1183 (match_operand 1 "ext_register_operand" "Q")
1185 (const_int 8)) 0)))]
1186 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1187 "cmp{b}\t{%h1, %0|%0, %h1}"
1188 [(set_attr "type" "icmp")
1189 (set_attr "mode" "QI")])
1191 (define_insn "*cmpqi_ext_2"
1192 [(set (reg FLAGS_REG)
1196 (match_operand 0 "ext_register_operand" "Q")
1199 (match_operand:QI 1 "const0_operand" "")))]
1200 "ix86_match_ccmode (insn, CCNOmode)"
1202 [(set_attr "type" "test")
1203 (set_attr "length_immediate" "0")
1204 (set_attr "mode" "QI")])
1206 (define_expand "cmpqi_ext_3"
1207 [(set (reg:CC FLAGS_REG)
1211 (match_operand 0 "ext_register_operand" "")
1214 (match_operand:QI 1 "general_operand" "")))]
1218 (define_insn "cmpqi_ext_3_insn"
1219 [(set (reg FLAGS_REG)
1223 (match_operand 0 "ext_register_operand" "Q")
1226 (match_operand:QI 1 "general_operand" "Qmn")))]
1227 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1228 "cmp{b}\t{%1, %h0|%h0, %1}"
1229 [(set_attr "type" "icmp")
1230 (set_attr "modrm" "1")
1231 (set_attr "mode" "QI")])
1233 (define_insn "cmpqi_ext_3_insn_rex64"
1234 [(set (reg FLAGS_REG)
1238 (match_operand 0 "ext_register_operand" "Q")
1241 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1242 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1243 "cmp{b}\t{%1, %h0|%h0, %1}"
1244 [(set_attr "type" "icmp")
1245 (set_attr "modrm" "1")
1246 (set_attr "mode" "QI")])
1248 (define_insn "*cmpqi_ext_4"
1249 [(set (reg FLAGS_REG)
1253 (match_operand 0 "ext_register_operand" "Q")
1258 (match_operand 1 "ext_register_operand" "Q")
1260 (const_int 8)) 0)))]
1261 "ix86_match_ccmode (insn, CCmode)"
1262 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1263 [(set_attr "type" "icmp")
1264 (set_attr "mode" "QI")])
1266 ;; These implement float point compares.
1267 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1268 ;; which would allow mix and match FP modes on the compares. Which is what
1269 ;; the old patterns did, but with many more of them.
1271 (define_expand "cbranchxf4"
1272 [(set (reg:CC FLAGS_REG)
1273 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1274 (match_operand:XF 2 "nonmemory_operand" "")))
1275 (set (pc) (if_then_else
1276 (match_operator 0 "ix86_fp_comparison_operator"
1279 (label_ref (match_operand 3 "" ""))
1283 ix86_compare_op0 = operands[1];
1284 ix86_compare_op1 = operands[2];
1285 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1289 (define_expand "cstorexf4"
1290 [(set (reg:CC FLAGS_REG)
1291 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1292 (match_operand:XF 3 "nonmemory_operand" "")))
1293 (set (match_operand:QI 0 "register_operand" "")
1294 (match_operator 1 "ix86_fp_comparison_operator"
1299 ix86_compare_op0 = operands[2];
1300 ix86_compare_op1 = operands[3];
1301 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1305 (define_expand "cbranch<mode>4"
1306 [(set (reg:CC FLAGS_REG)
1307 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1308 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1309 (set (pc) (if_then_else
1310 (match_operator 0 "ix86_fp_comparison_operator"
1313 (label_ref (match_operand 3 "" ""))
1315 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1317 ix86_compare_op0 = operands[1];
1318 ix86_compare_op1 = operands[2];
1319 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1323 (define_expand "cstore<mode>4"
1324 [(set (reg:CC FLAGS_REG)
1325 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1326 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1327 (set (match_operand:QI 0 "register_operand" "")
1328 (match_operator 1 "ix86_fp_comparison_operator"
1331 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1333 ix86_compare_op0 = operands[2];
1334 ix86_compare_op1 = operands[3];
1335 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1339 (define_expand "cbranchcc4"
1340 [(set (pc) (if_then_else
1341 (match_operator 0 "comparison_operator"
1342 [(match_operand 1 "flags_reg_operand" "")
1343 (match_operand 2 "const0_operand" "")])
1344 (label_ref (match_operand 3 "" ""))
1348 ix86_compare_op0 = operands[1];
1349 ix86_compare_op1 = operands[2];
1350 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1354 (define_expand "cstorecc4"
1355 [(set (match_operand:QI 0 "register_operand" "")
1356 (match_operator 1 "comparison_operator"
1357 [(match_operand 2 "flags_reg_operand" "")
1358 (match_operand 3 "const0_operand" "")]))]
1361 ix86_compare_op0 = operands[2];
1362 ix86_compare_op1 = operands[3];
1363 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1368 ;; FP compares, step 1:
1369 ;; Set the FP condition codes.
1371 ;; CCFPmode compare with exceptions
1372 ;; CCFPUmode compare with no exceptions
1374 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1375 ;; used to manage the reg stack popping would not be preserved.
1377 (define_insn "*cmpfp_0"
1378 [(set (match_operand:HI 0 "register_operand" "=a")
1381 (match_operand 1 "register_operand" "f")
1382 (match_operand 2 "const0_operand" ""))]
1384 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1385 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1386 "* return output_fp_compare (insn, operands, 0, 0);"
1387 [(set_attr "type" "multi")
1388 (set_attr "unit" "i387")
1390 (cond [(match_operand:SF 1 "" "")
1392 (match_operand:DF 1 "" "")
1395 (const_string "XF")))])
1397 (define_insn_and_split "*cmpfp_0_cc"
1398 [(set (reg:CCFP FLAGS_REG)
1400 (match_operand 1 "register_operand" "f")
1401 (match_operand 2 "const0_operand" "")))
1402 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1403 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1404 && TARGET_SAHF && !TARGET_CMOVE
1405 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1407 "&& reload_completed"
1410 [(compare:CCFP (match_dup 1)(match_dup 2))]
1412 (set (reg:CC FLAGS_REG)
1413 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1415 [(set_attr "type" "multi")
1416 (set_attr "unit" "i387")
1418 (cond [(match_operand:SF 1 "" "")
1420 (match_operand:DF 1 "" "")
1423 (const_string "XF")))])
1425 (define_insn "*cmpfp_xf"
1426 [(set (match_operand:HI 0 "register_operand" "=a")
1429 (match_operand:XF 1 "register_operand" "f")
1430 (match_operand:XF 2 "register_operand" "f"))]
1433 "* return output_fp_compare (insn, operands, 0, 0);"
1434 [(set_attr "type" "multi")
1435 (set_attr "unit" "i387")
1436 (set_attr "mode" "XF")])
1438 (define_insn_and_split "*cmpfp_xf_cc"
1439 [(set (reg:CCFP FLAGS_REG)
1441 (match_operand:XF 1 "register_operand" "f")
1442 (match_operand:XF 2 "register_operand" "f")))
1443 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1445 && TARGET_SAHF && !TARGET_CMOVE"
1447 "&& reload_completed"
1450 [(compare:CCFP (match_dup 1)(match_dup 2))]
1452 (set (reg:CC FLAGS_REG)
1453 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1455 [(set_attr "type" "multi")
1456 (set_attr "unit" "i387")
1457 (set_attr "mode" "XF")])
1459 (define_insn "*cmpfp_<mode>"
1460 [(set (match_operand:HI 0 "register_operand" "=a")
1463 (match_operand:MODEF 1 "register_operand" "f")
1464 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1467 "* return output_fp_compare (insn, operands, 0, 0);"
1468 [(set_attr "type" "multi")
1469 (set_attr "unit" "i387")
1470 (set_attr "mode" "<MODE>")])
1472 (define_insn_and_split "*cmpfp_<mode>_cc"
1473 [(set (reg:CCFP FLAGS_REG)
1475 (match_operand:MODEF 1 "register_operand" "f")
1476 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1477 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1479 && TARGET_SAHF && !TARGET_CMOVE"
1481 "&& reload_completed"
1484 [(compare:CCFP (match_dup 1)(match_dup 2))]
1486 (set (reg:CC FLAGS_REG)
1487 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1489 [(set_attr "type" "multi")
1490 (set_attr "unit" "i387")
1491 (set_attr "mode" "<MODE>")])
1493 (define_insn "*cmpfp_u"
1494 [(set (match_operand:HI 0 "register_operand" "=a")
1497 (match_operand 1 "register_operand" "f")
1498 (match_operand 2 "register_operand" "f"))]
1500 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1501 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1502 "* return output_fp_compare (insn, operands, 0, 1);"
1503 [(set_attr "type" "multi")
1504 (set_attr "unit" "i387")
1506 (cond [(match_operand:SF 1 "" "")
1508 (match_operand:DF 1 "" "")
1511 (const_string "XF")))])
1513 (define_insn_and_split "*cmpfp_u_cc"
1514 [(set (reg:CCFPU FLAGS_REG)
1516 (match_operand 1 "register_operand" "f")
1517 (match_operand 2 "register_operand" "f")))
1518 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1519 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1520 && TARGET_SAHF && !TARGET_CMOVE
1521 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1523 "&& reload_completed"
1526 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1528 (set (reg:CC FLAGS_REG)
1529 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1531 [(set_attr "type" "multi")
1532 (set_attr "unit" "i387")
1534 (cond [(match_operand:SF 1 "" "")
1536 (match_operand:DF 1 "" "")
1539 (const_string "XF")))])
1541 (define_insn "*cmpfp_<mode>"
1542 [(set (match_operand:HI 0 "register_operand" "=a")
1545 (match_operand 1 "register_operand" "f")
1546 (match_operator 3 "float_operator"
1547 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1549 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1550 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1551 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1552 "* return output_fp_compare (insn, operands, 0, 0);"
1553 [(set_attr "type" "multi")
1554 (set_attr "unit" "i387")
1555 (set_attr "fp_int_src" "true")
1556 (set_attr "mode" "<MODE>")])
1558 (define_insn_and_split "*cmpfp_<mode>_cc"
1559 [(set (reg:CCFP FLAGS_REG)
1561 (match_operand 1 "register_operand" "f")
1562 (match_operator 3 "float_operator"
1563 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1564 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1565 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1566 && TARGET_SAHF && !TARGET_CMOVE
1567 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1568 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1570 "&& reload_completed"
1575 (match_op_dup 3 [(match_dup 2)]))]
1577 (set (reg:CC FLAGS_REG)
1578 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1580 [(set_attr "type" "multi")
1581 (set_attr "unit" "i387")
1582 (set_attr "fp_int_src" "true")
1583 (set_attr "mode" "<MODE>")])
1585 ;; FP compares, step 2
1586 ;; Move the fpsw to ax.
1588 (define_insn "x86_fnstsw_1"
1589 [(set (match_operand:HI 0 "register_operand" "=a")
1590 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1593 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1594 (set_attr "mode" "SI")
1595 (set_attr "unit" "i387")])
1597 ;; FP compares, step 3
1598 ;; Get ax into flags, general case.
1600 (define_insn "x86_sahf_1"
1601 [(set (reg:CC FLAGS_REG)
1602 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1606 #ifdef HAVE_AS_IX86_SAHF
1609 return ASM_BYTE "0x9e";
1612 [(set_attr "length" "1")
1613 (set_attr "athlon_decode" "vector")
1614 (set_attr "amdfam10_decode" "direct")
1615 (set_attr "mode" "SI")])
1617 ;; Pentium Pro can do steps 1 through 3 in one go.
1618 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1619 (define_insn "*cmpfp_i_mixed"
1620 [(set (reg:CCFP FLAGS_REG)
1621 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1622 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1623 "TARGET_MIX_SSE_I387
1624 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1625 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1626 "* return output_fp_compare (insn, operands, 1, 0);"
1627 [(set_attr "type" "fcmp,ssecomi")
1628 (set_attr "prefix" "orig,maybe_vex")
1630 (if_then_else (match_operand:SF 1 "" "")
1632 (const_string "DF")))
1633 (set (attr "prefix_rep")
1634 (if_then_else (eq_attr "type" "ssecomi")
1636 (const_string "*")))
1637 (set (attr "prefix_data16")
1638 (cond [(eq_attr "type" "fcmp")
1640 (eq_attr "mode" "DF")
1643 (const_string "0")))
1644 (set_attr "athlon_decode" "vector")
1645 (set_attr "amdfam10_decode" "direct")])
1647 (define_insn "*cmpfp_i_sse"
1648 [(set (reg:CCFP FLAGS_REG)
1649 (compare:CCFP (match_operand 0 "register_operand" "x")
1650 (match_operand 1 "nonimmediate_operand" "xm")))]
1652 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1653 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1654 "* return output_fp_compare (insn, operands, 1, 0);"
1655 [(set_attr "type" "ssecomi")
1656 (set_attr "prefix" "maybe_vex")
1658 (if_then_else (match_operand:SF 1 "" "")
1660 (const_string "DF")))
1661 (set_attr "prefix_rep" "0")
1662 (set (attr "prefix_data16")
1663 (if_then_else (eq_attr "mode" "DF")
1665 (const_string "0")))
1666 (set_attr "athlon_decode" "vector")
1667 (set_attr "amdfam10_decode" "direct")])
1669 (define_insn "*cmpfp_i_i387"
1670 [(set (reg:CCFP FLAGS_REG)
1671 (compare:CCFP (match_operand 0 "register_operand" "f")
1672 (match_operand 1 "register_operand" "f")))]
1673 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1675 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1676 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1677 "* return output_fp_compare (insn, operands, 1, 0);"
1678 [(set_attr "type" "fcmp")
1680 (cond [(match_operand:SF 1 "" "")
1682 (match_operand:DF 1 "" "")
1685 (const_string "XF")))
1686 (set_attr "athlon_decode" "vector")
1687 (set_attr "amdfam10_decode" "direct")])
1689 (define_insn "*cmpfp_iu_mixed"
1690 [(set (reg:CCFPU FLAGS_REG)
1691 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1692 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1693 "TARGET_MIX_SSE_I387
1694 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1695 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1696 "* return output_fp_compare (insn, operands, 1, 1);"
1697 [(set_attr "type" "fcmp,ssecomi")
1698 (set_attr "prefix" "orig,maybe_vex")
1700 (if_then_else (match_operand:SF 1 "" "")
1702 (const_string "DF")))
1703 (set (attr "prefix_rep")
1704 (if_then_else (eq_attr "type" "ssecomi")
1706 (const_string "*")))
1707 (set (attr "prefix_data16")
1708 (cond [(eq_attr "type" "fcmp")
1710 (eq_attr "mode" "DF")
1713 (const_string "0")))
1714 (set_attr "athlon_decode" "vector")
1715 (set_attr "amdfam10_decode" "direct")])
1717 (define_insn "*cmpfp_iu_sse"
1718 [(set (reg:CCFPU FLAGS_REG)
1719 (compare:CCFPU (match_operand 0 "register_operand" "x")
1720 (match_operand 1 "nonimmediate_operand" "xm")))]
1722 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1723 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1724 "* return output_fp_compare (insn, operands, 1, 1);"
1725 [(set_attr "type" "ssecomi")
1726 (set_attr "prefix" "maybe_vex")
1728 (if_then_else (match_operand:SF 1 "" "")
1730 (const_string "DF")))
1731 (set_attr "prefix_rep" "0")
1732 (set (attr "prefix_data16")
1733 (if_then_else (eq_attr "mode" "DF")
1735 (const_string "0")))
1736 (set_attr "athlon_decode" "vector")
1737 (set_attr "amdfam10_decode" "direct")])
1739 (define_insn "*cmpfp_iu_387"
1740 [(set (reg:CCFPU FLAGS_REG)
1741 (compare:CCFPU (match_operand 0 "register_operand" "f")
1742 (match_operand 1 "register_operand" "f")))]
1743 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1745 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1746 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1747 "* return output_fp_compare (insn, operands, 1, 1);"
1748 [(set_attr "type" "fcmp")
1750 (cond [(match_operand:SF 1 "" "")
1752 (match_operand:DF 1 "" "")
1755 (const_string "XF")))
1756 (set_attr "athlon_decode" "vector")
1757 (set_attr "amdfam10_decode" "direct")])
1759 ;; Move instructions.
1761 ;; General case of fullword move.
1763 (define_expand "movsi"
1764 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1765 (match_operand:SI 1 "general_operand" ""))]
1767 "ix86_expand_move (SImode, operands); DONE;")
1769 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1772 ;; %%% We don't use a post-inc memory reference because x86 is not a
1773 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1774 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1775 ;; targets without our curiosities, and it is just as easy to represent
1776 ;; this differently.
1778 (define_insn "*pushsi2"
1779 [(set (match_operand:SI 0 "push_operand" "=<")
1780 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1783 [(set_attr "type" "push")
1784 (set_attr "mode" "SI")])
1786 ;; For 64BIT abi we always round up to 8 bytes.
1787 (define_insn "*pushsi2_rex64"
1788 [(set (match_operand:SI 0 "push_operand" "=X")
1789 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1792 [(set_attr "type" "push")
1793 (set_attr "mode" "SI")])
1795 (define_insn "*pushsi2_prologue"
1796 [(set (match_operand:SI 0 "push_operand" "=<")
1797 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1798 (clobber (mem:BLK (scratch)))]
1801 [(set_attr "type" "push")
1802 (set_attr "mode" "SI")])
1804 (define_insn "*popsi1_epilogue"
1805 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1806 (mem:SI (reg:SI SP_REG)))
1807 (set (reg:SI SP_REG)
1808 (plus:SI (reg:SI SP_REG) (const_int 4)))
1809 (clobber (mem:BLK (scratch)))]
1812 [(set_attr "type" "pop")
1813 (set_attr "mode" "SI")])
1815 (define_insn "popsi1"
1816 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1817 (mem:SI (reg:SI SP_REG)))
1818 (set (reg:SI SP_REG)
1819 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1822 [(set_attr "type" "pop")
1823 (set_attr "mode" "SI")])
1825 (define_insn "*movsi_xor"
1826 [(set (match_operand:SI 0 "register_operand" "=r")
1827 (match_operand:SI 1 "const0_operand" ""))
1828 (clobber (reg:CC FLAGS_REG))]
1831 [(set_attr "type" "alu1")
1832 (set_attr "mode" "SI")
1833 (set_attr "length_immediate" "0")])
1835 (define_insn "*movsi_or"
1836 [(set (match_operand:SI 0 "register_operand" "=r")
1837 (match_operand:SI 1 "immediate_operand" "i"))
1838 (clobber (reg:CC FLAGS_REG))]
1840 && operands[1] == constm1_rtx"
1842 operands[1] = constm1_rtx;
1843 return "or{l}\t{%1, %0|%0, %1}";
1845 [(set_attr "type" "alu1")
1846 (set_attr "mode" "SI")
1847 (set_attr "length_immediate" "1")])
1849 (define_insn "*movsi_1"
1850 [(set (match_operand:SI 0 "nonimmediate_operand"
1851 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1852 (match_operand:SI 1 "general_operand"
1853 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1854 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1856 switch (get_attr_type (insn))
1859 if (get_attr_mode (insn) == MODE_TI)
1860 return "%vpxor\t%0, %d0";
1861 return "%vxorps\t%0, %d0";
1864 switch (get_attr_mode (insn))
1867 return "%vmovdqa\t{%1, %0|%0, %1}";
1869 return "%vmovaps\t{%1, %0|%0, %1}";
1871 return "%vmovd\t{%1, %0|%0, %1}";
1873 return "%vmovss\t{%1, %0|%0, %1}";
1879 return "pxor\t%0, %0";
1882 if (get_attr_mode (insn) == MODE_DI)
1883 return "movq\t{%1, %0|%0, %1}";
1884 return "movd\t{%1, %0|%0, %1}";
1887 return "lea{l}\t{%1, %0|%0, %1}";
1890 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1891 return "mov{l}\t{%1, %0|%0, %1}";
1895 (cond [(eq_attr "alternative" "2")
1896 (const_string "mmx")
1897 (eq_attr "alternative" "3,4,5")
1898 (const_string "mmxmov")
1899 (eq_attr "alternative" "6")
1900 (const_string "sselog1")
1901 (eq_attr "alternative" "7,8,9,10,11")
1902 (const_string "ssemov")
1903 (match_operand:DI 1 "pic_32bit_operand" "")
1904 (const_string "lea")
1906 (const_string "imov")))
1907 (set (attr "prefix")
1908 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1909 (const_string "orig")
1910 (const_string "maybe_vex")))
1911 (set (attr "prefix_data16")
1912 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1914 (const_string "*")))
1916 (cond [(eq_attr "alternative" "2,3")
1918 (eq_attr "alternative" "6,7")
1920 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1921 (const_string "V4SF")
1922 (const_string "TI"))
1923 (and (eq_attr "alternative" "8,9,10,11")
1924 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1927 (const_string "SI")))])
1929 ;; Stores and loads of ax to arbitrary constant address.
1930 ;; We fake an second form of instruction to force reload to load address
1931 ;; into register when rax is not available
1932 (define_insn "*movabssi_1_rex64"
1933 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1934 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1935 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1937 movabs{l}\t{%1, %P0|%P0, %1}
1938 mov{l}\t{%1, %a0|%a0, %1}"
1939 [(set_attr "type" "imov")
1940 (set_attr "modrm" "0,*")
1941 (set_attr "length_address" "8,0")
1942 (set_attr "length_immediate" "0,*")
1943 (set_attr "memory" "store")
1944 (set_attr "mode" "SI")])
1946 (define_insn "*movabssi_2_rex64"
1947 [(set (match_operand:SI 0 "register_operand" "=a,r")
1948 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1949 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1951 movabs{l}\t{%P1, %0|%0, %P1}
1952 mov{l}\t{%a1, %0|%0, %a1}"
1953 [(set_attr "type" "imov")
1954 (set_attr "modrm" "0,*")
1955 (set_attr "length_address" "8,0")
1956 (set_attr "length_immediate" "0")
1957 (set_attr "memory" "load")
1958 (set_attr "mode" "SI")])
1960 (define_insn "*swapsi"
1961 [(set (match_operand:SI 0 "register_operand" "+r")
1962 (match_operand:SI 1 "register_operand" "+r"))
1967 [(set_attr "type" "imov")
1968 (set_attr "mode" "SI")
1969 (set_attr "pent_pair" "np")
1970 (set_attr "athlon_decode" "vector")
1971 (set_attr "amdfam10_decode" "double")])
1973 (define_expand "movhi"
1974 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1975 (match_operand:HI 1 "general_operand" ""))]
1977 "ix86_expand_move (HImode, operands); DONE;")
1979 (define_insn "*pushhi2"
1980 [(set (match_operand:HI 0 "push_operand" "=X")
1981 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1984 [(set_attr "type" "push")
1985 (set_attr "mode" "SI")])
1987 ;; For 64BIT abi we always round up to 8 bytes.
1988 (define_insn "*pushhi2_rex64"
1989 [(set (match_operand:HI 0 "push_operand" "=X")
1990 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1993 [(set_attr "type" "push")
1994 (set_attr "mode" "DI")])
1996 (define_insn "*movhi_1"
1997 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1998 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1999 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2001 switch (get_attr_type (insn))
2004 /* movzwl is faster than movw on p2 due to partial word stalls,
2005 though not as fast as an aligned movl. */
2006 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2008 if (get_attr_mode (insn) == MODE_SI)
2009 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2011 return "mov{w}\t{%1, %0|%0, %1}";
2015 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2016 (const_string "imov")
2017 (and (eq_attr "alternative" "0")
2018 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2020 (eq (symbol_ref "TARGET_HIMODE_MATH")
2022 (const_string "imov")
2023 (and (eq_attr "alternative" "1,2")
2024 (match_operand:HI 1 "aligned_operand" ""))
2025 (const_string "imov")
2026 (and (ne (symbol_ref "TARGET_MOVX")
2028 (eq_attr "alternative" "0,2"))
2029 (const_string "imovx")
2031 (const_string "imov")))
2033 (cond [(eq_attr "type" "imovx")
2035 (and (eq_attr "alternative" "1,2")
2036 (match_operand:HI 1 "aligned_operand" ""))
2038 (and (eq_attr "alternative" "0")
2039 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2041 (eq (symbol_ref "TARGET_HIMODE_MATH")
2045 (const_string "HI")))])
2047 ;; Stores and loads of ax to arbitrary constant address.
2048 ;; We fake an second form of instruction to force reload to load address
2049 ;; into register when rax is not available
2050 (define_insn "*movabshi_1_rex64"
2051 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2052 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
2053 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2055 movabs{w}\t{%1, %P0|%P0, %1}
2056 mov{w}\t{%1, %a0|%a0, %1}"
2057 [(set_attr "type" "imov")
2058 (set_attr "modrm" "0,*")
2059 (set_attr "length_address" "8,0")
2060 (set_attr "length_immediate" "0,*")
2061 (set_attr "memory" "store")
2062 (set_attr "mode" "HI")])
2064 (define_insn "*movabshi_2_rex64"
2065 [(set (match_operand:HI 0 "register_operand" "=a,r")
2066 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2067 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2069 movabs{w}\t{%P1, %0|%0, %P1}
2070 mov{w}\t{%a1, %0|%0, %a1}"
2071 [(set_attr "type" "imov")
2072 (set_attr "modrm" "0,*")
2073 (set_attr "length_address" "8,0")
2074 (set_attr "length_immediate" "0")
2075 (set_attr "memory" "load")
2076 (set_attr "mode" "HI")])
2078 (define_insn "*swaphi_1"
2079 [(set (match_operand:HI 0 "register_operand" "+r")
2080 (match_operand:HI 1 "register_operand" "+r"))
2083 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2085 [(set_attr "type" "imov")
2086 (set_attr "mode" "SI")
2087 (set_attr "pent_pair" "np")
2088 (set_attr "athlon_decode" "vector")
2089 (set_attr "amdfam10_decode" "double")])
2091 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2092 (define_insn "*swaphi_2"
2093 [(set (match_operand:HI 0 "register_operand" "+r")
2094 (match_operand:HI 1 "register_operand" "+r"))
2097 "TARGET_PARTIAL_REG_STALL"
2099 [(set_attr "type" "imov")
2100 (set_attr "mode" "HI")
2101 (set_attr "pent_pair" "np")
2102 (set_attr "athlon_decode" "vector")])
2104 (define_expand "movstricthi"
2105 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2106 (match_operand:HI 1 "general_operand" ""))]
2109 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2111 /* Don't generate memory->memory moves, go through a register */
2112 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2113 operands[1] = force_reg (HImode, operands[1]);
2116 (define_insn "*movstricthi_1"
2117 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
2118 (match_operand:HI 1 "general_operand" "rn,m"))]
2119 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2120 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2121 "mov{w}\t{%1, %0|%0, %1}"
2122 [(set_attr "type" "imov")
2123 (set_attr "mode" "HI")])
2125 (define_insn "*movstricthi_xor"
2126 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
2127 (match_operand:HI 1 "const0_operand" ""))
2128 (clobber (reg:CC FLAGS_REG))]
2131 [(set_attr "type" "alu1")
2132 (set_attr "mode" "HI")
2133 (set_attr "length_immediate" "0")])
2135 (define_expand "movqi"
2136 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2137 (match_operand:QI 1 "general_operand" ""))]
2139 "ix86_expand_move (QImode, operands); DONE;")
2141 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2142 ;; "push a byte". But actually we use pushl, which has the effect
2143 ;; of rounding the amount pushed up to a word.
2145 (define_insn "*pushqi2"
2146 [(set (match_operand:QI 0 "push_operand" "=X")
2147 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
2150 [(set_attr "type" "push")
2151 (set_attr "mode" "SI")])
2153 ;; For 64BIT abi we always round up to 8 bytes.
2154 (define_insn "*pushqi2_rex64"
2155 [(set (match_operand:QI 0 "push_operand" "=X")
2156 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
2159 [(set_attr "type" "push")
2160 (set_attr "mode" "DI")])
2162 ;; Situation is quite tricky about when to choose full sized (SImode) move
2163 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2164 ;; partial register dependency machines (such as AMD Athlon), where QImode
2165 ;; moves issue extra dependency and for partial register stalls machines
2166 ;; that don't use QImode patterns (and QImode move cause stall on the next
2169 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2170 ;; register stall machines with, where we use QImode instructions, since
2171 ;; partial register stall can be caused there. Then we use movzx.
2172 (define_insn "*movqi_1"
2173 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2174 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2175 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2177 switch (get_attr_type (insn))
2180 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2181 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2183 if (get_attr_mode (insn) == MODE_SI)
2184 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2186 return "mov{b}\t{%1, %0|%0, %1}";
2190 (cond [(and (eq_attr "alternative" "5")
2191 (not (match_operand:QI 1 "aligned_operand" "")))
2192 (const_string "imovx")
2193 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2194 (const_string "imov")
2195 (and (eq_attr "alternative" "3")
2196 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2198 (eq (symbol_ref "TARGET_QIMODE_MATH")
2200 (const_string "imov")
2201 (eq_attr "alternative" "3,5")
2202 (const_string "imovx")
2203 (and (ne (symbol_ref "TARGET_MOVX")
2205 (eq_attr "alternative" "2"))
2206 (const_string "imovx")
2208 (const_string "imov")))
2210 (cond [(eq_attr "alternative" "3,4,5")
2212 (eq_attr "alternative" "6")
2214 (eq_attr "type" "imovx")
2216 (and (eq_attr "type" "imov")
2217 (and (eq_attr "alternative" "0,1")
2218 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2220 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2222 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2225 ;; Avoid partial register stalls when not using QImode arithmetic
2226 (and (eq_attr "type" "imov")
2227 (and (eq_attr "alternative" "0,1")
2228 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2230 (eq (symbol_ref "TARGET_QIMODE_MATH")
2234 (const_string "QI")))])
2236 (define_insn "*swapqi_1"
2237 [(set (match_operand:QI 0 "register_operand" "+r")
2238 (match_operand:QI 1 "register_operand" "+r"))
2241 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2243 [(set_attr "type" "imov")
2244 (set_attr "mode" "SI")
2245 (set_attr "pent_pair" "np")
2246 (set_attr "athlon_decode" "vector")
2247 (set_attr "amdfam10_decode" "vector")])
2249 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2250 (define_insn "*swapqi_2"
2251 [(set (match_operand:QI 0 "register_operand" "+q")
2252 (match_operand:QI 1 "register_operand" "+q"))
2255 "TARGET_PARTIAL_REG_STALL"
2257 [(set_attr "type" "imov")
2258 (set_attr "mode" "QI")
2259 (set_attr "pent_pair" "np")
2260 (set_attr "athlon_decode" "vector")])
2262 (define_expand "movstrictqi"
2263 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2264 (match_operand:QI 1 "general_operand" ""))]
2267 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2269 /* Don't generate memory->memory moves, go through a register. */
2270 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2271 operands[1] = force_reg (QImode, operands[1]);
2274 (define_insn "*movstrictqi_1"
2275 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2276 (match_operand:QI 1 "general_operand" "*qn,m"))]
2277 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2278 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2279 "mov{b}\t{%1, %0|%0, %1}"
2280 [(set_attr "type" "imov")
2281 (set_attr "mode" "QI")])
2283 (define_insn "*movstrictqi_xor"
2284 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2285 (match_operand:QI 1 "const0_operand" ""))
2286 (clobber (reg:CC FLAGS_REG))]
2289 [(set_attr "type" "alu1")
2290 (set_attr "mode" "QI")
2291 (set_attr "length_immediate" "0")])
2293 (define_insn "*movsi_extv_1"
2294 [(set (match_operand:SI 0 "register_operand" "=R")
2295 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2299 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2300 [(set_attr "type" "imovx")
2301 (set_attr "mode" "SI")])
2303 (define_insn "*movhi_extv_1"
2304 [(set (match_operand:HI 0 "register_operand" "=R")
2305 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2309 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2310 [(set_attr "type" "imovx")
2311 (set_attr "mode" "SI")])
2313 (define_insn "*movqi_extv_1"
2314 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2315 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2320 switch (get_attr_type (insn))
2323 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2325 return "mov{b}\t{%h1, %0|%0, %h1}";
2329 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2330 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2331 (ne (symbol_ref "TARGET_MOVX")
2333 (const_string "imovx")
2334 (const_string "imov")))
2336 (if_then_else (eq_attr "type" "imovx")
2338 (const_string "QI")))])
2340 (define_insn "*movqi_extv_1_rex64"
2341 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2342 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2347 switch (get_attr_type (insn))
2350 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2352 return "mov{b}\t{%h1, %0|%0, %h1}";
2356 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2357 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2358 (ne (symbol_ref "TARGET_MOVX")
2360 (const_string "imovx")
2361 (const_string "imov")))
2363 (if_then_else (eq_attr "type" "imovx")
2365 (const_string "QI")))])
2367 ;; Stores and loads of ax to arbitrary constant address.
2368 ;; We fake an second form of instruction to force reload to load address
2369 ;; into register when rax is not available
2370 (define_insn "*movabsqi_1_rex64"
2371 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2372 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2373 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2375 movabs{b}\t{%1, %P0|%P0, %1}
2376 mov{b}\t{%1, %a0|%a0, %1}"
2377 [(set_attr "type" "imov")
2378 (set_attr "modrm" "0,*")
2379 (set_attr "length_address" "8,0")
2380 (set_attr "length_immediate" "0,*")
2381 (set_attr "memory" "store")
2382 (set_attr "mode" "QI")])
2384 (define_insn "*movabsqi_2_rex64"
2385 [(set (match_operand:QI 0 "register_operand" "=a,r")
2386 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2387 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2389 movabs{b}\t{%P1, %0|%0, %P1}
2390 mov{b}\t{%a1, %0|%0, %a1}"
2391 [(set_attr "type" "imov")
2392 (set_attr "modrm" "0,*")
2393 (set_attr "length_address" "8,0")
2394 (set_attr "length_immediate" "0")
2395 (set_attr "memory" "load")
2396 (set_attr "mode" "QI")])
2398 (define_insn "*movdi_extzv_1"
2399 [(set (match_operand:DI 0 "register_operand" "=R")
2400 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2404 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2405 [(set_attr "type" "imovx")
2406 (set_attr "mode" "SI")])
2408 (define_insn "*movsi_extzv_1"
2409 [(set (match_operand:SI 0 "register_operand" "=R")
2410 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2414 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2415 [(set_attr "type" "imovx")
2416 (set_attr "mode" "SI")])
2418 (define_insn "*movqi_extzv_2"
2419 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2420 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2425 switch (get_attr_type (insn))
2428 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2430 return "mov{b}\t{%h1, %0|%0, %h1}";
2434 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2435 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2436 (ne (symbol_ref "TARGET_MOVX")
2438 (const_string "imovx")
2439 (const_string "imov")))
2441 (if_then_else (eq_attr "type" "imovx")
2443 (const_string "QI")))])
2445 (define_insn "*movqi_extzv_2_rex64"
2446 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2447 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2452 switch (get_attr_type (insn))
2455 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2457 return "mov{b}\t{%h1, %0|%0, %h1}";
2461 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2462 (ne (symbol_ref "TARGET_MOVX")
2464 (const_string "imovx")
2465 (const_string "imov")))
2467 (if_then_else (eq_attr "type" "imovx")
2469 (const_string "QI")))])
2471 (define_insn "movsi_insv_1"
2472 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2475 (match_operand:SI 1 "general_operand" "Qmn"))]
2477 "mov{b}\t{%b1, %h0|%h0, %b1}"
2478 [(set_attr "type" "imov")
2479 (set_attr "mode" "QI")])
2481 (define_insn "*movsi_insv_1_rex64"
2482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2485 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2487 "mov{b}\t{%b1, %h0|%h0, %b1}"
2488 [(set_attr "type" "imov")
2489 (set_attr "mode" "QI")])
2491 (define_insn "movdi_insv_1_rex64"
2492 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2495 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2497 "mov{b}\t{%b1, %h0|%h0, %b1}"
2498 [(set_attr "type" "imov")
2499 (set_attr "mode" "QI")])
2501 (define_insn "*movqi_insv_2"
2502 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2505 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2508 "mov{b}\t{%h1, %h0|%h0, %h1}"
2509 [(set_attr "type" "imov")
2510 (set_attr "mode" "QI")])
2512 (define_expand "movdi"
2513 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2514 (match_operand:DI 1 "general_operand" ""))]
2516 "ix86_expand_move (DImode, operands); DONE;")
2518 (define_insn "*pushdi"
2519 [(set (match_operand:DI 0 "push_operand" "=<")
2520 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2524 (define_insn "*pushdi2_rex64"
2525 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2526 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2531 [(set_attr "type" "push,multi")
2532 (set_attr "mode" "DI")])
2534 ;; Convert impossible pushes of immediate to existing instructions.
2535 ;; First try to get scratch register and go through it. In case this
2536 ;; fails, push sign extended lower part first and then overwrite
2537 ;; upper part by 32bit move.
2539 [(match_scratch:DI 2 "r")
2540 (set (match_operand:DI 0 "push_operand" "")
2541 (match_operand:DI 1 "immediate_operand" ""))]
2542 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2543 && !x86_64_immediate_operand (operands[1], DImode)"
2544 [(set (match_dup 2) (match_dup 1))
2545 (set (match_dup 0) (match_dup 2))]
2548 ;; We need to define this as both peepholer and splitter for case
2549 ;; peephole2 pass is not run.
2550 ;; "&& 1" is needed to keep it from matching the previous pattern.
2552 [(set (match_operand:DI 0 "push_operand" "")
2553 (match_operand:DI 1 "immediate_operand" ""))]
2554 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2555 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2556 [(set (match_dup 0) (match_dup 1))
2557 (set (match_dup 2) (match_dup 3))]
2558 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2559 operands[1] = gen_lowpart (DImode, operands[2]);
2560 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2565 [(set (match_operand:DI 0 "push_operand" "")
2566 (match_operand:DI 1 "immediate_operand" ""))]
2567 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2568 ? epilogue_completed : reload_completed)
2569 && !symbolic_operand (operands[1], DImode)
2570 && !x86_64_immediate_operand (operands[1], DImode)"
2571 [(set (match_dup 0) (match_dup 1))
2572 (set (match_dup 2) (match_dup 3))]
2573 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2574 operands[1] = gen_lowpart (DImode, operands[2]);
2575 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2579 (define_insn "*pushdi2_prologue_rex64"
2580 [(set (match_operand:DI 0 "push_operand" "=<")
2581 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2582 (clobber (mem:BLK (scratch)))]
2585 [(set_attr "type" "push")
2586 (set_attr "mode" "DI")])
2588 (define_insn "*popdi1_epilogue_rex64"
2589 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2590 (mem:DI (reg:DI SP_REG)))
2591 (set (reg:DI SP_REG)
2592 (plus:DI (reg:DI SP_REG) (const_int 8)))
2593 (clobber (mem:BLK (scratch)))]
2596 [(set_attr "type" "pop")
2597 (set_attr "mode" "DI")])
2599 (define_insn "popdi1"
2600 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2601 (mem:DI (reg:DI SP_REG)))
2602 (set (reg:DI SP_REG)
2603 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2606 [(set_attr "type" "pop")
2607 (set_attr "mode" "DI")])
2609 (define_insn "*movdi_xor_rex64"
2610 [(set (match_operand:DI 0 "register_operand" "=r")
2611 (match_operand:DI 1 "const0_operand" ""))
2612 (clobber (reg:CC FLAGS_REG))]
2614 && reload_completed"
2616 [(set_attr "type" "alu1")
2617 (set_attr "mode" "SI")
2618 (set_attr "length_immediate" "0")])
2620 (define_insn "*movdi_or_rex64"
2621 [(set (match_operand:DI 0 "register_operand" "=r")
2622 (match_operand:DI 1 "const_int_operand" "i"))
2623 (clobber (reg:CC FLAGS_REG))]
2626 && operands[1] == constm1_rtx"
2628 operands[1] = constm1_rtx;
2629 return "or{q}\t{%1, %0|%0, %1}";
2631 [(set_attr "type" "alu1")
2632 (set_attr "mode" "DI")
2633 (set_attr "length_immediate" "1")])
2635 (define_insn "*movdi_2"
2636 [(set (match_operand:DI 0 "nonimmediate_operand"
2637 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2638 (match_operand:DI 1 "general_operand"
2639 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2640 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2645 movq\t{%1, %0|%0, %1}
2646 movq\t{%1, %0|%0, %1}
2648 %vmovq\t{%1, %0|%0, %1}
2649 %vmovdqa\t{%1, %0|%0, %1}
2650 %vmovq\t{%1, %0|%0, %1}
2652 movlps\t{%1, %0|%0, %1}
2653 movaps\t{%1, %0|%0, %1}
2654 movlps\t{%1, %0|%0, %1}"
2655 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2656 (set (attr "prefix")
2657 (if_then_else (eq_attr "alternative" "5,6,7,8")
2658 (const_string "vex")
2659 (const_string "orig")))
2660 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2663 [(set (match_operand:DI 0 "push_operand" "")
2664 (match_operand:DI 1 "general_operand" ""))]
2665 "!TARGET_64BIT && reload_completed
2666 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2668 "ix86_split_long_move (operands); DONE;")
2670 ;; %%% This multiword shite has got to go.
2672 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2673 (match_operand:DI 1 "general_operand" ""))]
2674 "!TARGET_64BIT && reload_completed
2675 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2676 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2678 "ix86_split_long_move (operands); DONE;")
2680 (define_insn "*movdi_1_rex64"
2681 [(set (match_operand:DI 0 "nonimmediate_operand"
2682 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2683 (match_operand:DI 1 "general_operand"
2684 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2685 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2687 switch (get_attr_type (insn))
2690 if (SSE_REG_P (operands[0]))
2691 return "movq2dq\t{%1, %0|%0, %1}";
2693 return "movdq2q\t{%1, %0|%0, %1}";
2698 if (get_attr_mode (insn) == MODE_TI)
2699 return "vmovdqa\t{%1, %0|%0, %1}";
2701 return "vmovq\t{%1, %0|%0, %1}";
2704 if (get_attr_mode (insn) == MODE_TI)
2705 return "movdqa\t{%1, %0|%0, %1}";
2709 /* Moves from and into integer register is done using movd
2710 opcode with REX prefix. */
2711 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2712 return "movd\t{%1, %0|%0, %1}";
2713 return "movq\t{%1, %0|%0, %1}";
2716 return "%vpxor\t%0, %d0";
2719 return "pxor\t%0, %0";
2725 return "lea{q}\t{%a1, %0|%0, %a1}";
2728 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2729 if (get_attr_mode (insn) == MODE_SI)
2730 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2731 else if (which_alternative == 2)
2732 return "movabs{q}\t{%1, %0|%0, %1}";
2734 return "mov{q}\t{%1, %0|%0, %1}";
2738 (cond [(eq_attr "alternative" "5")
2739 (const_string "mmx")
2740 (eq_attr "alternative" "6,7,8,9,10")
2741 (const_string "mmxmov")
2742 (eq_attr "alternative" "11")
2743 (const_string "sselog1")
2744 (eq_attr "alternative" "12,13,14,15,16")
2745 (const_string "ssemov")
2746 (eq_attr "alternative" "17,18")
2747 (const_string "ssecvt")
2748 (eq_attr "alternative" "4")
2749 (const_string "multi")
2750 (match_operand:DI 1 "pic_32bit_operand" "")
2751 (const_string "lea")
2753 (const_string "imov")))
2756 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2758 (const_string "*")))
2759 (set (attr "length_immediate")
2761 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2763 (const_string "*")))
2764 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2765 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2766 (set (attr "prefix")
2767 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2768 (const_string "maybe_vex")
2769 (const_string "orig")))
2770 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2772 ;; Stores and loads of ax to arbitrary constant address.
2773 ;; We fake an second form of instruction to force reload to load address
2774 ;; into register when rax is not available
2775 (define_insn "*movabsdi_1_rex64"
2776 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2777 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2778 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2780 movabs{q}\t{%1, %P0|%P0, %1}
2781 mov{q}\t{%1, %a0|%a0, %1}"
2782 [(set_attr "type" "imov")
2783 (set_attr "modrm" "0,*")
2784 (set_attr "length_address" "8,0")
2785 (set_attr "length_immediate" "0,*")
2786 (set_attr "memory" "store")
2787 (set_attr "mode" "DI")])
2789 (define_insn "*movabsdi_2_rex64"
2790 [(set (match_operand:DI 0 "register_operand" "=a,r")
2791 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2792 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2794 movabs{q}\t{%P1, %0|%0, %P1}
2795 mov{q}\t{%a1, %0|%0, %a1}"
2796 [(set_attr "type" "imov")
2797 (set_attr "modrm" "0,*")
2798 (set_attr "length_address" "8,0")
2799 (set_attr "length_immediate" "0")
2800 (set_attr "memory" "load")
2801 (set_attr "mode" "DI")])
2803 ;; Convert impossible stores of immediate to existing instructions.
2804 ;; First try to get scratch register and go through it. In case this
2805 ;; fails, move by 32bit parts.
2807 [(match_scratch:DI 2 "r")
2808 (set (match_operand:DI 0 "memory_operand" "")
2809 (match_operand:DI 1 "immediate_operand" ""))]
2810 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2811 && !x86_64_immediate_operand (operands[1], DImode)"
2812 [(set (match_dup 2) (match_dup 1))
2813 (set (match_dup 0) (match_dup 2))]
2816 ;; We need to define this as both peepholer and splitter for case
2817 ;; peephole2 pass is not run.
2818 ;; "&& 1" is needed to keep it from matching the previous pattern.
2820 [(set (match_operand:DI 0 "memory_operand" "")
2821 (match_operand:DI 1 "immediate_operand" ""))]
2822 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2823 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2824 [(set (match_dup 2) (match_dup 3))
2825 (set (match_dup 4) (match_dup 5))]
2826 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2829 [(set (match_operand:DI 0 "memory_operand" "")
2830 (match_operand:DI 1 "immediate_operand" ""))]
2831 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2832 ? epilogue_completed : reload_completed)
2833 && !symbolic_operand (operands[1], DImode)
2834 && !x86_64_immediate_operand (operands[1], DImode)"
2835 [(set (match_dup 2) (match_dup 3))
2836 (set (match_dup 4) (match_dup 5))]
2837 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2839 (define_insn "*swapdi_rex64"
2840 [(set (match_operand:DI 0 "register_operand" "+r")
2841 (match_operand:DI 1 "register_operand" "+r"))
2846 [(set_attr "type" "imov")
2847 (set_attr "mode" "DI")
2848 (set_attr "pent_pair" "np")
2849 (set_attr "athlon_decode" "vector")
2850 (set_attr "amdfam10_decode" "double")])
2852 (define_expand "movoi"
2853 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2854 (match_operand:OI 1 "general_operand" ""))]
2856 "ix86_expand_move (OImode, operands); DONE;")
2858 (define_insn "*movoi_internal"
2859 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2860 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2862 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2864 switch (which_alternative)
2867 return "vxorps\t%0, %0, %0";
2870 if (misaligned_operand (operands[0], OImode)
2871 || misaligned_operand (operands[1], OImode))
2872 return "vmovdqu\t{%1, %0|%0, %1}";
2874 return "vmovdqa\t{%1, %0|%0, %1}";
2879 [(set_attr "type" "sselog1,ssemov,ssemov")
2880 (set_attr "prefix" "vex")
2881 (set_attr "mode" "OI")])
2883 (define_expand "movti"
2884 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2885 (match_operand:TI 1 "nonimmediate_operand" ""))]
2886 "TARGET_SSE || TARGET_64BIT"
2889 ix86_expand_move (TImode, operands);
2890 else if (push_operand (operands[0], TImode))
2891 ix86_expand_push (TImode, operands[1]);
2893 ix86_expand_vector_move (TImode, operands);
2897 (define_insn "*movti_internal"
2898 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2899 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2900 "TARGET_SSE && !TARGET_64BIT
2901 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2903 switch (which_alternative)
2906 if (get_attr_mode (insn) == MODE_V4SF)
2907 return "%vxorps\t%0, %d0";
2909 return "%vpxor\t%0, %d0";
2912 /* TDmode values are passed as TImode on the stack. Moving them
2913 to stack may result in unaligned memory access. */
2914 if (misaligned_operand (operands[0], TImode)
2915 || misaligned_operand (operands[1], TImode))
2917 if (get_attr_mode (insn) == MODE_V4SF)
2918 return "%vmovups\t{%1, %0|%0, %1}";
2920 return "%vmovdqu\t{%1, %0|%0, %1}";
2924 if (get_attr_mode (insn) == MODE_V4SF)
2925 return "%vmovaps\t{%1, %0|%0, %1}";
2927 return "%vmovdqa\t{%1, %0|%0, %1}";
2933 [(set_attr "type" "sselog1,ssemov,ssemov")
2934 (set_attr "prefix" "maybe_vex")
2936 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2937 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2938 (const_string "V4SF")
2939 (and (eq_attr "alternative" "2")
2940 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2942 (const_string "V4SF")]
2943 (const_string "TI")))])
2945 (define_insn "*movti_rex64"
2946 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2947 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2949 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2951 switch (which_alternative)
2957 if (get_attr_mode (insn) == MODE_V4SF)
2958 return "%vxorps\t%0, %d0";
2960 return "%vpxor\t%0, %d0";
2963 /* TDmode values are passed as TImode on the stack. Moving them
2964 to stack may result in unaligned memory access. */
2965 if (misaligned_operand (operands[0], TImode)
2966 || misaligned_operand (operands[1], TImode))
2968 if (get_attr_mode (insn) == MODE_V4SF)
2969 return "%vmovups\t{%1, %0|%0, %1}";
2971 return "%vmovdqu\t{%1, %0|%0, %1}";
2975 if (get_attr_mode (insn) == MODE_V4SF)
2976 return "%vmovaps\t{%1, %0|%0, %1}";
2978 return "%vmovdqa\t{%1, %0|%0, %1}";
2984 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2985 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2987 (cond [(eq_attr "alternative" "2,3")
2989 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2991 (const_string "V4SF")
2992 (const_string "TI"))
2993 (eq_attr "alternative" "4")
2995 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2997 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2999 (const_string "V4SF")
3000 (const_string "TI"))]
3001 (const_string "DI")))])
3004 [(set (match_operand:TI 0 "nonimmediate_operand" "")
3005 (match_operand:TI 1 "general_operand" ""))]
3006 "reload_completed && !SSE_REG_P (operands[0])
3007 && !SSE_REG_P (operands[1])"
3009 "ix86_split_long_move (operands); DONE;")
3011 ;; This expands to what emit_move_complex would generate if we didn't
3012 ;; have a movti pattern. Having this avoids problems with reload on
3013 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
3014 ;; to have around all the time.
3015 (define_expand "movcdi"
3016 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
3017 (match_operand:CDI 1 "general_operand" ""))]
3020 if (push_operand (operands[0], CDImode))
3021 emit_move_complex_push (CDImode, operands[0], operands[1]);
3023 emit_move_complex_parts (operands[0], operands[1]);
3027 (define_expand "movsf"
3028 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3029 (match_operand:SF 1 "general_operand" ""))]
3031 "ix86_expand_move (SFmode, operands); DONE;")
3033 (define_insn "*pushsf"
3034 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3035 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
3038 /* Anything else should be already split before reg-stack. */
3039 gcc_assert (which_alternative == 1);
3040 return "push{l}\t%1";
3042 [(set_attr "type" "multi,push,multi")
3043 (set_attr "unit" "i387,*,*")
3044 (set_attr "mode" "SF,SI,SF")])
3046 (define_insn "*pushsf_rex64"
3047 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3048 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3051 /* Anything else should be already split before reg-stack. */
3052 gcc_assert (which_alternative == 1);
3053 return "push{q}\t%q1";
3055 [(set_attr "type" "multi,push,multi")
3056 (set_attr "unit" "i387,*,*")
3057 (set_attr "mode" "SF,DI,SF")])
3060 [(set (match_operand:SF 0 "push_operand" "")
3061 (match_operand:SF 1 "memory_operand" ""))]
3063 && MEM_P (operands[1])
3064 && (operands[2] = find_constant_src (insn))"
3068 ;; %%% Kill this when call knows how to work this out.
3070 [(set (match_operand:SF 0 "push_operand" "")
3071 (match_operand:SF 1 "any_fp_register_operand" ""))]
3073 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
3074 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
3077 [(set (match_operand:SF 0 "push_operand" "")
3078 (match_operand:SF 1 "any_fp_register_operand" ""))]
3080 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3081 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
3083 (define_insn "*movsf_1"
3084 [(set (match_operand:SF 0 "nonimmediate_operand"
3085 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3086 (match_operand:SF 1 "general_operand"
3087 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3088 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3089 && (reload_in_progress || reload_completed
3090 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3091 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3092 && standard_80387_constant_p (operands[1]))
3093 || GET_CODE (operands[1]) != CONST_DOUBLE
3094 || memory_operand (operands[0], SFmode))"
3096 switch (which_alternative)
3100 return output_387_reg_move (insn, operands);
3103 return standard_80387_constant_opcode (operands[1]);
3107 return "mov{l}\t{%1, %0|%0, %1}";
3109 if (get_attr_mode (insn) == MODE_TI)
3110 return "%vpxor\t%0, %d0";
3112 return "%vxorps\t%0, %d0";
3114 if (get_attr_mode (insn) == MODE_V4SF)
3115 return "%vmovaps\t{%1, %0|%0, %1}";
3117 return "%vmovss\t{%1, %d0|%d0, %1}";
3120 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3121 : "vmovss\t{%1, %0|%0, %1}";
3123 return "movss\t{%1, %0|%0, %1}";
3125 return "%vmovss\t{%1, %0|%0, %1}";
3127 case 9: case 10: case 14: case 15:
3128 return "movd\t{%1, %0|%0, %1}";
3130 return "%vmovd\t{%1, %0|%0, %1}";
3133 return "movq\t{%1, %0|%0, %1}";
3139 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3140 (set (attr "prefix")
3141 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3142 (const_string "maybe_vex")
3143 (const_string "orig")))
3145 (cond [(eq_attr "alternative" "3,4,9,10")
3147 (eq_attr "alternative" "5")
3149 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3151 (ne (symbol_ref "TARGET_SSE2")
3153 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3156 (const_string "V4SF"))
3157 /* For architectures resolving dependencies on
3158 whole SSE registers use APS move to break dependency
3159 chains, otherwise use short move to avoid extra work.
3161 Do the same for architectures resolving dependencies on
3162 the parts. While in DF mode it is better to always handle
3163 just register parts, the SF mode is different due to lack
3164 of instructions to load just part of the register. It is
3165 better to maintain the whole registers in single format
3166 to avoid problems on using packed logical operations. */
3167 (eq_attr "alternative" "6")
3169 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3171 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3173 (const_string "V4SF")
3174 (const_string "SF"))
3175 (eq_attr "alternative" "11")
3176 (const_string "DI")]
3177 (const_string "SF")))])
3179 (define_insn "*swapsf"
3180 [(set (match_operand:SF 0 "fp_register_operand" "+f")
3181 (match_operand:SF 1 "fp_register_operand" "+f"))
3184 "reload_completed || TARGET_80387"
3186 if (STACK_TOP_P (operands[0]))
3191 [(set_attr "type" "fxch")
3192 (set_attr "mode" "SF")])
3194 (define_expand "movdf"
3195 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3196 (match_operand:DF 1 "general_operand" ""))]
3198 "ix86_expand_move (DFmode, operands); DONE;")
3200 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3201 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3202 ;; On the average, pushdf using integers can be still shorter. Allow this
3203 ;; pattern for optimize_size too.
3205 (define_insn "*pushdf_nointeger"
3206 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3207 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3208 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3210 /* This insn should be already split before reg-stack. */
3213 [(set_attr "type" "multi")
3214 (set_attr "unit" "i387,*,*,*")
3215 (set_attr "mode" "DF,SI,SI,DF")])
3217 (define_insn "*pushdf_integer"
3218 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3219 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3220 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3222 /* This insn should be already split before reg-stack. */
3225 [(set_attr "type" "multi")
3226 (set_attr "unit" "i387,*,*")
3227 (set_attr "mode" "DF,SI,DF")])
3229 ;; %%% Kill this when call knows how to work this out.
3231 [(set (match_operand:DF 0 "push_operand" "")
3232 (match_operand:DF 1 "any_fp_register_operand" ""))]
3234 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3235 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3239 [(set (match_operand:DF 0 "push_operand" "")
3240 (match_operand:DF 1 "general_operand" ""))]
3243 "ix86_split_long_move (operands); DONE;")
3245 ;; Moving is usually shorter when only FP registers are used. This separate
3246 ;; movdf pattern avoids the use of integer registers for FP operations
3247 ;; when optimizing for size.
3249 (define_insn "*movdf_nointeger"
3250 [(set (match_operand:DF 0 "nonimmediate_operand"
3251 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3252 (match_operand:DF 1 "general_operand"
3253 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3254 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3255 && ((optimize_function_for_size_p (cfun)
3256 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3257 && (reload_in_progress || reload_completed
3258 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3259 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3260 && optimize_function_for_size_p (cfun)
3261 && !memory_operand (operands[0], DFmode)
3262 && standard_80387_constant_p (operands[1]))
3263 || GET_CODE (operands[1]) != CONST_DOUBLE
3264 || ((optimize_function_for_size_p (cfun)
3265 || !TARGET_MEMORY_MISMATCH_STALL
3266 || reload_in_progress || reload_completed)
3267 && memory_operand (operands[0], DFmode)))"
3269 switch (which_alternative)
3273 return output_387_reg_move (insn, operands);
3276 return standard_80387_constant_opcode (operands[1]);
3282 switch (get_attr_mode (insn))
3285 return "%vxorps\t%0, %d0";
3287 return "%vxorpd\t%0, %d0";
3289 return "%vpxor\t%0, %d0";
3296 switch (get_attr_mode (insn))
3299 return "%vmovaps\t{%1, %0|%0, %1}";
3301 return "%vmovapd\t{%1, %0|%0, %1}";
3303 return "%vmovdqa\t{%1, %0|%0, %1}";
3305 return "%vmovq\t{%1, %0|%0, %1}";
3309 if (REG_P (operands[0]) && REG_P (operands[1]))
3310 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3312 return "vmovsd\t{%1, %0|%0, %1}";
3315 return "movsd\t{%1, %0|%0, %1}";
3319 if (REG_P (operands[0]))
3320 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3322 return "vmovlpd\t{%1, %0|%0, %1}";
3325 return "movlpd\t{%1, %0|%0, %1}";
3329 if (REG_P (operands[0]))
3330 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3332 return "vmovlps\t{%1, %0|%0, %1}";
3335 return "movlps\t{%1, %0|%0, %1}";