OSDN Git Service

2006-10-22 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
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
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
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 2, or (at your option)
13 ;; any later version.
14 ;;
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.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          30)
91    (UNSPEC_MASKMOV              31)
92    (UNSPEC_MOVMSK               32)
93    (UNSPEC_MOVNT                33)
94    (UNSPEC_MOVU                 34)
95    (UNSPEC_RCP                  35)
96    (UNSPEC_RSQRT                36)
97    (UNSPEC_SFENCE               37)
98    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                39)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDDQU                47)
108
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
113
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
131
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_TAN_ONE              82)
136    (UNSPEC_TAN_TAN              83)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
145
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
151
152    ; SSSE3
153    (UNSPEC_PSHUFB               120)
154    (UNSPEC_PSIGN                121)
155    (UNSPEC_PALIGNR              122)
156   ])
157
158 (define_constants
159   [(UNSPECV_BLOCKAGE            0)
160    (UNSPECV_STACK_PROBE         1)
161    (UNSPECV_EMMS                2)
162    (UNSPECV_LDMXCSR             3)
163    (UNSPECV_STMXCSR             4)
164    (UNSPECV_FEMMS               5)
165    (UNSPECV_CLFLUSH             6)
166    (UNSPECV_ALIGN               7)
167    (UNSPECV_MONITOR             8)
168    (UNSPECV_MWAIT               9)
169    (UNSPECV_CMPXCHG_1           10)
170    (UNSPECV_CMPXCHG_2           11)
171    (UNSPECV_XCHG                12)
172    (UNSPECV_LOCK                13)
173   ])
174
175 ;; Registers by name.
176 (define_constants
177   [(BP_REG                       6)
178    (SP_REG                       7)
179    (FLAGS_REG                   17)
180    (FPSR_REG                    18)
181    (DIRFLAG_REG                 19)
182   ])
183
184 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
185 ;; from i386.c.
186
187 ;; In C guard expressions, put expressions which may be compile-time
188 ;; constants first.  This allows for better optimization.  For
189 ;; example, write "TARGET_64BIT && reload_completed", not
190 ;; "reload_completed && TARGET_64BIT".
191
192 \f
193 ;; Processor type.  This attribute must exactly match the processor_type
194 ;; enumeration in i386.h.
195 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
196   (const (symbol_ref "ix86_tune")))
197
198 ;; A basic instruction type.  Refinements due to arguments to be
199 ;; provided in other attributes.
200 (define_attr "type"
201   "other,multi,
202    alu,alu1,negnot,imov,imovx,lea,
203    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
204    icmp,test,ibr,setcc,icmov,
205    push,pop,call,callv,leave,
206    str,cld,
207    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
208    sselog,sselog1,sseiadd,sseishft,sseimul,
209    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
210    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
211   (const_string "other"))
212
213 ;; Main data type used by the insn
214 (define_attr "mode"
215   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
216   (const_string "unknown"))
217
218 ;; The CPU unit operations uses.
219 (define_attr "unit" "integer,i387,sse,mmx,unknown"
220   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
221            (const_string "i387")
222          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
223                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
224            (const_string "sse")
225          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
226            (const_string "mmx")
227          (eq_attr "type" "other")
228            (const_string "unknown")]
229          (const_string "integer")))
230
231 ;; The (bounding maximum) length of an instruction immediate.
232 (define_attr "length_immediate" ""
233   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
234            (const_int 0)
235          (eq_attr "unit" "i387,sse,mmx")
236            (const_int 0)
237          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
238                           imul,icmp,push,pop")
239            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
240          (eq_attr "type" "imov,test")
241            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
242          (eq_attr "type" "call")
243            (if_then_else (match_operand 0 "constant_call_address_operand" "")
244              (const_int 4)
245              (const_int 0))
246          (eq_attr "type" "callv")
247            (if_then_else (match_operand 1 "constant_call_address_operand" "")
248              (const_int 4)
249              (const_int 0))
250          ;; We don't know the size before shorten_branches.  Expect
251          ;; the instruction to fit for better scheduling.
252          (eq_attr "type" "ibr")
253            (const_int 1)
254          ]
255          (symbol_ref "/* Update immediate_length and other attributes! */
256                       gcc_unreachable (),1")))
257
258 ;; The (bounding maximum) length of an instruction address.
259 (define_attr "length_address" ""
260   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
261            (const_int 0)
262          (and (eq_attr "type" "call")
263               (match_operand 0 "constant_call_address_operand" ""))
264              (const_int 0)
265          (and (eq_attr "type" "callv")
266               (match_operand 1 "constant_call_address_operand" ""))
267              (const_int 0)
268          ]
269          (symbol_ref "ix86_attr_length_address_default (insn)")))
270
271 ;; Set when length prefix is used.
272 (define_attr "prefix_data16" ""
273   (if_then_else (ior (eq_attr "mode" "HI")
274                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
275     (const_int 1)
276     (const_int 0)))
277
278 ;; Set when string REP prefix is used.
279 (define_attr "prefix_rep" "" 
280   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
281     (const_int 1)
282     (const_int 0)))
283
284 ;; Set when 0f opcode prefix is used.
285 (define_attr "prefix_0f" ""
286   (if_then_else 
287     (ior (eq_attr "type" "imovx,setcc,icmov")
288          (eq_attr "unit" "sse,mmx"))
289     (const_int 1)
290     (const_int 0)))
291
292 ;; Set when REX opcode prefix is used.
293 (define_attr "prefix_rex" ""
294   (cond [(and (eq_attr "mode" "DI")
295               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
296            (const_int 1)
297          (and (eq_attr "mode" "QI")
298               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
299                   (const_int 0)))
300            (const_int 1)
301          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
302              (const_int 0))
303            (const_int 1)
304         ]
305         (const_int 0)))
306
307 ;; Set when modrm byte is used.
308 (define_attr "modrm" ""
309   (cond [(eq_attr "type" "str,cld,leave")
310            (const_int 0)
311          (eq_attr "unit" "i387")
312            (const_int 0)
313          (and (eq_attr "type" "incdec")
314               (ior (match_operand:SI 1 "register_operand" "")
315                    (match_operand:HI 1 "register_operand" "")))
316            (const_int 0)
317          (and (eq_attr "type" "push")
318               (not (match_operand 1 "memory_operand" "")))
319            (const_int 0)
320          (and (eq_attr "type" "pop")
321               (not (match_operand 0 "memory_operand" "")))
322            (const_int 0)
323          (and (eq_attr "type" "imov")
324               (ior (and (match_operand 0 "register_operand" "")
325                         (match_operand 1 "immediate_operand" ""))
326                    (ior (and (match_operand 0 "ax_reg_operand" "")
327                              (match_operand 1 "memory_displacement_only_operand" ""))
328                         (and (match_operand 0 "memory_displacement_only_operand" "")
329                              (match_operand 1 "ax_reg_operand" "")))))
330            (const_int 0)
331          (and (eq_attr "type" "call")
332               (match_operand 0 "constant_call_address_operand" ""))
333              (const_int 0)
334          (and (eq_attr "type" "callv")
335               (match_operand 1 "constant_call_address_operand" ""))
336              (const_int 0)
337          ]
338          (const_int 1)))
339
340 ;; The (bounding maximum) length of an instruction in bytes.
341 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
342 ;; Later we may want to split them and compute proper length as for
343 ;; other insns.
344 (define_attr "length" ""
345   (cond [(eq_attr "type" "other,multi,fistp,frndint")
346            (const_int 16)
347          (eq_attr "type" "fcmp")
348            (const_int 4)
349          (eq_attr "unit" "i387")
350            (plus (const_int 2)
351                  (plus (attr "prefix_data16")
352                        (attr "length_address")))]
353          (plus (plus (attr "modrm")
354                      (plus (attr "prefix_0f")
355                            (plus (attr "prefix_rex")
356                                  (const_int 1))))
357                (plus (attr "prefix_rep")
358                      (plus (attr "prefix_data16")
359                            (plus (attr "length_immediate")
360                                  (attr "length_address")))))))
361
362 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
363 ;; `store' if there is a simple memory reference therein, or `unknown'
364 ;; if the instruction is complex.
365
366 (define_attr "memory" "none,load,store,both,unknown"
367   (cond [(eq_attr "type" "other,multi,str")
368            (const_string "unknown")
369          (eq_attr "type" "lea,fcmov,fpspc,cld")
370            (const_string "none")
371          (eq_attr "type" "fistp,leave")
372            (const_string "both")
373          (eq_attr "type" "frndint")
374            (const_string "load")
375          (eq_attr "type" "push")
376            (if_then_else (match_operand 1 "memory_operand" "")
377              (const_string "both")
378              (const_string "store"))
379          (eq_attr "type" "pop")
380            (if_then_else (match_operand 0 "memory_operand" "")
381              (const_string "both")
382              (const_string "load"))
383          (eq_attr "type" "setcc")
384            (if_then_else (match_operand 0 "memory_operand" "")
385              (const_string "store")
386              (const_string "none"))
387          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
388            (if_then_else (ior (match_operand 0 "memory_operand" "")
389                               (match_operand 1 "memory_operand" ""))
390              (const_string "load")
391              (const_string "none"))
392          (eq_attr "type" "ibr")
393            (if_then_else (match_operand 0 "memory_operand" "")
394              (const_string "load")
395              (const_string "none"))
396          (eq_attr "type" "call")
397            (if_then_else (match_operand 0 "constant_call_address_operand" "")
398              (const_string "none")
399              (const_string "load"))
400          (eq_attr "type" "callv")
401            (if_then_else (match_operand 1 "constant_call_address_operand" "")
402              (const_string "none")
403              (const_string "load"))
404          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
405               (match_operand 1 "memory_operand" ""))
406            (const_string "both")
407          (and (match_operand 0 "memory_operand" "")
408               (match_operand 1 "memory_operand" ""))
409            (const_string "both")
410          (match_operand 0 "memory_operand" "")
411            (const_string "store")
412          (match_operand 1 "memory_operand" "")
413            (const_string "load")
414          (and (eq_attr "type"
415                  "!alu1,negnot,ishift1,
416                    imov,imovx,icmp,test,
417                    fmov,fcmp,fsgn,
418                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
419                    mmx,mmxmov,mmxcmp,mmxcvt")
420               (match_operand 2 "memory_operand" ""))
421            (const_string "load")
422          (and (eq_attr "type" "icmov")
423               (match_operand 3 "memory_operand" ""))
424            (const_string "load")
425         ]
426         (const_string "none")))
427
428 ;; Indicates if an instruction has both an immediate and a displacement.
429
430 (define_attr "imm_disp" "false,true,unknown"
431   (cond [(eq_attr "type" "other,multi")
432            (const_string "unknown")
433          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
434               (and (match_operand 0 "memory_displacement_operand" "")
435                    (match_operand 1 "immediate_operand" "")))
436            (const_string "true")
437          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
438               (and (match_operand 0 "memory_displacement_operand" "")
439                    (match_operand 2 "immediate_operand" "")))
440            (const_string "true")
441         ]
442         (const_string "false")))
443
444 ;; Indicates if an FP operation has an integer source.
445
446 (define_attr "fp_int_src" "false,true"
447   (const_string "false"))
448
449 ;; Defines rounding mode of an FP operation.
450
451 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
452   (const_string "any"))
453
454 ;; Describe a user's asm statement.
455 (define_asm_attributes
456   [(set_attr "length" "128")
457    (set_attr "type" "multi")])
458
459 ;; All x87 floating point modes
460 (define_mode_macro X87MODEF [SF DF XF])
461  
462 ;; All integer modes handled by x87 fisttp operator.
463 (define_mode_macro X87MODEI [HI SI DI])
464
465 ;; All integer modes handled by integer x87 operators.
466 (define_mode_macro X87MODEI12 [HI SI])
467
468 ;; All SSE floating point modes
469 (define_mode_macro SSEMODEF [SF DF])
470  
471 ;; All integer modes handled by SSE cvtts?2si* operators.
472 (define_mode_macro SSEMODEI24 [SI DI])
473
474 \f
475 ;; Scheduling descriptions
476
477 (include "pentium.md")
478 (include "ppro.md")
479 (include "k6.md")
480 (include "athlon.md")
481
482 \f
483 ;; Operand and operator predicates and constraints
484
485 (include "predicates.md")
486 (include "constraints.md")
487
488 \f
489 ;; Compare instructions.
490
491 ;; All compare insns have expanders that save the operands away without
492 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
493 ;; after the cmp) will actually emit the cmpM.
494
495 (define_expand "cmpti"
496   [(set (reg:CC FLAGS_REG)
497         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
498                     (match_operand:TI 1 "x86_64_general_operand" "")))]
499   "TARGET_64BIT"
500 {
501   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
502     operands[0] = force_reg (TImode, operands[0]);
503   ix86_compare_op0 = operands[0];
504   ix86_compare_op1 = operands[1];
505   DONE;
506 })
507
508 (define_expand "cmpdi"
509   [(set (reg:CC FLAGS_REG)
510         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
511                     (match_operand:DI 1 "x86_64_general_operand" "")))]
512   ""
513 {
514   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
515     operands[0] = force_reg (DImode, operands[0]);
516   ix86_compare_op0 = operands[0];
517   ix86_compare_op1 = operands[1];
518   DONE;
519 })
520
521 (define_expand "cmpsi"
522   [(set (reg:CC FLAGS_REG)
523         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
524                     (match_operand:SI 1 "general_operand" "")))]
525   ""
526 {
527   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
528     operands[0] = force_reg (SImode, operands[0]);
529   ix86_compare_op0 = operands[0];
530   ix86_compare_op1 = operands[1];
531   DONE;
532 })
533
534 (define_expand "cmphi"
535   [(set (reg:CC FLAGS_REG)
536         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
537                     (match_operand:HI 1 "general_operand" "")))]
538   ""
539 {
540   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
541     operands[0] = force_reg (HImode, operands[0]);
542   ix86_compare_op0 = operands[0];
543   ix86_compare_op1 = operands[1];
544   DONE;
545 })
546
547 (define_expand "cmpqi"
548   [(set (reg:CC FLAGS_REG)
549         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
550                     (match_operand:QI 1 "general_operand" "")))]
551   "TARGET_QIMODE_MATH"
552 {
553   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
554     operands[0] = force_reg (QImode, operands[0]);
555   ix86_compare_op0 = operands[0];
556   ix86_compare_op1 = operands[1];
557   DONE;
558 })
559
560 (define_insn "cmpdi_ccno_1_rex64"
561   [(set (reg FLAGS_REG)
562         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
563                  (match_operand:DI 1 "const0_operand" "n,n")))]
564   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
565   "@
566    test{q}\t{%0, %0|%0, %0}
567    cmp{q}\t{%1, %0|%0, %1}"
568   [(set_attr "type" "test,icmp")
569    (set_attr "length_immediate" "0,1")
570    (set_attr "mode" "DI")])
571
572 (define_insn "*cmpdi_minus_1_rex64"
573   [(set (reg FLAGS_REG)
574         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
575                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
576                  (const_int 0)))]
577   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
578   "cmp{q}\t{%1, %0|%0, %1}"
579   [(set_attr "type" "icmp")
580    (set_attr "mode" "DI")])
581
582 (define_expand "cmpdi_1_rex64"
583   [(set (reg:CC FLAGS_REG)
584         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
585                     (match_operand:DI 1 "general_operand" "")))]
586   "TARGET_64BIT"
587   "")
588
589 (define_insn "cmpdi_1_insn_rex64"
590   [(set (reg FLAGS_REG)
591         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
592                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
593   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
594   "cmp{q}\t{%1, %0|%0, %1}"
595   [(set_attr "type" "icmp")
596    (set_attr "mode" "DI")])
597
598
599 (define_insn "*cmpsi_ccno_1"
600   [(set (reg FLAGS_REG)
601         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
602                  (match_operand:SI 1 "const0_operand" "n,n")))]
603   "ix86_match_ccmode (insn, CCNOmode)"
604   "@
605    test{l}\t{%0, %0|%0, %0}
606    cmp{l}\t{%1, %0|%0, %1}"
607   [(set_attr "type" "test,icmp")
608    (set_attr "length_immediate" "0,1")
609    (set_attr "mode" "SI")])
610
611 (define_insn "*cmpsi_minus_1"
612   [(set (reg FLAGS_REG)
613         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
614                            (match_operand:SI 1 "general_operand" "ri,mr"))
615                  (const_int 0)))]
616   "ix86_match_ccmode (insn, CCGOCmode)"
617   "cmp{l}\t{%1, %0|%0, %1}"
618   [(set_attr "type" "icmp")
619    (set_attr "mode" "SI")])
620
621 (define_expand "cmpsi_1"
622   [(set (reg:CC FLAGS_REG)
623         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
624                     (match_operand:SI 1 "general_operand" "ri,mr")))]
625   ""
626   "")
627
628 (define_insn "*cmpsi_1_insn"
629   [(set (reg FLAGS_REG)
630         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
631                  (match_operand:SI 1 "general_operand" "ri,mr")))]
632   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
633     && ix86_match_ccmode (insn, CCmode)"
634   "cmp{l}\t{%1, %0|%0, %1}"
635   [(set_attr "type" "icmp")
636    (set_attr "mode" "SI")])
637
638 (define_insn "*cmphi_ccno_1"
639   [(set (reg FLAGS_REG)
640         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
641                  (match_operand:HI 1 "const0_operand" "n,n")))]
642   "ix86_match_ccmode (insn, CCNOmode)"
643   "@
644    test{w}\t{%0, %0|%0, %0}
645    cmp{w}\t{%1, %0|%0, %1}"
646   [(set_attr "type" "test,icmp")
647    (set_attr "length_immediate" "0,1")
648    (set_attr "mode" "HI")])
649
650 (define_insn "*cmphi_minus_1"
651   [(set (reg FLAGS_REG)
652         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
653                            (match_operand:HI 1 "general_operand" "ri,mr"))
654                  (const_int 0)))]
655   "ix86_match_ccmode (insn, CCGOCmode)"
656   "cmp{w}\t{%1, %0|%0, %1}"
657   [(set_attr "type" "icmp")
658    (set_attr "mode" "HI")])
659
660 (define_insn "*cmphi_1"
661   [(set (reg FLAGS_REG)
662         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
663                  (match_operand:HI 1 "general_operand" "ri,mr")))]
664   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
665    && ix86_match_ccmode (insn, CCmode)"
666   "cmp{w}\t{%1, %0|%0, %1}"
667   [(set_attr "type" "icmp")
668    (set_attr "mode" "HI")])
669
670 (define_insn "*cmpqi_ccno_1"
671   [(set (reg FLAGS_REG)
672         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
673                  (match_operand:QI 1 "const0_operand" "n,n")))]
674   "ix86_match_ccmode (insn, CCNOmode)"
675   "@
676    test{b}\t{%0, %0|%0, %0}
677    cmp{b}\t{$0, %0|%0, 0}"
678   [(set_attr "type" "test,icmp")
679    (set_attr "length_immediate" "0,1")
680    (set_attr "mode" "QI")])
681
682 (define_insn "*cmpqi_1"
683   [(set (reg FLAGS_REG)
684         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
685                  (match_operand:QI 1 "general_operand" "qi,mq")))]
686   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
687     && ix86_match_ccmode (insn, CCmode)"
688   "cmp{b}\t{%1, %0|%0, %1}"
689   [(set_attr "type" "icmp")
690    (set_attr "mode" "QI")])
691
692 (define_insn "*cmpqi_minus_1"
693   [(set (reg FLAGS_REG)
694         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
695                            (match_operand:QI 1 "general_operand" "qi,mq"))
696                  (const_int 0)))]
697   "ix86_match_ccmode (insn, CCGOCmode)"
698   "cmp{b}\t{%1, %0|%0, %1}"
699   [(set_attr "type" "icmp")
700    (set_attr "mode" "QI")])
701
702 (define_insn "*cmpqi_ext_1"
703   [(set (reg FLAGS_REG)
704         (compare
705           (match_operand:QI 0 "general_operand" "Qm")
706           (subreg:QI
707             (zero_extract:SI
708               (match_operand 1 "ext_register_operand" "Q")
709               (const_int 8)
710               (const_int 8)) 0)))]
711   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
712   "cmp{b}\t{%h1, %0|%0, %h1}"
713   [(set_attr "type" "icmp")
714    (set_attr "mode" "QI")])
715
716 (define_insn "*cmpqi_ext_1_rex64"
717   [(set (reg FLAGS_REG)
718         (compare
719           (match_operand:QI 0 "register_operand" "Q")
720           (subreg:QI
721             (zero_extract:SI
722               (match_operand 1 "ext_register_operand" "Q")
723               (const_int 8)
724               (const_int 8)) 0)))]
725   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
726   "cmp{b}\t{%h1, %0|%0, %h1}"
727   [(set_attr "type" "icmp")
728    (set_attr "mode" "QI")])
729
730 (define_insn "*cmpqi_ext_2"
731   [(set (reg FLAGS_REG)
732         (compare
733           (subreg:QI
734             (zero_extract:SI
735               (match_operand 0 "ext_register_operand" "Q")
736               (const_int 8)
737               (const_int 8)) 0)
738           (match_operand:QI 1 "const0_operand" "n")))]
739   "ix86_match_ccmode (insn, CCNOmode)"
740   "test{b}\t%h0, %h0"
741   [(set_attr "type" "test")
742    (set_attr "length_immediate" "0")
743    (set_attr "mode" "QI")])
744
745 (define_expand "cmpqi_ext_3"
746   [(set (reg:CC FLAGS_REG)
747         (compare:CC
748           (subreg:QI
749             (zero_extract:SI
750               (match_operand 0 "ext_register_operand" "")
751               (const_int 8)
752               (const_int 8)) 0)
753           (match_operand:QI 1 "general_operand" "")))]
754   ""
755   "")
756
757 (define_insn "cmpqi_ext_3_insn"
758   [(set (reg FLAGS_REG)
759         (compare
760           (subreg:QI
761             (zero_extract:SI
762               (match_operand 0 "ext_register_operand" "Q")
763               (const_int 8)
764               (const_int 8)) 0)
765           (match_operand:QI 1 "general_operand" "Qmn")))]
766   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
767   "cmp{b}\t{%1, %h0|%h0, %1}"
768   [(set_attr "type" "icmp")
769    (set_attr "mode" "QI")])
770
771 (define_insn "cmpqi_ext_3_insn_rex64"
772   [(set (reg FLAGS_REG)
773         (compare
774           (subreg:QI
775             (zero_extract:SI
776               (match_operand 0 "ext_register_operand" "Q")
777               (const_int 8)
778               (const_int 8)) 0)
779           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
780   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
781   "cmp{b}\t{%1, %h0|%h0, %1}"
782   [(set_attr "type" "icmp")
783    (set_attr "mode" "QI")])
784
785 (define_insn "*cmpqi_ext_4"
786   [(set (reg FLAGS_REG)
787         (compare
788           (subreg:QI
789             (zero_extract:SI
790               (match_operand 0 "ext_register_operand" "Q")
791               (const_int 8)
792               (const_int 8)) 0)
793           (subreg:QI
794             (zero_extract:SI
795               (match_operand 1 "ext_register_operand" "Q")
796               (const_int 8)
797               (const_int 8)) 0)))]
798   "ix86_match_ccmode (insn, CCmode)"
799   "cmp{b}\t{%h1, %h0|%h0, %h1}"
800   [(set_attr "type" "icmp")
801    (set_attr "mode" "QI")])
802
803 ;; These implement float point compares.
804 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
805 ;; which would allow mix and match FP modes on the compares.  Which is what
806 ;; the old patterns did, but with many more of them.
807
808 (define_expand "cmpxf"
809   [(set (reg:CC FLAGS_REG)
810         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
811                     (match_operand:XF 1 "nonmemory_operand" "")))]
812   "TARGET_80387"
813 {
814   ix86_compare_op0 = operands[0];
815   ix86_compare_op1 = operands[1];
816   DONE;
817 })
818
819 (define_expand "cmpdf"
820   [(set (reg:CC FLAGS_REG)
821         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
822                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
823   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
824 {
825   ix86_compare_op0 = operands[0];
826   ix86_compare_op1 = operands[1];
827   DONE;
828 })
829
830 (define_expand "cmpsf"
831   [(set (reg:CC FLAGS_REG)
832         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
833                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
834   "TARGET_80387 || TARGET_SSE_MATH"
835 {
836   ix86_compare_op0 = operands[0];
837   ix86_compare_op1 = operands[1];
838   DONE;
839 })
840
841 ;; FP compares, step 1:
842 ;; Set the FP condition codes.
843 ;;
844 ;; CCFPmode     compare with exceptions
845 ;; CCFPUmode    compare with no exceptions
846
847 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
848 ;; used to manage the reg stack popping would not be preserved.
849
850 (define_insn "*cmpfp_0"
851   [(set (match_operand:HI 0 "register_operand" "=a")
852         (unspec:HI
853           [(compare:CCFP
854              (match_operand 1 "register_operand" "f")
855              (match_operand 2 "const0_operand" "X"))]
856         UNSPEC_FNSTSW))]
857   "TARGET_80387
858    && FLOAT_MODE_P (GET_MODE (operands[1]))
859    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
860   "* return output_fp_compare (insn, operands, 0, 0);"
861   [(set_attr "type" "multi")
862    (set_attr "unit" "i387")
863    (set (attr "mode")
864      (cond [(match_operand:SF 1 "" "")
865               (const_string "SF")
866             (match_operand:DF 1 "" "")
867               (const_string "DF")
868            ]
869            (const_string "XF")))])
870
871 (define_insn "*cmpfp_sf"
872   [(set (match_operand:HI 0 "register_operand" "=a")
873         (unspec:HI
874           [(compare:CCFP
875              (match_operand:SF 1 "register_operand" "f")
876              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
877           UNSPEC_FNSTSW))]
878   "TARGET_80387"
879   "* return output_fp_compare (insn, operands, 0, 0);"
880   [(set_attr "type" "multi")
881    (set_attr "unit" "i387")
882    (set_attr "mode" "SF")])
883
884 (define_insn "*cmpfp_df"
885   [(set (match_operand:HI 0 "register_operand" "=a")
886         (unspec:HI
887           [(compare:CCFP
888              (match_operand:DF 1 "register_operand" "f")
889              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
890           UNSPEC_FNSTSW))]
891   "TARGET_80387"
892   "* return output_fp_compare (insn, operands, 0, 0);"
893   [(set_attr "type" "multi")
894    (set_attr "unit" "i387")
895    (set_attr "mode" "DF")])
896
897 (define_insn "*cmpfp_xf"
898   [(set (match_operand:HI 0 "register_operand" "=a")
899         (unspec:HI
900           [(compare:CCFP
901              (match_operand:XF 1 "register_operand" "f")
902              (match_operand:XF 2 "register_operand" "f"))]
903           UNSPEC_FNSTSW))]
904   "TARGET_80387"
905   "* return output_fp_compare (insn, operands, 0, 0);"
906   [(set_attr "type" "multi")
907    (set_attr "unit" "i387")
908    (set_attr "mode" "XF")])
909
910 (define_insn "*cmpfp_u"
911   [(set (match_operand:HI 0 "register_operand" "=a")
912         (unspec:HI
913           [(compare:CCFPU
914              (match_operand 1 "register_operand" "f")
915              (match_operand 2 "register_operand" "f"))]
916           UNSPEC_FNSTSW))]
917   "TARGET_80387
918    && FLOAT_MODE_P (GET_MODE (operands[1]))
919    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
920   "* return output_fp_compare (insn, operands, 0, 1);"
921   [(set_attr "type" "multi")
922    (set_attr "unit" "i387")
923    (set (attr "mode")
924      (cond [(match_operand:SF 1 "" "")
925               (const_string "SF")
926             (match_operand:DF 1 "" "")
927               (const_string "DF")
928            ]
929            (const_string "XF")))])
930
931 (define_insn "*cmpfp_<mode>"
932   [(set (match_operand:HI 0 "register_operand" "=a")
933         (unspec:HI
934           [(compare:CCFP
935              (match_operand 1 "register_operand" "f")
936              (match_operator 3 "float_operator"
937                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
938           UNSPEC_FNSTSW))]
939   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
940    && FLOAT_MODE_P (GET_MODE (operands[1]))
941    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
942   "* return output_fp_compare (insn, operands, 0, 0);"
943   [(set_attr "type" "multi")
944    (set_attr "unit" "i387")
945    (set_attr "fp_int_src" "true")
946    (set_attr "mode" "<MODE>")])
947
948 ;; FP compares, step 2
949 ;; Move the fpsw to ax.
950
951 (define_insn "x86_fnstsw_1"
952   [(set (match_operand:HI 0 "register_operand" "=a")
953         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
954   "TARGET_80387"
955   "fnstsw\t%0"
956   [(set_attr "length" "2")
957    (set_attr "mode" "SI")
958    (set_attr "unit" "i387")])
959
960 ;; FP compares, step 3
961 ;; Get ax into flags, general case.
962
963 (define_insn "x86_sahf_1"
964   [(set (reg:CC FLAGS_REG)
965         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
966   "!TARGET_64BIT"
967   "sahf"
968   [(set_attr "length" "1")
969    (set_attr "athlon_decode" "vector")
970    (set_attr "mode" "SI")])
971
972 ;; Pentium Pro can do steps 1 through 3 in one go.
973
974 (define_insn "*cmpfp_i_mixed"
975   [(set (reg:CCFP FLAGS_REG)
976         (compare:CCFP (match_operand 0 "register_operand" "f,x")
977                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
978   "TARGET_MIX_SSE_I387
979    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
980    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
981   "* return output_fp_compare (insn, operands, 1, 0);"
982   [(set_attr "type" "fcmp,ssecomi")
983    (set (attr "mode")
984      (if_then_else (match_operand:SF 1 "" "")
985         (const_string "SF")
986         (const_string "DF")))
987    (set_attr "athlon_decode" "vector")])
988
989 (define_insn "*cmpfp_i_sse"
990   [(set (reg:CCFP FLAGS_REG)
991         (compare:CCFP (match_operand 0 "register_operand" "x")
992                       (match_operand 1 "nonimmediate_operand" "xm")))]
993   "TARGET_SSE_MATH
994    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
995    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
996   "* return output_fp_compare (insn, operands, 1, 0);"
997   [(set_attr "type" "ssecomi")
998    (set (attr "mode")
999      (if_then_else (match_operand:SF 1 "" "")
1000         (const_string "SF")
1001         (const_string "DF")))
1002    (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_i_i387"
1005   [(set (reg:CCFP FLAGS_REG)
1006         (compare:CCFP (match_operand 0 "register_operand" "f")
1007                       (match_operand 1 "register_operand" "f")))]
1008   "TARGET_80387 && TARGET_CMOVE
1009    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1010    && FLOAT_MODE_P (GET_MODE (operands[0]))
1011    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1012   "* return output_fp_compare (insn, operands, 1, 0);"
1013   [(set_attr "type" "fcmp")
1014    (set (attr "mode")
1015      (cond [(match_operand:SF 1 "" "")
1016               (const_string "SF")
1017             (match_operand:DF 1 "" "")
1018               (const_string "DF")
1019            ]
1020            (const_string "XF")))
1021    (set_attr "athlon_decode" "vector")])
1022
1023 (define_insn "*cmpfp_iu_mixed"
1024   [(set (reg:CCFPU FLAGS_REG)
1025         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1026                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1027   "TARGET_MIX_SSE_I387
1028    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1029    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1030   "* return output_fp_compare (insn, operands, 1, 1);"
1031   [(set_attr "type" "fcmp,ssecomi")
1032    (set (attr "mode")
1033      (if_then_else (match_operand:SF 1 "" "")
1034         (const_string "SF")
1035         (const_string "DF")))
1036    (set_attr "athlon_decode" "vector")])
1037
1038 (define_insn "*cmpfp_iu_sse"
1039   [(set (reg:CCFPU FLAGS_REG)
1040         (compare:CCFPU (match_operand 0 "register_operand" "x")
1041                        (match_operand 1 "nonimmediate_operand" "xm")))]
1042   "TARGET_SSE_MATH
1043    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1044    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1045   "* return output_fp_compare (insn, operands, 1, 1);"
1046   [(set_attr "type" "ssecomi")
1047    (set (attr "mode")
1048      (if_then_else (match_operand:SF 1 "" "")
1049         (const_string "SF")
1050         (const_string "DF")))
1051    (set_attr "athlon_decode" "vector")])
1052
1053 (define_insn "*cmpfp_iu_387"
1054   [(set (reg:CCFPU FLAGS_REG)
1055         (compare:CCFPU (match_operand 0 "register_operand" "f")
1056                        (match_operand 1 "register_operand" "f")))]
1057   "TARGET_80387 && TARGET_CMOVE
1058    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1059    && FLOAT_MODE_P (GET_MODE (operands[0]))
1060    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1061   "* return output_fp_compare (insn, operands, 1, 1);"
1062   [(set_attr "type" "fcmp")
1063    (set (attr "mode")
1064      (cond [(match_operand:SF 1 "" "")
1065               (const_string "SF")
1066             (match_operand:DF 1 "" "")
1067               (const_string "DF")
1068            ]
1069            (const_string "XF")))
1070    (set_attr "athlon_decode" "vector")])
1071 \f
1072 ;; Move instructions.
1073
1074 ;; General case of fullword move.
1075
1076 (define_expand "movsi"
1077   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1078         (match_operand:SI 1 "general_operand" ""))]
1079   ""
1080   "ix86_expand_move (SImode, operands); DONE;")
1081
1082 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1083 ;; general_operand.
1084 ;;
1085 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1086 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1087 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1088 ;; targets without our curiosities, and it is just as easy to represent
1089 ;; this differently.
1090
1091 (define_insn "*pushsi2"
1092   [(set (match_operand:SI 0 "push_operand" "=<")
1093         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1094   "!TARGET_64BIT"
1095   "push{l}\t%1"
1096   [(set_attr "type" "push")
1097    (set_attr "mode" "SI")])
1098
1099 ;; For 64BIT abi we always round up to 8 bytes.
1100 (define_insn "*pushsi2_rex64"
1101   [(set (match_operand:SI 0 "push_operand" "=X")
1102         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1103   "TARGET_64BIT"
1104   "push{q}\t%q1"
1105   [(set_attr "type" "push")
1106    (set_attr "mode" "SI")])
1107
1108 (define_insn "*pushsi2_prologue"
1109   [(set (match_operand:SI 0 "push_operand" "=<")
1110         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1111    (clobber (mem:BLK (scratch)))]
1112   "!TARGET_64BIT"
1113   "push{l}\t%1"
1114   [(set_attr "type" "push")
1115    (set_attr "mode" "SI")])
1116
1117 (define_insn "*popsi1_epilogue"
1118   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1119         (mem:SI (reg:SI SP_REG)))
1120    (set (reg:SI SP_REG)
1121         (plus:SI (reg:SI SP_REG) (const_int 4)))
1122    (clobber (mem:BLK (scratch)))]
1123   "!TARGET_64BIT"
1124   "pop{l}\t%0"
1125   [(set_attr "type" "pop")
1126    (set_attr "mode" "SI")])
1127
1128 (define_insn "popsi1"
1129   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1130         (mem:SI (reg:SI SP_REG)))
1131    (set (reg:SI SP_REG)
1132         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1133   "!TARGET_64BIT"
1134   "pop{l}\t%0"
1135   [(set_attr "type" "pop")
1136    (set_attr "mode" "SI")])
1137
1138 (define_insn "*movsi_xor"
1139   [(set (match_operand:SI 0 "register_operand" "=r")
1140         (match_operand:SI 1 "const0_operand" "i"))
1141    (clobber (reg:CC FLAGS_REG))]
1142   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1143   "xor{l}\t{%0, %0|%0, %0}"
1144   [(set_attr "type" "alu1")
1145    (set_attr "mode" "SI")
1146    (set_attr "length_immediate" "0")])
1147  
1148 (define_insn "*movsi_or"
1149   [(set (match_operand:SI 0 "register_operand" "=r")
1150         (match_operand:SI 1 "immediate_operand" "i"))
1151    (clobber (reg:CC FLAGS_REG))]
1152   "reload_completed
1153    && operands[1] == constm1_rtx
1154    && (TARGET_PENTIUM || optimize_size)"
1155 {
1156   operands[1] = constm1_rtx;
1157   return "or{l}\t{%1, %0|%0, %1}";
1158 }
1159   [(set_attr "type" "alu1")
1160    (set_attr "mode" "SI")
1161    (set_attr "length_immediate" "1")])
1162
1163 (define_insn "*movsi_1"
1164   [(set (match_operand:SI 0 "nonimmediate_operand"
1165                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1166         (match_operand:SI 1 "general_operand"
1167                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1168   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1169 {
1170   switch (get_attr_type (insn))
1171     {
1172     case TYPE_SSELOG1:
1173       if (get_attr_mode (insn) == MODE_TI)
1174         return "pxor\t%0, %0";
1175       return "xorps\t%0, %0";
1176
1177     case TYPE_SSEMOV:
1178       switch (get_attr_mode (insn))
1179         {
1180         case MODE_TI:
1181           return "movdqa\t{%1, %0|%0, %1}";
1182         case MODE_V4SF:
1183           return "movaps\t{%1, %0|%0, %1}";
1184         case MODE_SI:
1185           return "movd\t{%1, %0|%0, %1}";
1186         case MODE_SF:
1187           return "movss\t{%1, %0|%0, %1}";
1188         default:
1189           gcc_unreachable ();
1190         }
1191
1192     case TYPE_MMXADD:
1193       return "pxor\t%0, %0";
1194
1195     case TYPE_MMXMOV:
1196       if (get_attr_mode (insn) == MODE_DI)
1197         return "movq\t{%1, %0|%0, %1}";
1198       return "movd\t{%1, %0|%0, %1}";
1199
1200     case TYPE_LEA:
1201       return "lea{l}\t{%1, %0|%0, %1}";
1202
1203     default:
1204       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1205       return "mov{l}\t{%1, %0|%0, %1}";
1206     }
1207 }
1208   [(set (attr "type")
1209      (cond [(eq_attr "alternative" "2")
1210               (const_string "mmxadd")
1211             (eq_attr "alternative" "3,4,5")
1212               (const_string "mmxmov")
1213             (eq_attr "alternative" "6")
1214               (const_string "sselog1")
1215             (eq_attr "alternative" "7,8,9,10,11")
1216               (const_string "ssemov")
1217             (match_operand:DI 1 "pic_32bit_operand" "")
1218               (const_string "lea")
1219            ]
1220            (const_string "imov")))
1221    (set (attr "mode")
1222      (cond [(eq_attr "alternative" "2,3")
1223               (const_string "DI")
1224             (eq_attr "alternative" "6,7")
1225               (if_then_else
1226                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1227                 (const_string "V4SF")
1228                 (const_string "TI"))
1229             (and (eq_attr "alternative" "8,9,10,11")
1230                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1231               (const_string "SF")
1232            ]
1233            (const_string "SI")))])
1234
1235 ;; Stores and loads of ax to arbitrary constant address.
1236 ;; We fake an second form of instruction to force reload to load address
1237 ;; into register when rax is not available
1238 (define_insn "*movabssi_1_rex64"
1239   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1240         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1241   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1242   "@
1243    movabs{l}\t{%1, %P0|%P0, %1}
1244    mov{l}\t{%1, %a0|%a0, %1}"
1245   [(set_attr "type" "imov")
1246    (set_attr "modrm" "0,*")
1247    (set_attr "length_address" "8,0")
1248    (set_attr "length_immediate" "0,*")
1249    (set_attr "memory" "store")
1250    (set_attr "mode" "SI")])
1251
1252 (define_insn "*movabssi_2_rex64"
1253   [(set (match_operand:SI 0 "register_operand" "=a,r")
1254         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1255   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1256   "@
1257    movabs{l}\t{%P1, %0|%0, %P1}
1258    mov{l}\t{%a1, %0|%0, %a1}"
1259   [(set_attr "type" "imov")
1260    (set_attr "modrm" "0,*")
1261    (set_attr "length_address" "8,0")
1262    (set_attr "length_immediate" "0")
1263    (set_attr "memory" "load")
1264    (set_attr "mode" "SI")])
1265
1266 (define_insn "*swapsi"
1267   [(set (match_operand:SI 0 "register_operand" "+r")
1268         (match_operand:SI 1 "register_operand" "+r"))
1269    (set (match_dup 1)
1270         (match_dup 0))]
1271   ""
1272   "xchg{l}\t%1, %0"
1273   [(set_attr "type" "imov")
1274    (set_attr "mode" "SI")
1275    (set_attr "pent_pair" "np")
1276    (set_attr "athlon_decode" "vector")])
1277
1278 (define_expand "movhi"
1279   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1280         (match_operand:HI 1 "general_operand" ""))]
1281   ""
1282   "ix86_expand_move (HImode, operands); DONE;")
1283
1284 (define_insn "*pushhi2"
1285   [(set (match_operand:HI 0 "push_operand" "=X")
1286         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1287   "!TARGET_64BIT"
1288   "push{l}\t%k1"
1289   [(set_attr "type" "push")
1290    (set_attr "mode" "SI")])
1291
1292 ;; For 64BIT abi we always round up to 8 bytes.
1293 (define_insn "*pushhi2_rex64"
1294   [(set (match_operand:HI 0 "push_operand" "=X")
1295         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1296   "TARGET_64BIT"
1297   "push{q}\t%q1"
1298   [(set_attr "type" "push")
1299    (set_attr "mode" "DI")])
1300
1301 (define_insn "*movhi_1"
1302   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1303         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1304   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1305 {
1306   switch (get_attr_type (insn))
1307     {
1308     case TYPE_IMOVX:
1309       /* movzwl is faster than movw on p2 due to partial word stalls,
1310          though not as fast as an aligned movl.  */
1311       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1312     default:
1313       if (get_attr_mode (insn) == MODE_SI)
1314         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1315       else
1316         return "mov{w}\t{%1, %0|%0, %1}";
1317     }
1318 }
1319   [(set (attr "type")
1320      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1321               (const_string "imov")
1322             (and (eq_attr "alternative" "0")
1323                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1324                           (const_int 0))
1325                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1326                           (const_int 0))))
1327               (const_string "imov")
1328             (and (eq_attr "alternative" "1,2")
1329                  (match_operand:HI 1 "aligned_operand" ""))
1330               (const_string "imov")
1331             (and (ne (symbol_ref "TARGET_MOVX")
1332                      (const_int 0))
1333                  (eq_attr "alternative" "0,2"))
1334               (const_string "imovx")
1335            ]
1336            (const_string "imov")))
1337     (set (attr "mode")
1338       (cond [(eq_attr "type" "imovx")
1339                (const_string "SI")
1340              (and (eq_attr "alternative" "1,2")
1341                   (match_operand:HI 1 "aligned_operand" ""))
1342                (const_string "SI")
1343              (and (eq_attr "alternative" "0")
1344                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1345                            (const_int 0))
1346                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1347                            (const_int 0))))
1348                (const_string "SI")
1349             ]
1350             (const_string "HI")))])
1351
1352 ;; Stores and loads of ax to arbitrary constant address.
1353 ;; We fake an second form of instruction to force reload to load address
1354 ;; into register when rax is not available
1355 (define_insn "*movabshi_1_rex64"
1356   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1357         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1358   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1359   "@
1360    movabs{w}\t{%1, %P0|%P0, %1}
1361    mov{w}\t{%1, %a0|%a0, %1}"
1362   [(set_attr "type" "imov")
1363    (set_attr "modrm" "0,*")
1364    (set_attr "length_address" "8,0")
1365    (set_attr "length_immediate" "0,*")
1366    (set_attr "memory" "store")
1367    (set_attr "mode" "HI")])
1368
1369 (define_insn "*movabshi_2_rex64"
1370   [(set (match_operand:HI 0 "register_operand" "=a,r")
1371         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1372   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1373   "@
1374    movabs{w}\t{%P1, %0|%0, %P1}
1375    mov{w}\t{%a1, %0|%0, %a1}"
1376   [(set_attr "type" "imov")
1377    (set_attr "modrm" "0,*")
1378    (set_attr "length_address" "8,0")
1379    (set_attr "length_immediate" "0")
1380    (set_attr "memory" "load")
1381    (set_attr "mode" "HI")])
1382
1383 (define_insn "*swaphi_1"
1384   [(set (match_operand:HI 0 "register_operand" "+r")
1385         (match_operand:HI 1 "register_operand" "+r"))
1386    (set (match_dup 1)
1387         (match_dup 0))]
1388   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1389   "xchg{l}\t%k1, %k0"
1390   [(set_attr "type" "imov")
1391    (set_attr "mode" "SI")
1392    (set_attr "pent_pair" "np")
1393    (set_attr "athlon_decode" "vector")])
1394
1395 (define_insn "*swaphi_2"
1396   [(set (match_operand:HI 0 "register_operand" "+r")
1397         (match_operand:HI 1 "register_operand" "+r"))
1398    (set (match_dup 1)
1399         (match_dup 0))]
1400   "TARGET_PARTIAL_REG_STALL"
1401   "xchg{w}\t%1, %0"
1402   [(set_attr "type" "imov")
1403    (set_attr "mode" "HI")
1404    (set_attr "pent_pair" "np")
1405    (set_attr "athlon_decode" "vector")])
1406
1407 (define_expand "movstricthi"
1408   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1409         (match_operand:HI 1 "general_operand" ""))]
1410   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1411 {
1412   /* Don't generate memory->memory moves, go through a register */
1413   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1414     operands[1] = force_reg (HImode, operands[1]);
1415 })
1416
1417 (define_insn "*movstricthi_1"
1418   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1419         (match_operand:HI 1 "general_operand" "rn,m"))]
1420   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1421    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1422   "mov{w}\t{%1, %0|%0, %1}"
1423   [(set_attr "type" "imov")
1424    (set_attr "mode" "HI")])
1425
1426 (define_insn "*movstricthi_xor"
1427   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1428         (match_operand:HI 1 "const0_operand" "i"))
1429    (clobber (reg:CC FLAGS_REG))]
1430   "reload_completed
1431    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1432   "xor{w}\t{%0, %0|%0, %0}"
1433   [(set_attr "type" "alu1")
1434    (set_attr "mode" "HI")
1435    (set_attr "length_immediate" "0")])
1436
1437 (define_expand "movqi"
1438   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1439         (match_operand:QI 1 "general_operand" ""))]
1440   ""
1441   "ix86_expand_move (QImode, operands); DONE;")
1442
1443 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1444 ;; "push a byte".  But actually we use pushl, which has the effect
1445 ;; of rounding the amount pushed up to a word.
1446
1447 (define_insn "*pushqi2"
1448   [(set (match_operand:QI 0 "push_operand" "=X")
1449         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1450   "!TARGET_64BIT"
1451   "push{l}\t%k1"
1452   [(set_attr "type" "push")
1453    (set_attr "mode" "SI")])
1454
1455 ;; For 64BIT abi we always round up to 8 bytes.
1456 (define_insn "*pushqi2_rex64"
1457   [(set (match_operand:QI 0 "push_operand" "=X")
1458         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1459   "TARGET_64BIT"
1460   "push{q}\t%q1"
1461   [(set_attr "type" "push")
1462    (set_attr "mode" "DI")])
1463
1464 ;; Situation is quite tricky about when to choose full sized (SImode) move
1465 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1466 ;; partial register dependency machines (such as AMD Athlon), where QImode
1467 ;; moves issue extra dependency and for partial register stalls machines
1468 ;; that don't use QImode patterns (and QImode move cause stall on the next
1469 ;; instruction).
1470 ;;
1471 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1472 ;; register stall machines with, where we use QImode instructions, since
1473 ;; partial register stall can be caused there.  Then we use movzx.
1474 (define_insn "*movqi_1"
1475   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1476         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1477   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1478 {
1479   switch (get_attr_type (insn))
1480     {
1481     case TYPE_IMOVX:
1482       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1483       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1484     default:
1485       if (get_attr_mode (insn) == MODE_SI)
1486         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1487       else
1488         return "mov{b}\t{%1, %0|%0, %1}";
1489     }
1490 }
1491   [(set (attr "type")
1492      (cond [(and (eq_attr "alternative" "5")
1493                  (not (match_operand:QI 1 "aligned_operand" "")))
1494               (const_string "imovx")
1495             (ne (symbol_ref "optimize_size") (const_int 0))
1496               (const_string "imov")
1497             (and (eq_attr "alternative" "3")
1498                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1499                           (const_int 0))
1500                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1501                           (const_int 0))))
1502               (const_string "imov")
1503             (eq_attr "alternative" "3,5")
1504               (const_string "imovx")
1505             (and (ne (symbol_ref "TARGET_MOVX")
1506                      (const_int 0))
1507                  (eq_attr "alternative" "2"))
1508               (const_string "imovx")
1509            ]
1510            (const_string "imov")))
1511    (set (attr "mode")
1512       (cond [(eq_attr "alternative" "3,4,5")
1513                (const_string "SI")
1514              (eq_attr "alternative" "6")
1515                (const_string "QI")
1516              (eq_attr "type" "imovx")
1517                (const_string "SI")
1518              (and (eq_attr "type" "imov")
1519                   (and (eq_attr "alternative" "0,1")
1520                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1521                                 (const_int 0))
1522                             (and (eq (symbol_ref "optimize_size")
1523                                      (const_int 0))
1524                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1525                                      (const_int 0))))))
1526                (const_string "SI")
1527              ;; Avoid partial register stalls when not using QImode arithmetic
1528              (and (eq_attr "type" "imov")
1529                   (and (eq_attr "alternative" "0,1")
1530                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1531                                 (const_int 0))
1532                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1533                                 (const_int 0)))))
1534                (const_string "SI")
1535            ]
1536            (const_string "QI")))])
1537
1538 (define_expand "reload_outqi"
1539   [(parallel [(match_operand:QI 0 "" "=m")
1540               (match_operand:QI 1 "register_operand" "r")
1541               (match_operand:QI 2 "register_operand" "=&q")])]
1542   ""
1543 {
1544   rtx op0, op1, op2;
1545   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1546
1547   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1548   if (! q_regs_operand (op1, QImode))
1549     {
1550       emit_insn (gen_movqi (op2, op1));
1551       op1 = op2;
1552     }
1553   emit_insn (gen_movqi (op0, op1));
1554   DONE;
1555 })
1556
1557 (define_insn "*swapqi_1"
1558   [(set (match_operand:QI 0 "register_operand" "+r")
1559         (match_operand:QI 1 "register_operand" "+r"))
1560    (set (match_dup 1)
1561         (match_dup 0))]
1562   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1563   "xchg{l}\t%k1, %k0"
1564   [(set_attr "type" "imov")
1565    (set_attr "mode" "SI")
1566    (set_attr "pent_pair" "np")
1567    (set_attr "athlon_decode" "vector")])
1568
1569 (define_insn "*swapqi_2"
1570   [(set (match_operand:QI 0 "register_operand" "+q")
1571         (match_operand:QI 1 "register_operand" "+q"))
1572    (set (match_dup 1)
1573         (match_dup 0))]
1574   "TARGET_PARTIAL_REG_STALL"
1575   "xchg{b}\t%1, %0"
1576   [(set_attr "type" "imov")
1577    (set_attr "mode" "QI")
1578    (set_attr "pent_pair" "np")
1579    (set_attr "athlon_decode" "vector")])
1580
1581 (define_expand "movstrictqi"
1582   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1583         (match_operand:QI 1 "general_operand" ""))]
1584   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1585 {
1586   /* Don't generate memory->memory moves, go through a register.  */
1587   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1588     operands[1] = force_reg (QImode, operands[1]);
1589 })
1590
1591 (define_insn "*movstrictqi_1"
1592   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1593         (match_operand:QI 1 "general_operand" "*qn,m"))]
1594   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1595    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1596   "mov{b}\t{%1, %0|%0, %1}"
1597   [(set_attr "type" "imov")
1598    (set_attr "mode" "QI")])
1599
1600 (define_insn "*movstrictqi_xor"
1601   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1602         (match_operand:QI 1 "const0_operand" "i"))
1603    (clobber (reg:CC FLAGS_REG))]
1604   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1605   "xor{b}\t{%0, %0|%0, %0}"
1606   [(set_attr "type" "alu1")
1607    (set_attr "mode" "QI")
1608    (set_attr "length_immediate" "0")])
1609
1610 (define_insn "*movsi_extv_1"
1611   [(set (match_operand:SI 0 "register_operand" "=R")
1612         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1613                          (const_int 8)
1614                          (const_int 8)))]
1615   ""
1616   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1617   [(set_attr "type" "imovx")
1618    (set_attr "mode" "SI")])
1619
1620 (define_insn "*movhi_extv_1"
1621   [(set (match_operand:HI 0 "register_operand" "=R")
1622         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1623                          (const_int 8)
1624                          (const_int 8)))]
1625   ""
1626   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1627   [(set_attr "type" "imovx")
1628    (set_attr "mode" "SI")])
1629
1630 (define_insn "*movqi_extv_1"
1631   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1632         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1633                          (const_int 8)
1634                          (const_int 8)))]
1635   "!TARGET_64BIT"
1636 {
1637   switch (get_attr_type (insn))
1638     {
1639     case TYPE_IMOVX:
1640       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1641     default:
1642       return "mov{b}\t{%h1, %0|%0, %h1}";
1643     }
1644 }
1645   [(set (attr "type")
1646      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1647                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1648                              (ne (symbol_ref "TARGET_MOVX")
1649                                  (const_int 0))))
1650         (const_string "imovx")
1651         (const_string "imov")))
1652    (set (attr "mode")
1653      (if_then_else (eq_attr "type" "imovx")
1654         (const_string "SI")
1655         (const_string "QI")))])
1656
1657 (define_insn "*movqi_extv_1_rex64"
1658   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1659         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1660                          (const_int 8)
1661                          (const_int 8)))]
1662   "TARGET_64BIT"
1663 {
1664   switch (get_attr_type (insn))
1665     {
1666     case TYPE_IMOVX:
1667       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1668     default:
1669       return "mov{b}\t{%h1, %0|%0, %h1}";
1670     }
1671 }
1672   [(set (attr "type")
1673      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1674                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1675                              (ne (symbol_ref "TARGET_MOVX")
1676                                  (const_int 0))))
1677         (const_string "imovx")
1678         (const_string "imov")))
1679    (set (attr "mode")
1680      (if_then_else (eq_attr "type" "imovx")
1681         (const_string "SI")
1682         (const_string "QI")))])
1683
1684 ;; Stores and loads of ax to arbitrary constant address.
1685 ;; We fake an second form of instruction to force reload to load address
1686 ;; into register when rax is not available
1687 (define_insn "*movabsqi_1_rex64"
1688   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1689         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1690   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1691   "@
1692    movabs{b}\t{%1, %P0|%P0, %1}
1693    mov{b}\t{%1, %a0|%a0, %1}"
1694   [(set_attr "type" "imov")
1695    (set_attr "modrm" "0,*")
1696    (set_attr "length_address" "8,0")
1697    (set_attr "length_immediate" "0,*")
1698    (set_attr "memory" "store")
1699    (set_attr "mode" "QI")])
1700
1701 (define_insn "*movabsqi_2_rex64"
1702   [(set (match_operand:QI 0 "register_operand" "=a,r")
1703         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1704   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1705   "@
1706    movabs{b}\t{%P1, %0|%0, %P1}
1707    mov{b}\t{%a1, %0|%0, %a1}"
1708   [(set_attr "type" "imov")
1709    (set_attr "modrm" "0,*")
1710    (set_attr "length_address" "8,0")
1711    (set_attr "length_immediate" "0")
1712    (set_attr "memory" "load")
1713    (set_attr "mode" "QI")])
1714
1715 (define_insn "*movdi_extzv_1"
1716   [(set (match_operand:DI 0 "register_operand" "=R")
1717         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1718                          (const_int 8)
1719                          (const_int 8)))]
1720   "TARGET_64BIT"
1721   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1722   [(set_attr "type" "imovx")
1723    (set_attr "mode" "DI")])
1724
1725 (define_insn "*movsi_extzv_1"
1726   [(set (match_operand:SI 0 "register_operand" "=R")
1727         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1728                          (const_int 8)
1729                          (const_int 8)))]
1730   ""
1731   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1732   [(set_attr "type" "imovx")
1733    (set_attr "mode" "SI")])
1734
1735 (define_insn "*movqi_extzv_2"
1736   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1737         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1738                                     (const_int 8)
1739                                     (const_int 8)) 0))]
1740   "!TARGET_64BIT"
1741 {
1742   switch (get_attr_type (insn))
1743     {
1744     case TYPE_IMOVX:
1745       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1746     default:
1747       return "mov{b}\t{%h1, %0|%0, %h1}";
1748     }
1749 }
1750   [(set (attr "type")
1751      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1752                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1753                              (ne (symbol_ref "TARGET_MOVX")
1754                                  (const_int 0))))
1755         (const_string "imovx")
1756         (const_string "imov")))
1757    (set (attr "mode")
1758      (if_then_else (eq_attr "type" "imovx")
1759         (const_string "SI")
1760         (const_string "QI")))])
1761
1762 (define_insn "*movqi_extzv_2_rex64"
1763   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1764         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1765                                     (const_int 8)
1766                                     (const_int 8)) 0))]
1767   "TARGET_64BIT"
1768 {
1769   switch (get_attr_type (insn))
1770     {
1771     case TYPE_IMOVX:
1772       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1773     default:
1774       return "mov{b}\t{%h1, %0|%0, %h1}";
1775     }
1776 }
1777   [(set (attr "type")
1778      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1779                         (ne (symbol_ref "TARGET_MOVX")
1780                             (const_int 0)))
1781         (const_string "imovx")
1782         (const_string "imov")))
1783    (set (attr "mode")
1784      (if_then_else (eq_attr "type" "imovx")
1785         (const_string "SI")
1786         (const_string "QI")))])
1787
1788 (define_insn "movsi_insv_1"
1789   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1790                          (const_int 8)
1791                          (const_int 8))
1792         (match_operand:SI 1 "general_operand" "Qmn"))]
1793   "!TARGET_64BIT"
1794   "mov{b}\t{%b1, %h0|%h0, %b1}"
1795   [(set_attr "type" "imov")
1796    (set_attr "mode" "QI")])
1797
1798 (define_insn "movdi_insv_1_rex64"
1799   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1800                          (const_int 8)
1801                          (const_int 8))
1802         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1803   "TARGET_64BIT"
1804   "mov{b}\t{%b1, %h0|%h0, %b1}"
1805   [(set_attr "type" "imov")
1806    (set_attr "mode" "QI")])
1807
1808 (define_insn "*movqi_insv_2"
1809   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1810                          (const_int 8)
1811                          (const_int 8))
1812         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1813                      (const_int 8)))]
1814   ""
1815   "mov{b}\t{%h1, %h0|%h0, %h1}"
1816   [(set_attr "type" "imov")
1817    (set_attr "mode" "QI")])
1818
1819 (define_expand "movdi"
1820   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1821         (match_operand:DI 1 "general_operand" ""))]
1822   ""
1823   "ix86_expand_move (DImode, operands); DONE;")
1824
1825 (define_insn "*pushdi"
1826   [(set (match_operand:DI 0 "push_operand" "=<")
1827         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1828   "!TARGET_64BIT"
1829   "#")
1830
1831 (define_insn "*pushdi2_rex64"
1832   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1833         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1834   "TARGET_64BIT"
1835   "@
1836    push{q}\t%1
1837    #"
1838   [(set_attr "type" "push,multi")
1839    (set_attr "mode" "DI")])
1840
1841 ;; Convert impossible pushes of immediate to existing instructions.
1842 ;; First try to get scratch register and go through it.  In case this
1843 ;; fails, push sign extended lower part first and then overwrite
1844 ;; upper part by 32bit move.
1845 (define_peephole2
1846   [(match_scratch:DI 2 "r")
1847    (set (match_operand:DI 0 "push_operand" "")
1848         (match_operand:DI 1 "immediate_operand" ""))]
1849   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1850    && !x86_64_immediate_operand (operands[1], DImode)"
1851   [(set (match_dup 2) (match_dup 1))
1852    (set (match_dup 0) (match_dup 2))]
1853   "")
1854
1855 ;; We need to define this as both peepholer and splitter for case
1856 ;; peephole2 pass is not run.
1857 ;; "&& 1" is needed to keep it from matching the previous pattern.
1858 (define_peephole2
1859   [(set (match_operand:DI 0 "push_operand" "")
1860         (match_operand:DI 1 "immediate_operand" ""))]
1861   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1862    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1863   [(set (match_dup 0) (match_dup 1))
1864    (set (match_dup 2) (match_dup 3))]
1865   "split_di (operands + 1, 1, operands + 2, operands + 3);
1866    operands[1] = gen_lowpart (DImode, operands[2]);
1867    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1868                                                     GEN_INT (4)));
1869   ")
1870
1871 (define_split
1872   [(set (match_operand:DI 0 "push_operand" "")
1873         (match_operand:DI 1 "immediate_operand" ""))]
1874   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1875                     ? flow2_completed : reload_completed)
1876    && !symbolic_operand (operands[1], DImode)
1877    && !x86_64_immediate_operand (operands[1], DImode)"
1878   [(set (match_dup 0) (match_dup 1))
1879    (set (match_dup 2) (match_dup 3))]
1880   "split_di (operands + 1, 1, operands + 2, operands + 3);
1881    operands[1] = gen_lowpart (DImode, operands[2]);
1882    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1883                                                     GEN_INT (4)));
1884   ")
1885
1886 (define_insn "*pushdi2_prologue_rex64"
1887   [(set (match_operand:DI 0 "push_operand" "=<")
1888         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1889    (clobber (mem:BLK (scratch)))]
1890   "TARGET_64BIT"
1891   "push{q}\t%1"
1892   [(set_attr "type" "push")
1893    (set_attr "mode" "DI")])
1894
1895 (define_insn "*popdi1_epilogue_rex64"
1896   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1897         (mem:DI (reg:DI SP_REG)))
1898    (set (reg:DI SP_REG)
1899         (plus:DI (reg:DI SP_REG) (const_int 8)))
1900    (clobber (mem:BLK (scratch)))]
1901   "TARGET_64BIT"
1902   "pop{q}\t%0"
1903   [(set_attr "type" "pop")
1904    (set_attr "mode" "DI")])
1905
1906 (define_insn "popdi1"
1907   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1908         (mem:DI (reg:DI SP_REG)))
1909    (set (reg:DI SP_REG)
1910         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1911   "TARGET_64BIT"
1912   "pop{q}\t%0"
1913   [(set_attr "type" "pop")
1914    (set_attr "mode" "DI")])
1915
1916 (define_insn "*movdi_xor_rex64"
1917   [(set (match_operand:DI 0 "register_operand" "=r")
1918         (match_operand:DI 1 "const0_operand" "i"))
1919    (clobber (reg:CC FLAGS_REG))]
1920   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1921    && reload_completed"
1922   "xor{l}\t{%k0, %k0|%k0, %k0}"
1923   [(set_attr "type" "alu1")
1924    (set_attr "mode" "SI")
1925    (set_attr "length_immediate" "0")])
1926
1927 (define_insn "*movdi_or_rex64"
1928   [(set (match_operand:DI 0 "register_operand" "=r")
1929         (match_operand:DI 1 "const_int_operand" "i"))
1930    (clobber (reg:CC FLAGS_REG))]
1931   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1932    && reload_completed
1933    && operands[1] == constm1_rtx"
1934 {
1935   operands[1] = constm1_rtx;
1936   return "or{q}\t{%1, %0|%0, %1}";
1937 }
1938   [(set_attr "type" "alu1")
1939    (set_attr "mode" "DI")
1940    (set_attr "length_immediate" "1")])
1941
1942 (define_insn "*movdi_2"
1943   [(set (match_operand:DI 0 "nonimmediate_operand"
1944                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1945         (match_operand:DI 1 "general_operand"
1946                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1947   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1948   "@
1949    #
1950    #
1951    pxor\t%0, %0
1952    movq\t{%1, %0|%0, %1}
1953    movq\t{%1, %0|%0, %1}
1954    pxor\t%0, %0
1955    movq\t{%1, %0|%0, %1}
1956    movdqa\t{%1, %0|%0, %1}
1957    movq\t{%1, %0|%0, %1}
1958    xorps\t%0, %0
1959    movlps\t{%1, %0|%0, %1}
1960    movaps\t{%1, %0|%0, %1}
1961    movlps\t{%1, %0|%0, %1}"
1962   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1963    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1964
1965 (define_split
1966   [(set (match_operand:DI 0 "push_operand" "")
1967         (match_operand:DI 1 "general_operand" ""))]
1968   "!TARGET_64BIT && reload_completed
1969    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1970   [(const_int 0)]
1971   "ix86_split_long_move (operands); DONE;")
1972
1973 ;; %%% This multiword shite has got to go.
1974 (define_split
1975   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1976         (match_operand:DI 1 "general_operand" ""))]
1977   "!TARGET_64BIT && reload_completed
1978    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1979    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1980   [(const_int 0)]
1981   "ix86_split_long_move (operands); DONE;")
1982
1983 (define_insn "*movdi_1_rex64"
1984   [(set (match_operand:DI 0 "nonimmediate_operand"
1985                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1986         (match_operand:DI 1 "general_operand"
1987                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1988   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1989 {
1990   switch (get_attr_type (insn))
1991     {
1992     case TYPE_SSECVT:
1993       if (which_alternative == 13)
1994         return "movq2dq\t{%1, %0|%0, %1}";
1995       else
1996         return "movdq2q\t{%1, %0|%0, %1}";
1997     case TYPE_SSEMOV:
1998       if (get_attr_mode (insn) == MODE_TI)
1999           return "movdqa\t{%1, %0|%0, %1}";
2000       /* FALLTHRU */
2001     case TYPE_MMXMOV:
2002       /* Moves from and into integer register is done using movd opcode with
2003          REX prefix.  */
2004       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2005           return "movd\t{%1, %0|%0, %1}";
2006       return "movq\t{%1, %0|%0, %1}";
2007     case TYPE_SSELOG1:
2008     case TYPE_MMXADD:
2009       return "pxor\t%0, %0";
2010     case TYPE_MULTI:
2011       return "#";
2012     case TYPE_LEA:
2013       return "lea{q}\t{%a1, %0|%0, %a1}";
2014     default:
2015       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2016       if (get_attr_mode (insn) == MODE_SI)
2017         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2018       else if (which_alternative == 2)
2019         return "movabs{q}\t{%1, %0|%0, %1}";
2020       else
2021         return "mov{q}\t{%1, %0|%0, %1}";
2022     }
2023 }
2024   [(set (attr "type")
2025      (cond [(eq_attr "alternative" "5")
2026               (const_string "mmxadd")
2027             (eq_attr "alternative" "6,7,8")
2028               (const_string "mmxmov")
2029             (eq_attr "alternative" "9")
2030               (const_string "sselog1")
2031             (eq_attr "alternative" "10,11,12")
2032               (const_string "ssemov")
2033             (eq_attr "alternative" "13,14")
2034               (const_string "ssecvt")
2035             (eq_attr "alternative" "4")
2036               (const_string "multi")
2037             (match_operand:DI 1 "pic_32bit_operand" "")
2038               (const_string "lea")
2039            ]
2040            (const_string "imov")))
2041    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2042    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2043    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2044
2045 ;; Stores and loads of ax to arbitrary constant address.
2046 ;; We fake an second form of instruction to force reload to load address
2047 ;; into register when rax is not available
2048 (define_insn "*movabsdi_1_rex64"
2049   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2050         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2051   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2052   "@
2053    movabs{q}\t{%1, %P0|%P0, %1}
2054    mov{q}\t{%1, %a0|%a0, %1}"
2055   [(set_attr "type" "imov")
2056    (set_attr "modrm" "0,*")
2057    (set_attr "length_address" "8,0")
2058    (set_attr "length_immediate" "0,*")
2059    (set_attr "memory" "store")
2060    (set_attr "mode" "DI")])
2061
2062 (define_insn "*movabsdi_2_rex64"
2063   [(set (match_operand:DI 0 "register_operand" "=a,r")
2064         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2065   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2066   "@
2067    movabs{q}\t{%P1, %0|%0, %P1}
2068    mov{q}\t{%a1, %0|%0, %a1}"
2069   [(set_attr "type" "imov")
2070    (set_attr "modrm" "0,*")
2071    (set_attr "length_address" "8,0")
2072    (set_attr "length_immediate" "0")
2073    (set_attr "memory" "load")
2074    (set_attr "mode" "DI")])
2075
2076 ;; Convert impossible stores of immediate to existing instructions.
2077 ;; First try to get scratch register and go through it.  In case this
2078 ;; fails, move by 32bit parts.
2079 (define_peephole2
2080   [(match_scratch:DI 2 "r")
2081    (set (match_operand:DI 0 "memory_operand" "")
2082         (match_operand:DI 1 "immediate_operand" ""))]
2083   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084    && !x86_64_immediate_operand (operands[1], DImode)"
2085   [(set (match_dup 2) (match_dup 1))
2086    (set (match_dup 0) (match_dup 2))]
2087   "")
2088
2089 ;; We need to define this as both peepholer and splitter for case
2090 ;; peephole2 pass is not run.
2091 ;; "&& 1" is needed to keep it from matching the previous pattern.
2092 (define_peephole2
2093   [(set (match_operand:DI 0 "memory_operand" "")
2094         (match_operand:DI 1 "immediate_operand" ""))]
2095   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2096    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2097   [(set (match_dup 2) (match_dup 3))
2098    (set (match_dup 4) (match_dup 5))]
2099   "split_di (operands, 2, operands + 2, operands + 4);")
2100
2101 (define_split
2102   [(set (match_operand:DI 0 "memory_operand" "")
2103         (match_operand:DI 1 "immediate_operand" ""))]
2104   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2105                     ? flow2_completed : reload_completed)
2106    && !symbolic_operand (operands[1], DImode)
2107    && !x86_64_immediate_operand (operands[1], DImode)"
2108   [(set (match_dup 2) (match_dup 3))
2109    (set (match_dup 4) (match_dup 5))]
2110   "split_di (operands, 2, operands + 2, operands + 4);")
2111
2112 (define_insn "*swapdi_rex64"
2113   [(set (match_operand:DI 0 "register_operand" "+r")
2114         (match_operand:DI 1 "register_operand" "+r"))
2115    (set (match_dup 1)
2116         (match_dup 0))]
2117   "TARGET_64BIT"
2118   "xchg{q}\t%1, %0"
2119   [(set_attr "type" "imov")
2120    (set_attr "mode" "DI")
2121    (set_attr "pent_pair" "np")
2122    (set_attr "athlon_decode" "vector")])
2123
2124 (define_expand "movti"
2125   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2126         (match_operand:TI 1 "nonimmediate_operand" ""))]
2127   "TARGET_SSE || TARGET_64BIT"
2128 {
2129   if (TARGET_64BIT)
2130     ix86_expand_move (TImode, operands);
2131   else
2132     ix86_expand_vector_move (TImode, operands);
2133   DONE;
2134 })
2135
2136 (define_insn "*movti_internal"
2137   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2138         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2139   "TARGET_SSE && !TARGET_64BIT
2140    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2141 {
2142   switch (which_alternative)
2143     {
2144     case 0:
2145       if (get_attr_mode (insn) == MODE_V4SF)
2146         return "xorps\t%0, %0";
2147       else
2148         return "pxor\t%0, %0";
2149     case 1:
2150     case 2:
2151       if (get_attr_mode (insn) == MODE_V4SF)
2152         return "movaps\t{%1, %0|%0, %1}";
2153       else
2154         return "movdqa\t{%1, %0|%0, %1}";
2155     default:
2156       gcc_unreachable ();
2157     }
2158 }
2159   [(set_attr "type" "sselog1,ssemov,ssemov")
2160    (set (attr "mode")
2161         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2162                     (ne (symbol_ref "optimize_size") (const_int 0)))
2163                  (const_string "V4SF")
2164                (and (eq_attr "alternative" "2")
2165                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2166                         (const_int 0)))
2167                  (const_string "V4SF")]
2168               (const_string "TI")))])
2169
2170 (define_insn "*movti_rex64"
2171   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2172         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2173   "TARGET_64BIT
2174    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2175 {
2176   switch (which_alternative)
2177     {
2178     case 0:
2179     case 1:
2180       return "#";
2181     case 2:
2182       if (get_attr_mode (insn) == MODE_V4SF)
2183         return "xorps\t%0, %0";
2184       else
2185         return "pxor\t%0, %0";
2186     case 3:
2187     case 4:
2188       if (get_attr_mode (insn) == MODE_V4SF)
2189         return "movaps\t{%1, %0|%0, %1}";
2190       else
2191         return "movdqa\t{%1, %0|%0, %1}";
2192     default:
2193       gcc_unreachable ();
2194     }
2195 }
2196   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2197    (set (attr "mode")
2198         (cond [(eq_attr "alternative" "2,3")
2199                  (if_then_else
2200                    (ne (symbol_ref "optimize_size")
2201                        (const_int 0))
2202                    (const_string "V4SF")
2203                    (const_string "TI"))
2204                (eq_attr "alternative" "4")
2205                  (if_then_else
2206                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2207                             (const_int 0))
2208                         (ne (symbol_ref "optimize_size")
2209                             (const_int 0)))
2210                    (const_string "V4SF")
2211                    (const_string "TI"))]
2212                (const_string "DI")))])
2213
2214 (define_split
2215   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2216         (match_operand:TI 1 "general_operand" ""))]
2217   "reload_completed && !SSE_REG_P (operands[0])
2218    && !SSE_REG_P (operands[1])"
2219   [(const_int 0)]
2220   "ix86_split_long_move (operands); DONE;")
2221
2222 (define_expand "movsf"
2223   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2224         (match_operand:SF 1 "general_operand" ""))]
2225   ""
2226   "ix86_expand_move (SFmode, operands); DONE;")
2227
2228 (define_insn "*pushsf"
2229   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2230         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2231   "!TARGET_64BIT"
2232 {
2233   /* Anything else should be already split before reg-stack.  */
2234   gcc_assert (which_alternative == 1);
2235   return "push{l}\t%1";
2236 }
2237   [(set_attr "type" "multi,push,multi")
2238    (set_attr "unit" "i387,*,*")
2239    (set_attr "mode" "SF,SI,SF")])
2240
2241 (define_insn "*pushsf_rex64"
2242   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2243         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2244   "TARGET_64BIT"
2245 {
2246   /* Anything else should be already split before reg-stack.  */
2247   gcc_assert (which_alternative == 1);
2248   return "push{q}\t%q1";
2249 }
2250   [(set_attr "type" "multi,push,multi")
2251    (set_attr "unit" "i387,*,*")
2252    (set_attr "mode" "SF,DI,SF")])
2253
2254 (define_split
2255   [(set (match_operand:SF 0 "push_operand" "")
2256         (match_operand:SF 1 "memory_operand" ""))]
2257   "reload_completed
2258    && GET_CODE (operands[1]) == MEM
2259    && constant_pool_reference_p (operands[1])"
2260   [(set (match_dup 0)
2261         (match_dup 1))]
2262   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2263
2264
2265 ;; %%% Kill this when call knows how to work this out.
2266 (define_split
2267   [(set (match_operand:SF 0 "push_operand" "")
2268         (match_operand:SF 1 "any_fp_register_operand" ""))]
2269   "!TARGET_64BIT"
2270   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2271    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2272
2273 (define_split
2274   [(set (match_operand:SF 0 "push_operand" "")
2275         (match_operand:SF 1 "any_fp_register_operand" ""))]
2276   "TARGET_64BIT"
2277   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2278    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2279
2280 (define_insn "*movsf_1"
2281   [(set (match_operand:SF 0 "nonimmediate_operand"
2282           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2283         (match_operand:SF 1 "general_operand"
2284           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2285   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2286    && (reload_in_progress || reload_completed
2287        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288        || GET_CODE (operands[1]) != CONST_DOUBLE
2289        || memory_operand (operands[0], SFmode))" 
2290 {
2291   switch (which_alternative)
2292     {
2293     case 0:
2294       return output_387_reg_move (insn, operands);
2295
2296     case 1:
2297       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298         return "fstp%z0\t%y0";
2299       else
2300         return "fst%z0\t%y0";
2301
2302     case 2:
2303       return standard_80387_constant_opcode (operands[1]);
2304
2305     case 3:
2306     case 4:
2307       return "mov{l}\t{%1, %0|%0, %1}";
2308     case 5:
2309       if (get_attr_mode (insn) == MODE_TI)
2310         return "pxor\t%0, %0";
2311       else
2312         return "xorps\t%0, %0";
2313     case 6:
2314       if (get_attr_mode (insn) == MODE_V4SF)
2315         return "movaps\t{%1, %0|%0, %1}";
2316       else
2317         return "movss\t{%1, %0|%0, %1}";
2318     case 7:
2319     case 8:
2320       return "movss\t{%1, %0|%0, %1}";
2321
2322     case 9:
2323     case 10:
2324       return "movd\t{%1, %0|%0, %1}";
2325
2326     case 11:
2327       return "movq\t{%1, %0|%0, %1}";
2328
2329     default:
2330       gcc_unreachable ();
2331     }
2332 }
2333   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334    (set (attr "mode")
2335         (cond [(eq_attr "alternative" "3,4,9,10")
2336                  (const_string "SI")
2337                (eq_attr "alternative" "5")
2338                  (if_then_else
2339                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340                                  (const_int 0))
2341                              (ne (symbol_ref "TARGET_SSE2")
2342                                  (const_int 0)))
2343                         (eq (symbol_ref "optimize_size")
2344                             (const_int 0)))
2345                    (const_string "TI")
2346                    (const_string "V4SF"))
2347                /* For architectures resolving dependencies on
2348                   whole SSE registers use APS move to break dependency
2349                   chains, otherwise use short move to avoid extra work. 
2350
2351                   Do the same for architectures resolving dependencies on
2352                   the parts.  While in DF mode it is better to always handle
2353                   just register parts, the SF mode is different due to lack
2354                   of instructions to load just part of the register.  It is
2355                   better to maintain the whole registers in single format
2356                   to avoid problems on using packed logical operations.  */
2357                (eq_attr "alternative" "6")
2358                  (if_then_else
2359                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360                             (const_int 0))
2361                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2362                             (const_int 0)))
2363                    (const_string "V4SF")
2364                    (const_string "SF"))
2365                (eq_attr "alternative" "11")
2366                  (const_string "DI")]
2367                (const_string "SF")))])
2368
2369 (define_insn "*swapsf"
2370   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2371         (match_operand:SF 1 "fp_register_operand" "+f"))
2372    (set (match_dup 1)
2373         (match_dup 0))]
2374   "reload_completed || TARGET_80387"
2375 {
2376   if (STACK_TOP_P (operands[0]))
2377     return "fxch\t%1";
2378   else
2379     return "fxch\t%0";
2380 }
2381   [(set_attr "type" "fxch")
2382    (set_attr "mode" "SF")])
2383
2384 (define_expand "movdf"
2385   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386         (match_operand:DF 1 "general_operand" ""))]
2387   ""
2388   "ix86_expand_move (DFmode, operands); DONE;")
2389
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter.  Allow this
2393 ;; pattern for optimize_size too.
2394
2395 (define_insn "*pushdf_nointeger"
2396   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2398   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2399 {
2400   /* This insn should be already split before reg-stack.  */
2401   gcc_unreachable ();
2402 }
2403   [(set_attr "type" "multi")
2404    (set_attr "unit" "i387,*,*,*")
2405    (set_attr "mode" "DF,SI,SI,DF")])
2406
2407 (define_insn "*pushdf_integer"
2408   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2409         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2410   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2411 {
2412   /* This insn should be already split before reg-stack.  */
2413   gcc_unreachable ();
2414 }
2415   [(set_attr "type" "multi")
2416    (set_attr "unit" "i387,*,*")
2417    (set_attr "mode" "DF,SI,DF")])
2418
2419 ;; %%% Kill this when call knows how to work this out.
2420 (define_split
2421   [(set (match_operand:DF 0 "push_operand" "")
2422         (match_operand:DF 1 "any_fp_register_operand" ""))]
2423   "!TARGET_64BIT && reload_completed"
2424   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2425    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2426   "")
2427
2428 (define_split
2429   [(set (match_operand:DF 0 "push_operand" "")
2430         (match_operand:DF 1 "any_fp_register_operand" ""))]
2431   "TARGET_64BIT && reload_completed"
2432   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2433    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2434   "")
2435
2436 (define_split
2437   [(set (match_operand:DF 0 "push_operand" "")
2438         (match_operand:DF 1 "general_operand" ""))]
2439   "reload_completed"
2440   [(const_int 0)]
2441   "ix86_split_long_move (operands); DONE;")
2442
2443 ;; Moving is usually shorter when only FP registers are used. This separate
2444 ;; movdf pattern avoids the use of integer registers for FP operations
2445 ;; when optimizing for size.
2446
2447 (define_insn "*movdf_nointeger"
2448   [(set (match_operand:DF 0 "nonimmediate_operand"
2449                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2450         (match_operand:DF 1 "general_operand"
2451                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2452   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2453    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2454    && (reload_in_progress || reload_completed
2455        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2456        || GET_CODE (operands[1]) != CONST_DOUBLE
2457        || memory_operand (operands[0], DFmode))" 
2458 {
2459   switch (which_alternative)
2460     {
2461     case 0:
2462       return output_387_reg_move (insn, operands);
2463
2464     case 1:
2465       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2466         return "fstp%z0\t%y0";
2467       else
2468         return "fst%z0\t%y0";
2469
2470     case 2:
2471       return standard_80387_constant_opcode (operands[1]);
2472
2473     case 3:
2474     case 4:
2475       return "#";
2476     case 5:
2477       switch (get_attr_mode (insn))
2478         {
2479         case MODE_V4SF:
2480           return "xorps\t%0, %0";
2481         case MODE_V2DF:
2482           return "xorpd\t%0, %0";
2483         case MODE_TI:
2484           return "pxor\t%0, %0";
2485         default:
2486           gcc_unreachable ();
2487         }
2488     case 6:
2489     case 7:
2490     case 8:
2491       switch (get_attr_mode (insn))
2492         {
2493         case MODE_V4SF:
2494           return "movaps\t{%1, %0|%0, %1}";
2495         case MODE_V2DF:
2496           return "movapd\t{%1, %0|%0, %1}";
2497         case MODE_TI:
2498           return "movdqa\t{%1, %0|%0, %1}";
2499         case MODE_DI:
2500           return "movq\t{%1, %0|%0, %1}";
2501         case MODE_DF:
2502           return "movsd\t{%1, %0|%0, %1}";
2503         case MODE_V1DF:
2504           return "movlpd\t{%1, %0|%0, %1}";
2505         case MODE_V2SF:
2506           return "movlps\t{%1, %0|%0, %1}";
2507         default:
2508           gcc_unreachable ();
2509         }
2510
2511     default:
2512       gcc_unreachable ();
2513     }
2514 }
2515   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2516    (set (attr "mode")
2517         (cond [(eq_attr "alternative" "0,1,2")
2518                  (const_string "DF")
2519                (eq_attr "alternative" "3,4")
2520                  (const_string "SI")
2521
2522                /* For SSE1, we have many fewer alternatives.  */
2523                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2524                  (cond [(eq_attr "alternative" "5,6")
2525                           (const_string "V4SF")
2526                        ]
2527                    (const_string "V2SF"))
2528
2529                /* xorps is one byte shorter.  */
2530                (eq_attr "alternative" "5")
2531                  (cond [(ne (symbol_ref "optimize_size")
2532                             (const_int 0))
2533                           (const_string "V4SF")
2534                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2535                             (const_int 0))
2536                           (const_string "TI")
2537                        ]
2538                        (const_string "V2DF"))
2539
2540                /* For architectures resolving dependencies on
2541                   whole SSE registers use APD move to break dependency
2542                   chains, otherwise use short move to avoid extra work.
2543
2544                   movaps encodes one byte shorter.  */
2545                (eq_attr "alternative" "6")
2546                  (cond
2547                    [(ne (symbol_ref "optimize_size")
2548                         (const_int 0))
2549                       (const_string "V4SF")
2550                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2551                         (const_int 0))
2552                       (const_string "V2DF")
2553                    ]
2554                    (const_string "DF"))
2555                /* For architectures resolving dependencies on register
2556                   parts we may avoid extra work to zero out upper part
2557                   of register.  */
2558                (eq_attr "alternative" "7")
2559                  (if_then_else
2560                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2561                        (const_int 0))
2562                    (const_string "V1DF")
2563                    (const_string "DF"))
2564               ]
2565               (const_string "DF")))])
2566
2567 (define_insn "*movdf_integer"
2568   [(set (match_operand:DF 0 "nonimmediate_operand"
2569                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2570         (match_operand:DF 1 "general_operand"
2571                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2572   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2573    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2574    && (reload_in_progress || reload_completed
2575        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2576        || GET_CODE (operands[1]) != CONST_DOUBLE
2577        || memory_operand (operands[0], DFmode))" 
2578 {
2579   switch (which_alternative)
2580     {
2581     case 0:
2582       return output_387_reg_move (insn, operands);
2583
2584     case 1:
2585       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2586         return "fstp%z0\t%y0";
2587       else
2588         return "fst%z0\t%y0";
2589
2590     case 2:
2591       return standard_80387_constant_opcode (operands[1]);
2592
2593     case 3:
2594     case 4:
2595       return "#";
2596
2597     case 5:
2598       switch (get_attr_mode (insn))
2599         {
2600         case MODE_V4SF:
2601           return "xorps\t%0, %0";
2602         case MODE_V2DF:
2603           return "xorpd\t%0, %0";
2604         case MODE_TI:
2605           return "pxor\t%0, %0";
2606         default:
2607           gcc_unreachable ();
2608         }
2609     case 6:
2610     case 7:
2611     case 8:
2612       switch (get_attr_mode (insn))
2613         {
2614         case MODE_V4SF:
2615           return "movaps\t{%1, %0|%0, %1}";
2616         case MODE_V2DF:
2617           return "movapd\t{%1, %0|%0, %1}";
2618         case MODE_TI:
2619           return "movdqa\t{%1, %0|%0, %1}";
2620         case MODE_DI:
2621           return "movq\t{%1, %0|%0, %1}";
2622         case MODE_DF:
2623           return "movsd\t{%1, %0|%0, %1}";
2624         case MODE_V1DF:
2625           return "movlpd\t{%1, %0|%0, %1}";
2626         case MODE_V2SF:
2627           return "movlps\t{%1, %0|%0, %1}";
2628         default:
2629           gcc_unreachable ();
2630         }
2631
2632     default:
2633       gcc_unreachable();
2634     }
2635 }
2636   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2637    (set (attr "mode")
2638         (cond [(eq_attr "alternative" "0,1,2")
2639                  (const_string "DF")
2640                (eq_attr "alternative" "3,4")
2641                  (const_string "SI")
2642
2643                /* For SSE1, we have many fewer alternatives.  */
2644                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2645                  (cond [(eq_attr "alternative" "5,6")
2646                           (const_string "V4SF")
2647                        ]
2648                    (const_string "V2SF"))
2649
2650                /* xorps is one byte shorter.  */
2651                (eq_attr "alternative" "5")
2652                  (cond [(ne (symbol_ref "optimize_size")
2653                             (const_int 0))
2654                           (const_string "V4SF")
2655                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2656                             (const_int 0))
2657                           (const_string "TI")
2658                        ]
2659                        (const_string "V2DF"))
2660
2661                /* For architectures resolving dependencies on
2662                   whole SSE registers use APD move to break dependency
2663                   chains, otherwise use short move to avoid extra work.
2664
2665                   movaps encodes one byte shorter.  */
2666                (eq_attr "alternative" "6")
2667                  (cond
2668                    [(ne (symbol_ref "optimize_size")
2669                         (const_int 0))
2670                       (const_string "V4SF")
2671                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2672                         (const_int 0))
2673                       (const_string "V2DF")
2674                    ]
2675                    (const_string "DF"))
2676                /* For architectures resolving dependencies on register
2677                   parts we may avoid extra work to zero out upper part
2678                   of register.  */
2679                (eq_attr "alternative" "7")
2680                  (if_then_else
2681                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2682                        (const_int 0))
2683                    (const_string "V1DF")
2684                    (const_string "DF"))
2685               ]
2686               (const_string "DF")))])
2687
2688 (define_split
2689   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2690         (match_operand:DF 1 "general_operand" ""))]
2691   "reload_completed
2692    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2693    && ! (ANY_FP_REG_P (operands[0]) || 
2694          (GET_CODE (operands[0]) == SUBREG
2695           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2696    && ! (ANY_FP_REG_P (operands[1]) || 
2697          (GET_CODE (operands[1]) == SUBREG
2698           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2699   [(const_int 0)]
2700   "ix86_split_long_move (operands); DONE;")
2701
2702 (define_insn "*swapdf"
2703   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2704         (match_operand:DF 1 "fp_register_operand" "+f"))
2705    (set (match_dup 1)
2706         (match_dup 0))]
2707   "reload_completed || TARGET_80387"
2708 {
2709   if (STACK_TOP_P (operands[0]))
2710     return "fxch\t%1";
2711   else
2712     return "fxch\t%0";
2713 }
2714   [(set_attr "type" "fxch")
2715    (set_attr "mode" "DF")])
2716
2717 (define_expand "movxf"
2718   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2719         (match_operand:XF 1 "general_operand" ""))]
2720   ""
2721   "ix86_expand_move (XFmode, operands); DONE;")
2722
2723 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2724 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2725 ;; Pushing using integer instructions is longer except for constants
2726 ;; and direct memory references.
2727 ;; (assuming that any given constant is pushed only once, but this ought to be
2728 ;;  handled elsewhere).
2729
2730 (define_insn "*pushxf_nointeger"
2731   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2732         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2733   "optimize_size"
2734 {
2735   /* This insn should be already split before reg-stack.  */
2736   gcc_unreachable ();
2737 }
2738   [(set_attr "type" "multi")
2739    (set_attr "unit" "i387,*,*")
2740    (set_attr "mode" "XF,SI,SI")])
2741
2742 (define_insn "*pushxf_integer"
2743   [(set (match_operand:XF 0 "push_operand" "=<,<")
2744         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2745   "!optimize_size"
2746 {
2747   /* This insn should be already split before reg-stack.  */
2748   gcc_unreachable ();
2749 }
2750   [(set_attr "type" "multi")
2751    (set_attr "unit" "i387,*")
2752    (set_attr "mode" "XF,SI")])
2753
2754 (define_split
2755   [(set (match_operand 0 "push_operand" "")
2756         (match_operand 1 "general_operand" ""))]
2757   "reload_completed
2758    && (GET_MODE (operands[0]) == XFmode
2759        || GET_MODE (operands[0]) == DFmode)
2760    && !ANY_FP_REG_P (operands[1])"
2761   [(const_int 0)]
2762   "ix86_split_long_move (operands); DONE;")
2763
2764 (define_split
2765   [(set (match_operand:XF 0 "push_operand" "")
2766         (match_operand:XF 1 "any_fp_register_operand" ""))]
2767   "!TARGET_64BIT"
2768   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2769    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2770   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2771
2772 (define_split
2773   [(set (match_operand:XF 0 "push_operand" "")
2774         (match_operand:XF 1 "any_fp_register_operand" ""))]
2775   "TARGET_64BIT"
2776   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2777    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2778   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2779
2780 ;; Do not use integer registers when optimizing for size
2781 (define_insn "*movxf_nointeger"
2782   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2783         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2784   "optimize_size
2785    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2786    && (reload_in_progress || reload_completed
2787        || GET_CODE (operands[1]) != CONST_DOUBLE
2788        || memory_operand (operands[0], XFmode))" 
2789 {
2790   switch (which_alternative)
2791     {
2792     case 0:
2793       return output_387_reg_move (insn, operands);
2794
2795     case 1:
2796       /* There is no non-popping store to memory for XFmode.  So if
2797          we need one, follow the store with a load.  */
2798       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2799         return "fstp%z0\t%y0\;fld%z0\t%y0";
2800       else
2801         return "fstp%z0\t%y0";
2802
2803     case 2:
2804       return standard_80387_constant_opcode (operands[1]);
2805
2806     case 3: case 4:
2807       return "#";
2808     default:
2809       gcc_unreachable ();
2810     }
2811 }
2812   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2813    (set_attr "mode" "XF,XF,XF,SI,SI")])
2814
2815 (define_insn "*movxf_integer"
2816   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2817         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2818   "!optimize_size
2819    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2820    && (reload_in_progress || reload_completed
2821        || GET_CODE (operands[1]) != CONST_DOUBLE
2822        || memory_operand (operands[0], XFmode))" 
2823 {
2824   switch (which_alternative)
2825     {
2826     case 0:
2827       return output_387_reg_move (insn, operands);
2828
2829     case 1:
2830       /* There is no non-popping store to memory for XFmode.  So if
2831          we need one, follow the store with a load.  */
2832       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2833         return "fstp%z0\t%y0\;fld%z0\t%y0";
2834       else
2835         return "fstp%z0\t%y0";
2836
2837     case 2:
2838       return standard_80387_constant_opcode (operands[1]);
2839
2840     case 3: case 4:
2841       return "#";
2842
2843     default:
2844       gcc_unreachable ();
2845     }
2846 }
2847   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2848    (set_attr "mode" "XF,XF,XF,SI,SI")])
2849
2850 (define_split
2851   [(set (match_operand 0 "nonimmediate_operand" "")
2852         (match_operand 1 "general_operand" ""))]
2853   "reload_completed
2854    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2855    && GET_MODE (operands[0]) == XFmode
2856    && ! (ANY_FP_REG_P (operands[0]) || 
2857          (GET_CODE (operands[0]) == SUBREG
2858           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2859    && ! (ANY_FP_REG_P (operands[1]) || 
2860          (GET_CODE (operands[1]) == SUBREG
2861           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2862   [(const_int 0)]
2863   "ix86_split_long_move (operands); DONE;")
2864
2865 (define_split
2866   [(set (match_operand 0 "register_operand" "")
2867         (match_operand 1 "memory_operand" ""))]
2868   "reload_completed
2869    && GET_CODE (operands[1]) == MEM
2870    && (GET_MODE (operands[0]) == XFmode
2871        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2872    && constant_pool_reference_p (operands[1])"
2873   [(set (match_dup 0) (match_dup 1))]
2874 {
2875   rtx c = avoid_constant_pool_reference (operands[1]);
2876   rtx r = operands[0];
2877
2878   if (GET_CODE (r) == SUBREG)
2879     r = SUBREG_REG (r);
2880
2881   if (SSE_REG_P (r))
2882     {
2883       if (!standard_sse_constant_p (c))
2884         FAIL;
2885     }
2886   else if (FP_REG_P (r))
2887     {
2888       if (!standard_80387_constant_p (c))
2889         FAIL;
2890     }
2891   else if (MMX_REG_P (r))
2892     FAIL;
2893
2894   operands[1] = c;
2895 })
2896
2897 (define_insn "swapxf"
2898   [(set (match_operand:XF 0 "register_operand" "+f")
2899         (match_operand:XF 1 "register_operand" "+f"))
2900    (set (match_dup 1)
2901         (match_dup 0))]
2902   "TARGET_80387"
2903 {
2904   if (STACK_TOP_P (operands[0]))
2905     return "fxch\t%1";
2906   else
2907     return "fxch\t%0";
2908 }
2909   [(set_attr "type" "fxch")
2910    (set_attr "mode" "XF")])
2911
2912 (define_expand "movtf"
2913   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2914         (match_operand:TF 1 "nonimmediate_operand" ""))]
2915   "TARGET_64BIT"
2916 {
2917   ix86_expand_move (TFmode, operands);
2918   DONE;
2919 })
2920
2921 (define_insn "*movtf_internal"
2922   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2923         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2924   "TARGET_64BIT
2925    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2926 {
2927   switch (which_alternative)
2928     {
2929     case 0:
2930     case 1:
2931       return "#";
2932     case 2:
2933       if (get_attr_mode (insn) == MODE_V4SF)
2934         return "xorps\t%0, %0";
2935       else
2936         return "pxor\t%0, %0";
2937     case 3:
2938     case 4:
2939       if (get_attr_mode (insn) == MODE_V4SF)
2940         return "movaps\t{%1, %0|%0, %1}";
2941       else
2942         return "movdqa\t{%1, %0|%0, %1}";
2943     default:
2944       gcc_unreachable ();
2945     }
2946 }
2947   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2948    (set (attr "mode")
2949         (cond [(eq_attr "alternative" "2,3")
2950                  (if_then_else
2951                    (ne (symbol_ref "optimize_size")
2952                        (const_int 0))
2953                    (const_string "V4SF")
2954                    (const_string "TI"))
2955                (eq_attr "alternative" "4")
2956                  (if_then_else
2957                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2958                             (const_int 0))
2959                         (ne (symbol_ref "optimize_size")
2960                             (const_int 0)))
2961                    (const_string "V4SF")
2962                    (const_string "TI"))]
2963                (const_string "DI")))])
2964
2965 (define_split
2966   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2967         (match_operand:TF 1 "general_operand" ""))]
2968   "reload_completed && !SSE_REG_P (operands[0])
2969    && !SSE_REG_P (operands[1])"
2970   [(const_int 0)]
2971   "ix86_split_long_move (operands); DONE;")
2972 \f
2973 ;; Zero extension instructions
2974
2975 (define_expand "zero_extendhisi2"
2976   [(set (match_operand:SI 0 "register_operand" "")
2977      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2978   ""
2979 {
2980   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2981     {
2982       operands[1] = force_reg (HImode, operands[1]);
2983       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2984       DONE;
2985     }
2986 })
2987
2988 (define_insn "zero_extendhisi2_and"
2989   [(set (match_operand:SI 0 "register_operand" "=r")
2990      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2991    (clobber (reg:CC FLAGS_REG))]
2992   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2993   "#"
2994   [(set_attr "type" "alu1")
2995    (set_attr "mode" "SI")])
2996
2997 (define_split
2998   [(set (match_operand:SI 0 "register_operand" "")
2999         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3000    (clobber (reg:CC FLAGS_REG))]
3001   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3002   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3003               (clobber (reg:CC FLAGS_REG))])]
3004   "")
3005
3006 (define_insn "*zero_extendhisi2_movzwl"
3007   [(set (match_operand:SI 0 "register_operand" "=r")
3008      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3009   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3010   "movz{wl|x}\t{%1, %0|%0, %1}"
3011   [(set_attr "type" "imovx")
3012    (set_attr "mode" "SI")])
3013
3014 (define_expand "zero_extendqihi2"
3015   [(parallel
3016     [(set (match_operand:HI 0 "register_operand" "")
3017        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3018      (clobber (reg:CC FLAGS_REG))])]
3019   ""
3020   "")
3021
3022 (define_insn "*zero_extendqihi2_and"
3023   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3024      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3025    (clobber (reg:CC FLAGS_REG))]
3026   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3027   "#"
3028   [(set_attr "type" "alu1")
3029    (set_attr "mode" "HI")])
3030
3031 (define_insn "*zero_extendqihi2_movzbw_and"
3032   [(set (match_operand:HI 0 "register_operand" "=r,r")
3033      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3034    (clobber (reg:CC FLAGS_REG))]
3035   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3036   "#"
3037   [(set_attr "type" "imovx,alu1")
3038    (set_attr "mode" "HI")])
3039
3040 ; zero extend to SImode here to avoid partial register stalls
3041 (define_insn "*zero_extendqihi2_movzbl"
3042   [(set (match_operand:HI 0 "register_operand" "=r")
3043      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3044   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3045   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3046   [(set_attr "type" "imovx")
3047    (set_attr "mode" "SI")])
3048
3049 ;; For the movzbw case strip only the clobber
3050 (define_split
3051   [(set (match_operand:HI 0 "register_operand" "")
3052         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3053    (clobber (reg:CC FLAGS_REG))]
3054   "reload_completed 
3055    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3056    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3057   [(set (match_operand:HI 0 "register_operand" "")
3058         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3059
3060 ;; When source and destination does not overlap, clear destination
3061 ;; first and then do the movb
3062 (define_split
3063   [(set (match_operand:HI 0 "register_operand" "")
3064         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3065    (clobber (reg:CC FLAGS_REG))]
3066   "reload_completed
3067    && ANY_QI_REG_P (operands[0])
3068    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3069    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3070   [(set (match_dup 0) (const_int 0))
3071    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3072   "operands[2] = gen_lowpart (QImode, operands[0]);")
3073
3074 ;; Rest is handled by single and.
3075 (define_split
3076   [(set (match_operand:HI 0 "register_operand" "")
3077         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3078    (clobber (reg:CC FLAGS_REG))]
3079   "reload_completed
3080    && true_regnum (operands[0]) == true_regnum (operands[1])"
3081   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3082               (clobber (reg:CC FLAGS_REG))])]
3083   "")
3084
3085 (define_expand "zero_extendqisi2"
3086   [(parallel
3087     [(set (match_operand:SI 0 "register_operand" "")
3088        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3089      (clobber (reg:CC FLAGS_REG))])]
3090   ""
3091   "")
3092
3093 (define_insn "*zero_extendqisi2_and"
3094   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3095      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3096    (clobber (reg:CC FLAGS_REG))]
3097   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3098   "#"
3099   [(set_attr "type" "alu1")
3100    (set_attr "mode" "SI")])
3101
3102 (define_insn "*zero_extendqisi2_movzbw_and"
3103   [(set (match_operand:SI 0 "register_operand" "=r,r")
3104      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3105    (clobber (reg:CC FLAGS_REG))]
3106   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3107   "#"
3108   [(set_attr "type" "imovx,alu1")
3109    (set_attr "mode" "SI")])
3110
3111 (define_insn "*zero_extendqisi2_movzbw"
3112   [(set (match_operand:SI 0 "register_operand" "=r")
3113      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3114   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3115   "movz{bl|x}\t{%1, %0|%0, %1}"
3116   [(set_attr "type" "imovx")
3117    (set_attr "mode" "SI")])
3118
3119 ;; For the movzbl case strip only the clobber
3120 (define_split
3121   [(set (match_operand:SI 0 "register_operand" "")
3122         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3123    (clobber (reg:CC FLAGS_REG))]
3124   "reload_completed 
3125    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3126    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3127   [(set (match_dup 0)
3128         (zero_extend:SI (match_dup 1)))])
3129
3130 ;; When source and destination does not overlap, clear destination
3131 ;; first and then do the movb
3132 (define_split
3133   [(set (match_operand:SI 0 "register_operand" "")
3134         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3135    (clobber (reg:CC FLAGS_REG))]
3136   "reload_completed
3137    && ANY_QI_REG_P (operands[0])
3138    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3139    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3140    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3141   [(set (match_dup 0) (const_int 0))
3142    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3143   "operands[2] = gen_lowpart (QImode, operands[0]);")
3144
3145 ;; Rest is handled by single and.
3146 (define_split
3147   [(set (match_operand:SI 0 "register_operand" "")
3148         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3149    (clobber (reg:CC FLAGS_REG))]
3150   "reload_completed
3151    && true_regnum (operands[0]) == true_regnum (operands[1])"
3152   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3153               (clobber (reg:CC FLAGS_REG))])]
3154   "")
3155
3156 ;; %%% Kill me once multi-word ops are sane.
3157 (define_expand "zero_extendsidi2"
3158   [(set (match_operand:DI 0 "register_operand" "=r")
3159      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3160   ""
3161   "if (!TARGET_64BIT)
3162      {
3163        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3164        DONE;
3165      }
3166   ")
3167
3168 (define_insn "zero_extendsidi2_32"
3169   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3170         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3171    (clobber (reg:CC FLAGS_REG))]
3172   "!TARGET_64BIT"
3173   "@
3174    #
3175    #
3176    #
3177    movd\t{%1, %0|%0, %1}
3178    movd\t{%1, %0|%0, %1}"
3179   [(set_attr "mode" "SI,SI,SI,DI,TI")
3180    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3181
3182 (define_insn "zero_extendsidi2_rex64"
3183   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3184      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3185   "TARGET_64BIT"
3186   "@
3187    mov\t{%k1, %k0|%k0, %k1}
3188    #
3189    movd\t{%1, %0|%0, %1}
3190    movd\t{%1, %0|%0, %1}"
3191   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3192    (set_attr "mode" "SI,DI,SI,SI")])
3193
3194 (define_split
3195   [(set (match_operand:DI 0 "memory_operand" "")
3196      (zero_extend:DI (match_dup 0)))]
3197   "TARGET_64BIT"
3198   [(set (match_dup 4) (const_int 0))]
3199   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3200
3201 (define_split 
3202   [(set (match_operand:DI 0 "register_operand" "")
3203         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3204    (clobber (reg:CC FLAGS_REG))]
3205   "!TARGET_64BIT && reload_completed
3206    && true_regnum (operands[0]) == true_regnum (operands[1])"
3207   [(set (match_dup 4) (const_int 0))]
3208   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3209
3210 (define_split 
3211   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3212         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3213    (clobber (reg:CC FLAGS_REG))]
3214   "!TARGET_64BIT && reload_completed
3215    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3216   [(set (match_dup 3) (match_dup 1))
3217    (set (match_dup 4) (const_int 0))]
3218   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3219
3220 (define_insn "zero_extendhidi2"
3221   [(set (match_operand:DI 0 "register_operand" "=r")
3222      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3223   "TARGET_64BIT"
3224   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3225   [(set_attr "type" "imovx")
3226    (set_attr "mode" "DI")])
3227
3228 (define_insn "zero_extendqidi2"
3229   [(set (match_operand:DI 0 "register_operand" "=r")
3230      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3231   "TARGET_64BIT"
3232   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3233   [(set_attr "type" "imovx")
3234    (set_attr "mode" "DI")])
3235 \f
3236 ;; Sign extension instructions
3237
3238 (define_expand "extendsidi2"
3239   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3240                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3241               (clobber (reg:CC FLAGS_REG))
3242               (clobber (match_scratch:SI 2 ""))])]
3243   ""
3244 {
3245   if (TARGET_64BIT)
3246     {
3247       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3248       DONE;
3249     }
3250 })
3251
3252 (define_insn "*extendsidi2_1"
3253   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3254         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3255    (clobber (reg:CC FLAGS_REG))
3256    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3257   "!TARGET_64BIT"
3258   "#")
3259
3260 (define_insn "extendsidi2_rex64"
3261   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3262         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3263   "TARGET_64BIT"
3264   "@
3265    {cltq|cdqe}
3266    movs{lq|x}\t{%1,%0|%0, %1}"
3267   [(set_attr "type" "imovx")
3268    (set_attr "mode" "DI")
3269    (set_attr "prefix_0f" "0")
3270    (set_attr "modrm" "0,1")])
3271
3272 (define_insn "extendhidi2"
3273   [(set (match_operand:DI 0 "register_operand" "=r")
3274         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3275   "TARGET_64BIT"
3276   "movs{wq|x}\t{%1,%0|%0, %1}"
3277   [(set_attr "type" "imovx")
3278    (set_attr "mode" "DI")])
3279
3280 (define_insn "extendqidi2"
3281   [(set (match_operand:DI 0 "register_operand" "=r")
3282         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3283   "TARGET_64BIT"
3284   "movs{bq|x}\t{%1,%0|%0, %1}"
3285    [(set_attr "type" "imovx")
3286     (set_attr "mode" "DI")])
3287
3288 ;; Extend to memory case when source register does die.
3289 (define_split 
3290   [(set (match_operand:DI 0 "memory_operand" "")
3291         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3292    (clobber (reg:CC FLAGS_REG))
3293    (clobber (match_operand:SI 2 "register_operand" ""))]
3294   "(reload_completed
3295     && dead_or_set_p (insn, operands[1])
3296     && !reg_mentioned_p (operands[1], operands[0]))"
3297   [(set (match_dup 3) (match_dup 1))
3298    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3299               (clobber (reg:CC FLAGS_REG))])
3300    (set (match_dup 4) (match_dup 1))]
3301   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3302
3303 ;; Extend to memory case when source register does not die.
3304 (define_split 
3305   [(set (match_operand:DI 0 "memory_operand" "")
3306         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3307    (clobber (reg:CC FLAGS_REG))
3308    (clobber (match_operand:SI 2 "register_operand" ""))]
3309   "reload_completed"
3310   [(const_int 0)]
3311 {
3312   split_di (&operands[0], 1, &operands[3], &operands[4]);
3313
3314   emit_move_insn (operands[3], operands[1]);
3315
3316   /* Generate a cltd if possible and doing so it profitable.  */
3317   if (true_regnum (operands[1]) == 0
3318       && true_regnum (operands[2]) == 1
3319       && (optimize_size || TARGET_USE_CLTD))
3320     {
3321       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3322     }
3323   else
3324     {
3325       emit_move_insn (operands[2], operands[1]);
3326       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3327     }
3328   emit_move_insn (operands[4], operands[2]);
3329   DONE;
3330 })
3331
3332 ;; Extend to register case.  Optimize case where source and destination
3333 ;; registers match and cases where we can use cltd.
3334 (define_split 
3335   [(set (match_operand:DI 0 "register_operand" "")
3336         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3337    (clobber (reg:CC FLAGS_REG))
3338    (clobber (match_scratch:SI 2 ""))]
3339   "reload_completed"
3340   [(const_int 0)]
3341 {
3342   split_di (&operands[0], 1, &operands[3], &operands[4]);
3343
3344   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3345     emit_move_insn (operands[3], operands[1]);
3346
3347   /* Generate a cltd if possible and doing so it profitable.  */
3348   if (true_regnum (operands[3]) == 0
3349       && (optimize_size || TARGET_USE_CLTD))
3350     {
3351       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3352       DONE;
3353     }
3354
3355   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3356     emit_move_insn (operands[4], operands[1]);
3357
3358   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3359   DONE;
3360 })
3361
3362 (define_insn "extendhisi2"
3363   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3364         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3365   ""
3366 {
3367   switch (get_attr_prefix_0f (insn))
3368     {
3369     case 0:
3370       return "{cwtl|cwde}";
3371     default:
3372       return "movs{wl|x}\t{%1,%0|%0, %1}";
3373     }
3374 }
3375   [(set_attr "type" "imovx")
3376    (set_attr "mode" "SI")