OSDN Git Service

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