OSDN Git Service

2006-01-26 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          30)
91    (UNSPEC_MASKMOV              31)
92    (UNSPEC_MOVMSK               32)
93    (UNSPEC_MOVNT                33)
94    (UNSPEC_MOVU                 34)
95    (UNSPEC_RCP                  35)
96    (UNSPEC_RSQRT                36)
97    (UNSPEC_SFENCE               37)
98    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                39)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDQQU                47)
108
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
113
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
131
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_TAN_ONE              82)
136    (UNSPEC_TAN_TAN              83)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
145
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
151   ])
152
153 (define_constants
154   [(UNSPECV_BLOCKAGE            0)
155    (UNSPECV_STACK_PROBE         1)
156    (UNSPECV_EMMS                2)
157    (UNSPECV_LDMXCSR             3)
158    (UNSPECV_STMXCSR             4)
159    (UNSPECV_FEMMS               5)
160    (UNSPECV_CLFLUSH             6)
161    (UNSPECV_ALIGN               7)
162    (UNSPECV_MONITOR             8)
163    (UNSPECV_MWAIT               9)
164    (UNSPECV_CMPXCHG_1           10)
165    (UNSPECV_CMPXCHG_2           11)
166    (UNSPECV_XCHG                12)
167    (UNSPECV_LOCK                13)
168   ])
169
170 ;; Registers by name.
171 (define_constants
172   [(BP_REG                       6)
173    (SP_REG                       7)
174    (FLAGS_REG                   17)
175    (FPSR_REG                    18)
176    (DIRFLAG_REG                 19)
177   ])
178
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; from i386.c.
181
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first.  This allows for better optimization.  For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
186
187 \f
188 ;; Processor type.  This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
191   (const (symbol_ref "ix86_tune")))
192
193 ;; A basic instruction type.  Refinements due to arguments to be
194 ;; provided in other attributes.
195 (define_attr "type"
196   "other,multi,
197    alu,alu1,negnot,imov,imovx,lea,
198    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199    icmp,test,ibr,setcc,icmov,
200    push,pop,call,callv,leave,
201    str,cld,
202    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203    sselog,sselog1,sseiadd,sseishft,sseimul,
204    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206   (const_string "other"))
207
208 ;; Main data type used by the insn
209 (define_attr "mode"
210   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211   (const_string "unknown"))
212
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216            (const_string "i387")
217          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
219            (const_string "sse")
220          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
221            (const_string "mmx")
222          (eq_attr "type" "other")
223            (const_string "unknown")]
224          (const_string "integer")))
225
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
229            (const_int 0)
230          (eq_attr "unit" "i387,sse,mmx")
231            (const_int 0)
232          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
233                           imul,icmp,push,pop")
234            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235          (eq_attr "type" "imov,test")
236            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237          (eq_attr "type" "call")
238            (if_then_else (match_operand 0 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          (eq_attr "type" "callv")
242            (if_then_else (match_operand 1 "constant_call_address_operand" "")
243              (const_int 4)
244              (const_int 0))
245          ;; We don't know the size before shorten_branches.  Expect
246          ;; the instruction to fit for better scheduling.
247          (eq_attr "type" "ibr")
248            (const_int 1)
249          ]
250          (symbol_ref "/* Update immediate_length and other attributes! */
251                       gcc_unreachable (),1")))
252
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
256            (const_int 0)
257          (and (eq_attr "type" "call")
258               (match_operand 0 "constant_call_address_operand" ""))
259              (const_int 0)
260          (and (eq_attr "type" "callv")
261               (match_operand 1 "constant_call_address_operand" ""))
262              (const_int 0)
263          ]
264          (symbol_ref "ix86_attr_length_address_default (insn)")))
265
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268   (if_then_else (ior (eq_attr "mode" "HI")
269                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
270     (const_int 1)
271     (const_int 0)))
272
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" "" 
275   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
281   (if_then_else 
282     (ior (eq_attr "type" "imovx,setcc,icmov")
283          (eq_attr "unit" "sse,mmx"))
284     (const_int 1)
285     (const_int 0)))
286
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289   (cond [(and (eq_attr "mode" "DI")
290               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
291            (const_int 1)
292          (and (eq_attr "mode" "QI")
293               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294                   (const_int 0)))
295            (const_int 1)
296          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
297              (const_int 0))
298            (const_int 1)
299         ]
300         (const_int 0)))
301
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304   (cond [(eq_attr "type" "str,cld,leave")
305            (const_int 0)
306          (eq_attr "unit" "i387")
307            (const_int 0)
308          (and (eq_attr "type" "incdec")
309               (ior (match_operand:SI 1 "register_operand" "")
310                    (match_operand:HI 1 "register_operand" "")))
311            (const_int 0)
312          (and (eq_attr "type" "push")
313               (not (match_operand 1 "memory_operand" "")))
314            (const_int 0)
315          (and (eq_attr "type" "pop")
316               (not (match_operand 0 "memory_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "imov")
319               (ior (and (match_operand 0 "register_operand" "")
320                         (match_operand 1 "immediate_operand" ""))
321                    (ior (and (match_operand 0 "ax_reg_operand" "")
322                              (match_operand 1 "memory_displacement_only_operand" ""))
323                         (and (match_operand 0 "memory_displacement_only_operand" "")
324                              (match_operand 1 "ax_reg_operand" "")))))
325            (const_int 0)
326          (and (eq_attr "type" "call")
327               (match_operand 0 "constant_call_address_operand" ""))
328              (const_int 0)
329          (and (eq_attr "type" "callv")
330               (match_operand 1 "constant_call_address_operand" ""))
331              (const_int 0)
332          ]
333          (const_int 1)))
334
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
338 ;; other insns.
339 (define_attr "length" ""
340   (cond [(eq_attr "type" "other,multi,fistp,frndint")
341            (const_int 16)
342          (eq_attr "type" "fcmp")
343            (const_int 4)
344          (eq_attr "unit" "i387")
345            (plus (const_int 2)
346                  (plus (attr "prefix_data16")
347                        (attr "length_address")))]
348          (plus (plus (attr "modrm")
349                      (plus (attr "prefix_0f")
350                            (plus (attr "prefix_rex")
351                                  (const_int 1))))
352                (plus (attr "prefix_rep")
353                      (plus (attr "prefix_data16")
354                            (plus (attr "length_immediate")
355                                  (attr "length_address")))))))
356
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
360
361 (define_attr "memory" "none,load,store,both,unknown"
362   (cond [(eq_attr "type" "other,multi,str")
363            (const_string "unknown")
364          (eq_attr "type" "lea,fcmov,fpspc,cld")
365            (const_string "none")
366          (eq_attr "type" "fistp,leave")
367            (const_string "both")
368          (eq_attr "type" "frndint")
369            (const_string "load")
370          (eq_attr "type" "push")
371            (if_then_else (match_operand 1 "memory_operand" "")
372              (const_string "both")
373              (const_string "store"))
374          (eq_attr "type" "pop")
375            (if_then_else (match_operand 0 "memory_operand" "")
376              (const_string "both")
377              (const_string "load"))
378          (eq_attr "type" "setcc")
379            (if_then_else (match_operand 0 "memory_operand" "")
380              (const_string "store")
381              (const_string "none"))
382          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383            (if_then_else (ior (match_operand 0 "memory_operand" "")
384                               (match_operand 1 "memory_operand" ""))
385              (const_string "load")
386              (const_string "none"))
387          (eq_attr "type" "ibr")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "load")
390              (const_string "none"))
391          (eq_attr "type" "call")
392            (if_then_else (match_operand 0 "constant_call_address_operand" "")
393              (const_string "none")
394              (const_string "load"))
395          (eq_attr "type" "callv")
396            (if_then_else (match_operand 1 "constant_call_address_operand" "")
397              (const_string "none")
398              (const_string "load"))
399          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400               (match_operand 1 "memory_operand" ""))
401            (const_string "both")
402          (and (match_operand 0 "memory_operand" "")
403               (match_operand 1 "memory_operand" ""))
404            (const_string "both")
405          (match_operand 0 "memory_operand" "")
406            (const_string "store")
407          (match_operand 1 "memory_operand" "")
408            (const_string "load")
409          (and (eq_attr "type"
410                  "!alu1,negnot,ishift1,
411                    imov,imovx,icmp,test,
412                    fmov,fcmp,fsgn,
413                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414                    mmx,mmxmov,mmxcmp,mmxcvt")
415               (match_operand 2 "memory_operand" ""))
416            (const_string "load")
417          (and (eq_attr "type" "icmov")
418               (match_operand 3 "memory_operand" ""))
419            (const_string "load")
420         ]
421         (const_string "none")))
422
423 ;; Indicates if an instruction has both an immediate and a displacement.
424
425 (define_attr "imm_disp" "false,true,unknown"
426   (cond [(eq_attr "type" "other,multi")
427            (const_string "unknown")
428          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429               (and (match_operand 0 "memory_displacement_operand" "")
430                    (match_operand 1 "immediate_operand" "")))
431            (const_string "true")
432          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433               (and (match_operand 0 "memory_displacement_operand" "")
434                    (match_operand 2 "immediate_operand" "")))
435            (const_string "true")
436         ]
437         (const_string "false")))
438
439 ;; Indicates if an FP operation has an integer source.
440
441 (define_attr "fp_int_src" "false,true"
442   (const_string "false"))
443
444 ;; Defines rounding mode of an FP operation.
445
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447   (const_string "any"))
448
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451   [(set_attr "length" "128")
452    (set_attr "type" "multi")])
453
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
456  
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
459
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
462
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
465  
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
468
469 \f
470 ;; Scheduling descriptions
471
472 (include "pentium.md")
473 (include "ppro.md")
474 (include "k6.md")
475 (include "athlon.md")
476
477 \f
478 ;; Operand and operator predicates
479
480 (include "predicates.md")
481
482 \f
483 ;; Compare instructions.
484
485 ;; All compare insns have expanders that save the operands away without
486 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
487 ;; after the cmp) will actually emit the cmpM.
488
489 (define_expand "cmpti"
490   [(set (reg:CC FLAGS_REG)
491         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
492                     (match_operand:TI 1 "x86_64_general_operand" "")))]
493   "TARGET_64BIT"
494 {
495   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
496     operands[0] = force_reg (TImode, operands[0]);
497   ix86_compare_op0 = operands[0];
498   ix86_compare_op1 = operands[1];
499   DONE;
500 })
501
502 (define_expand "cmpdi"
503   [(set (reg:CC FLAGS_REG)
504         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
505                     (match_operand:DI 1 "x86_64_general_operand" "")))]
506   ""
507 {
508   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
509     operands[0] = force_reg (DImode, operands[0]);
510   ix86_compare_op0 = operands[0];
511   ix86_compare_op1 = operands[1];
512   DONE;
513 })
514
515 (define_expand "cmpsi"
516   [(set (reg:CC FLAGS_REG)
517         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
518                     (match_operand:SI 1 "general_operand" "")))]
519   ""
520 {
521   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
522     operands[0] = force_reg (SImode, operands[0]);
523   ix86_compare_op0 = operands[0];
524   ix86_compare_op1 = operands[1];
525   DONE;
526 })
527
528 (define_expand "cmphi"
529   [(set (reg:CC FLAGS_REG)
530         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
531                     (match_operand:HI 1 "general_operand" "")))]
532   ""
533 {
534   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
535     operands[0] = force_reg (HImode, operands[0]);
536   ix86_compare_op0 = operands[0];
537   ix86_compare_op1 = operands[1];
538   DONE;
539 })
540
541 (define_expand "cmpqi"
542   [(set (reg:CC FLAGS_REG)
543         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
544                     (match_operand:QI 1 "general_operand" "")))]
545   "TARGET_QIMODE_MATH"
546 {
547   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
548     operands[0] = force_reg (QImode, operands[0]);
549   ix86_compare_op0 = operands[0];
550   ix86_compare_op1 = operands[1];
551   DONE;
552 })
553
554 (define_insn "cmpdi_ccno_1_rex64"
555   [(set (reg FLAGS_REG)
556         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
557                  (match_operand:DI 1 "const0_operand" "n,n")))]
558   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
559   "@
560    test{q}\t{%0, %0|%0, %0}
561    cmp{q}\t{%1, %0|%0, %1}"
562   [(set_attr "type" "test,icmp")
563    (set_attr "length_immediate" "0,1")
564    (set_attr "mode" "DI")])
565
566 (define_insn "*cmpdi_minus_1_rex64"
567   [(set (reg FLAGS_REG)
568         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
569                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
570                  (const_int 0)))]
571   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
572   "cmp{q}\t{%1, %0|%0, %1}"
573   [(set_attr "type" "icmp")
574    (set_attr "mode" "DI")])
575
576 (define_expand "cmpdi_1_rex64"
577   [(set (reg:CC FLAGS_REG)
578         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
579                     (match_operand:DI 1 "general_operand" "")))]
580   "TARGET_64BIT"
581   "")
582
583 (define_insn "cmpdi_1_insn_rex64"
584   [(set (reg FLAGS_REG)
585         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
586                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
587   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
588   "cmp{q}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "icmp")
590    (set_attr "mode" "DI")])
591
592
593 (define_insn "*cmpsi_ccno_1"
594   [(set (reg FLAGS_REG)
595         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
596                  (match_operand:SI 1 "const0_operand" "n,n")))]
597   "ix86_match_ccmode (insn, CCNOmode)"
598   "@
599    test{l}\t{%0, %0|%0, %0}
600    cmp{l}\t{%1, %0|%0, %1}"
601   [(set_attr "type" "test,icmp")
602    (set_attr "length_immediate" "0,1")
603    (set_attr "mode" "SI")])
604
605 (define_insn "*cmpsi_minus_1"
606   [(set (reg FLAGS_REG)
607         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
608                            (match_operand:SI 1 "general_operand" "ri,mr"))
609                  (const_int 0)))]
610   "ix86_match_ccmode (insn, CCGOCmode)"
611   "cmp{l}\t{%1, %0|%0, %1}"
612   [(set_attr "type" "icmp")
613    (set_attr "mode" "SI")])
614
615 (define_expand "cmpsi_1"
616   [(set (reg:CC FLAGS_REG)
617         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
618                     (match_operand:SI 1 "general_operand" "ri,mr")))]
619   ""
620   "")
621
622 (define_insn "*cmpsi_1_insn"
623   [(set (reg FLAGS_REG)
624         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625                  (match_operand:SI 1 "general_operand" "ri,mr")))]
626   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
627     && ix86_match_ccmode (insn, CCmode)"
628   "cmp{l}\t{%1, %0|%0, %1}"
629   [(set_attr "type" "icmp")
630    (set_attr "mode" "SI")])
631
632 (define_insn "*cmphi_ccno_1"
633   [(set (reg FLAGS_REG)
634         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
635                  (match_operand:HI 1 "const0_operand" "n,n")))]
636   "ix86_match_ccmode (insn, CCNOmode)"
637   "@
638    test{w}\t{%0, %0|%0, %0}
639    cmp{w}\t{%1, %0|%0, %1}"
640   [(set_attr "type" "test,icmp")
641    (set_attr "length_immediate" "0,1")
642    (set_attr "mode" "HI")])
643
644 (define_insn "*cmphi_minus_1"
645   [(set (reg FLAGS_REG)
646         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
647                            (match_operand:HI 1 "general_operand" "ri,mr"))
648                  (const_int 0)))]
649   "ix86_match_ccmode (insn, CCGOCmode)"
650   "cmp{w}\t{%1, %0|%0, %1}"
651   [(set_attr "type" "icmp")
652    (set_attr "mode" "HI")])
653
654 (define_insn "*cmphi_1"
655   [(set (reg FLAGS_REG)
656         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
657                  (match_operand:HI 1 "general_operand" "ri,mr")))]
658   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
659    && ix86_match_ccmode (insn, CCmode)"
660   "cmp{w}\t{%1, %0|%0, %1}"
661   [(set_attr "type" "icmp")
662    (set_attr "mode" "HI")])
663
664 (define_insn "*cmpqi_ccno_1"
665   [(set (reg FLAGS_REG)
666         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
667                  (match_operand:QI 1 "const0_operand" "n,n")))]
668   "ix86_match_ccmode (insn, CCNOmode)"
669   "@
670    test{b}\t{%0, %0|%0, %0}
671    cmp{b}\t{$0, %0|%0, 0}"
672   [(set_attr "type" "test,icmp")
673    (set_attr "length_immediate" "0,1")
674    (set_attr "mode" "QI")])
675
676 (define_insn "*cmpqi_1"
677   [(set (reg FLAGS_REG)
678         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
679                  (match_operand:QI 1 "general_operand" "qi,mq")))]
680   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
681     && ix86_match_ccmode (insn, CCmode)"
682   "cmp{b}\t{%1, %0|%0, %1}"
683   [(set_attr "type" "icmp")
684    (set_attr "mode" "QI")])
685
686 (define_insn "*cmpqi_minus_1"
687   [(set (reg FLAGS_REG)
688         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
689                            (match_operand:QI 1 "general_operand" "qi,mq"))
690                  (const_int 0)))]
691   "ix86_match_ccmode (insn, CCGOCmode)"
692   "cmp{b}\t{%1, %0|%0, %1}"
693   [(set_attr "type" "icmp")
694    (set_attr "mode" "QI")])
695
696 (define_insn "*cmpqi_ext_1"
697   [(set (reg FLAGS_REG)
698         (compare
699           (match_operand:QI 0 "general_operand" "Qm")
700           (subreg:QI
701             (zero_extract:SI
702               (match_operand 1 "ext_register_operand" "Q")
703               (const_int 8)
704               (const_int 8)) 0)))]
705   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%h1, %0|%0, %h1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 (define_insn "*cmpqi_ext_1_rex64"
711   [(set (reg FLAGS_REG)
712         (compare
713           (match_operand:QI 0 "register_operand" "Q")
714           (subreg:QI
715             (zero_extract:SI
716               (match_operand 1 "ext_register_operand" "Q")
717               (const_int 8)
718               (const_int 8)) 0)))]
719   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%h1, %0|%0, %h1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "*cmpqi_ext_2"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "const0_operand" "n")))]
733   "ix86_match_ccmode (insn, CCNOmode)"
734   "test{b}\t%h0, %h0"
735   [(set_attr "type" "test")
736    (set_attr "length_immediate" "0")
737    (set_attr "mode" "QI")])
738
739 (define_expand "cmpqi_ext_3"
740   [(set (reg:CC FLAGS_REG)
741         (compare:CC
742           (subreg:QI
743             (zero_extract:SI
744               (match_operand 0 "ext_register_operand" "")
745               (const_int 8)
746               (const_int 8)) 0)
747           (match_operand:QI 1 "general_operand" "")))]
748   ""
749   "")
750
751 (define_insn "cmpqi_ext_3_insn"
752   [(set (reg FLAGS_REG)
753         (compare
754           (subreg:QI
755             (zero_extract:SI
756               (match_operand 0 "ext_register_operand" "Q")
757               (const_int 8)
758               (const_int 8)) 0)
759           (match_operand:QI 1 "general_operand" "Qmn")))]
760   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
761   "cmp{b}\t{%1, %h0|%h0, %1}"
762   [(set_attr "type" "icmp")
763    (set_attr "mode" "QI")])
764
765 (define_insn "cmpqi_ext_3_insn_rex64"
766   [(set (reg FLAGS_REG)
767         (compare
768           (subreg:QI
769             (zero_extract:SI
770               (match_operand 0 "ext_register_operand" "Q")
771               (const_int 8)
772               (const_int 8)) 0)
773           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
774   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
775   "cmp{b}\t{%1, %h0|%h0, %1}"
776   [(set_attr "type" "icmp")
777    (set_attr "mode" "QI")])
778
779 (define_insn "*cmpqi_ext_4"
780   [(set (reg FLAGS_REG)
781         (compare
782           (subreg:QI
783             (zero_extract:SI
784               (match_operand 0 "ext_register_operand" "Q")
785               (const_int 8)
786               (const_int 8)) 0)
787           (subreg:QI
788             (zero_extract:SI
789               (match_operand 1 "ext_register_operand" "Q")
790               (const_int 8)
791               (const_int 8)) 0)))]
792   "ix86_match_ccmode (insn, CCmode)"
793   "cmp{b}\t{%h1, %h0|%h0, %h1}"
794   [(set_attr "type" "icmp")
795    (set_attr "mode" "QI")])
796
797 ;; These implement float point compares.
798 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
799 ;; which would allow mix and match FP modes on the compares.  Which is what
800 ;; the old patterns did, but with many more of them.
801
802 (define_expand "cmpxf"
803   [(set (reg:CC FLAGS_REG)
804         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
805                     (match_operand:XF 1 "nonmemory_operand" "")))]
806   "TARGET_80387"
807 {
808   ix86_compare_op0 = operands[0];
809   ix86_compare_op1 = operands[1];
810   DONE;
811 })
812
813 (define_expand "cmpdf"
814   [(set (reg:CC FLAGS_REG)
815         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
816                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
817   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
818 {
819   ix86_compare_op0 = operands[0];
820   ix86_compare_op1 = operands[1];
821   DONE;
822 })
823
824 (define_expand "cmpsf"
825   [(set (reg:CC FLAGS_REG)
826         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
827                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
828   "TARGET_80387 || TARGET_SSE_MATH"
829 {
830   ix86_compare_op0 = operands[0];
831   ix86_compare_op1 = operands[1];
832   DONE;
833 })
834
835 ;; FP compares, step 1:
836 ;; Set the FP condition codes.
837 ;;
838 ;; CCFPmode     compare with exceptions
839 ;; CCFPUmode    compare with no exceptions
840
841 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
842 ;; used to manage the reg stack popping would not be preserved.
843
844 (define_insn "*cmpfp_0"
845   [(set (match_operand:HI 0 "register_operand" "=a")
846         (unspec:HI
847           [(compare:CCFP
848              (match_operand 1 "register_operand" "f")
849              (match_operand 2 "const0_operand" "X"))]
850         UNSPEC_FNSTSW))]
851   "TARGET_80387
852    && FLOAT_MODE_P (GET_MODE (operands[1]))
853    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
854   "* return output_fp_compare (insn, operands, 0, 0);"
855   [(set_attr "type" "multi")
856    (set_attr "unit" "i387")
857    (set (attr "mode")
858      (cond [(match_operand:SF 1 "" "")
859               (const_string "SF")
860             (match_operand:DF 1 "" "")
861               (const_string "DF")
862            ]
863            (const_string "XF")))])
864
865 (define_insn "*cmpfp_sf"
866   [(set (match_operand:HI 0 "register_operand" "=a")
867         (unspec:HI
868           [(compare:CCFP
869              (match_operand:SF 1 "register_operand" "f")
870              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
871           UNSPEC_FNSTSW))]
872   "TARGET_80387"
873   "* return output_fp_compare (insn, operands, 0, 0);"
874   [(set_attr "type" "multi")
875    (set_attr "unit" "i387")
876    (set_attr "mode" "SF")])
877
878 (define_insn "*cmpfp_df"
879   [(set (match_operand:HI 0 "register_operand" "=a")
880         (unspec:HI
881           [(compare:CCFP
882              (match_operand:DF 1 "register_operand" "f")
883              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
884           UNSPEC_FNSTSW))]
885   "TARGET_80387"
886   "* return output_fp_compare (insn, operands, 0, 0);"
887   [(set_attr "type" "multi")
888    (set_attr "unit" "i387")
889    (set_attr "mode" "DF")])
890
891 (define_insn "*cmpfp_xf"
892   [(set (match_operand:HI 0 "register_operand" "=a")
893         (unspec:HI
894           [(compare:CCFP
895              (match_operand:XF 1 "register_operand" "f")
896              (match_operand:XF 2 "register_operand" "f"))]
897           UNSPEC_FNSTSW))]
898   "TARGET_80387"
899   "* return output_fp_compare (insn, operands, 0, 0);"
900   [(set_attr "type" "multi")
901    (set_attr "unit" "i387")
902    (set_attr "mode" "XF")])
903
904 (define_insn "*cmpfp_u"
905   [(set (match_operand:HI 0 "register_operand" "=a")
906         (unspec:HI
907           [(compare:CCFPU
908              (match_operand 1 "register_operand" "f")
909              (match_operand 2 "register_operand" "f"))]
910           UNSPEC_FNSTSW))]
911   "TARGET_80387
912    && FLOAT_MODE_P (GET_MODE (operands[1]))
913    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
914   "* return output_fp_compare (insn, operands, 0, 1);"
915   [(set_attr "type" "multi")
916    (set_attr "unit" "i387")
917    (set (attr "mode")
918      (cond [(match_operand:SF 1 "" "")
919               (const_string "SF")
920             (match_operand:DF 1 "" "")
921               (const_string "DF")
922            ]
923            (const_string "XF")))])
924
925 (define_insn "*cmpfp_<mode>"
926   [(set (match_operand:HI 0 "register_operand" "=a")
927         (unspec:HI
928           [(compare:CCFP
929              (match_operand 1 "register_operand" "f")
930              (match_operator 3 "float_operator"
931                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
932           UNSPEC_FNSTSW))]
933   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
934    && FLOAT_MODE_P (GET_MODE (operands[1]))
935    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
936   "* return output_fp_compare (insn, operands, 0, 0);"
937   [(set_attr "type" "multi")
938    (set_attr "unit" "i387")
939    (set_attr "fp_int_src" "true")
940    (set_attr "mode" "<MODE>")])
941
942 ;; FP compares, step 2
943 ;; Move the fpsw to ax.
944
945 (define_insn "x86_fnstsw_1"
946   [(set (match_operand:HI 0 "register_operand" "=a")
947         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
948   "TARGET_80387"
949   "fnstsw\t%0"
950   [(set_attr "length" "2")
951    (set_attr "mode" "SI")
952    (set_attr "unit" "i387")])
953
954 ;; FP compares, step 3
955 ;; Get ax into flags, general case.
956
957 (define_insn "x86_sahf_1"
958   [(set (reg:CC FLAGS_REG)
959         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
960   "!TARGET_64BIT"
961   "sahf"
962   [(set_attr "length" "1")
963    (set_attr "athlon_decode" "vector")
964    (set_attr "mode" "SI")])
965
966 ;; Pentium Pro can do steps 1 through 3 in one go.
967
968 (define_insn "*cmpfp_i_mixed"
969   [(set (reg:CCFP FLAGS_REG)
970         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
971                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
972   "TARGET_MIX_SSE_I387
973    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
974    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
975   "* return output_fp_compare (insn, operands, 1, 0);"
976   [(set_attr "type" "fcmp,ssecomi")
977    (set (attr "mode")
978      (if_then_else (match_operand:SF 1 "" "")
979         (const_string "SF")
980         (const_string "DF")))
981    (set_attr "athlon_decode" "vector")])
982
983 (define_insn "*cmpfp_i_sse"
984   [(set (reg:CCFP FLAGS_REG)
985         (compare:CCFP (match_operand 0 "register_operand" "x")
986                       (match_operand 1 "nonimmediate_operand" "xm")))]
987   "TARGET_SSE_MATH
988    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990   "* return output_fp_compare (insn, operands, 1, 0);"
991   [(set_attr "type" "ssecomi")
992    (set (attr "mode")
993      (if_then_else (match_operand:SF 1 "" "")
994         (const_string "SF")
995         (const_string "DF")))
996    (set_attr "athlon_decode" "vector")])
997
998 (define_insn "*cmpfp_i_i387"
999   [(set (reg:CCFP FLAGS_REG)
1000         (compare:CCFP (match_operand 0 "register_operand" "f")
1001                       (match_operand 1 "register_operand" "f")))]
1002   "TARGET_80387 && TARGET_CMOVE
1003    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1004    && FLOAT_MODE_P (GET_MODE (operands[0]))
1005    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006   "* return output_fp_compare (insn, operands, 1, 0);"
1007   [(set_attr "type" "fcmp")
1008    (set (attr "mode")
1009      (cond [(match_operand:SF 1 "" "")
1010               (const_string "SF")
1011             (match_operand:DF 1 "" "")
1012               (const_string "DF")
1013            ]
1014            (const_string "XF")))
1015    (set_attr "athlon_decode" "vector")])
1016
1017 (define_insn "*cmpfp_iu_mixed"
1018   [(set (reg:CCFPU FLAGS_REG)
1019         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1020                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1021   "TARGET_MIX_SSE_I387
1022    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1023    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024   "* return output_fp_compare (insn, operands, 1, 1);"
1025   [(set_attr "type" "fcmp,ssecomi")
1026    (set (attr "mode")
1027      (if_then_else (match_operand:SF 1 "" "")
1028         (const_string "SF")
1029         (const_string "DF")))
1030    (set_attr "athlon_decode" "vector")])
1031
1032 (define_insn "*cmpfp_iu_sse"
1033   [(set (reg:CCFPU FLAGS_REG)
1034         (compare:CCFPU (match_operand 0 "register_operand" "x")
1035                        (match_operand 1 "nonimmediate_operand" "xm")))]
1036   "TARGET_SSE_MATH
1037    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039   "* return output_fp_compare (insn, operands, 1, 1);"
1040   [(set_attr "type" "ssecomi")
1041    (set (attr "mode")
1042      (if_then_else (match_operand:SF 1 "" "")
1043         (const_string "SF")
1044         (const_string "DF")))
1045    (set_attr "athlon_decode" "vector")])
1046
1047 (define_insn "*cmpfp_iu_387"
1048   [(set (reg:CCFPU FLAGS_REG)
1049         (compare:CCFPU (match_operand 0 "register_operand" "f")
1050                        (match_operand 1 "register_operand" "f")))]
1051   "TARGET_80387 && TARGET_CMOVE
1052    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1053    && FLOAT_MODE_P (GET_MODE (operands[0]))
1054    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055   "* return output_fp_compare (insn, operands, 1, 1);"
1056   [(set_attr "type" "fcmp")
1057    (set (attr "mode")
1058      (cond [(match_operand:SF 1 "" "")
1059               (const_string "SF")
1060             (match_operand:DF 1 "" "")
1061               (const_string "DF")
1062            ]
1063            (const_string "XF")))
1064    (set_attr "athlon_decode" "vector")])
1065 \f
1066 ;; Move instructions.
1067
1068 ;; General case of fullword move.
1069
1070 (define_expand "movsi"
1071   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1072         (match_operand:SI 1 "general_operand" ""))]
1073   ""
1074   "ix86_expand_move (SImode, operands); DONE;")
1075
1076 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1077 ;; general_operand.
1078 ;;
1079 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1080 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1081 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1082 ;; targets without our curiosities, and it is just as easy to represent
1083 ;; this differently.
1084
1085 (define_insn "*pushsi2"
1086   [(set (match_operand:SI 0 "push_operand" "=<")
1087         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1088   "!TARGET_64BIT"
1089   "push{l}\t%1"
1090   [(set_attr "type" "push")
1091    (set_attr "mode" "SI")])
1092
1093 ;; For 64BIT abi we always round up to 8 bytes.
1094 (define_insn "*pushsi2_rex64"
1095   [(set (match_operand:SI 0 "push_operand" "=X")
1096         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1097   "TARGET_64BIT"
1098   "push{q}\t%q1"
1099   [(set_attr "type" "push")
1100    (set_attr "mode" "SI")])
1101
1102 (define_insn "*pushsi2_prologue"
1103   [(set (match_operand:SI 0 "push_operand" "=<")
1104         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1105    (clobber (mem:BLK (scratch)))]
1106   "!TARGET_64BIT"
1107   "push{l}\t%1"
1108   [(set_attr "type" "push")
1109    (set_attr "mode" "SI")])
1110
1111 (define_insn "*popsi1_epilogue"
1112   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1113         (mem:SI (reg:SI SP_REG)))
1114    (set (reg:SI SP_REG)
1115         (plus:SI (reg:SI SP_REG) (const_int 4)))
1116    (clobber (mem:BLK (scratch)))]
1117   "!TARGET_64BIT"
1118   "pop{l}\t%0"
1119   [(set_attr "type" "pop")
1120    (set_attr "mode" "SI")])
1121
1122 (define_insn "popsi1"
1123   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1124         (mem:SI (reg:SI SP_REG)))
1125    (set (reg:SI SP_REG)
1126         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1127   "!TARGET_64BIT"
1128   "pop{l}\t%0"
1129   [(set_attr "type" "pop")
1130    (set_attr "mode" "SI")])
1131
1132 (define_insn "*movsi_xor"
1133   [(set (match_operand:SI 0 "register_operand" "=r")
1134         (match_operand:SI 1 "const0_operand" "i"))
1135    (clobber (reg:CC FLAGS_REG))]
1136   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1137   "xor{l}\t{%0, %0|%0, %0}"
1138   [(set_attr "type" "alu1")
1139    (set_attr "mode" "SI")
1140    (set_attr "length_immediate" "0")])
1141  
1142 (define_insn "*movsi_or"
1143   [(set (match_operand:SI 0 "register_operand" "=r")
1144         (match_operand:SI 1 "immediate_operand" "i"))
1145    (clobber (reg:CC FLAGS_REG))]
1146   "reload_completed
1147    && operands[1] == constm1_rtx
1148    && (TARGET_PENTIUM || optimize_size)"
1149 {
1150   operands[1] = constm1_rtx;
1151   return "or{l}\t{%1, %0|%0, %1}";
1152 }
1153   [(set_attr "type" "alu1")
1154    (set_attr "mode" "SI")
1155    (set_attr "length_immediate" "1")])
1156
1157 (define_insn "*movsi_1"
1158   [(set (match_operand:SI 0 "nonimmediate_operand"
1159                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1160         (match_operand:SI 1 "general_operand"
1161                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1162   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1163 {
1164   switch (get_attr_type (insn))
1165     {
1166     case TYPE_SSELOG1:
1167       if (get_attr_mode (insn) == MODE_TI)
1168         return "pxor\t%0, %0";
1169       return "xorps\t%0, %0";
1170
1171     case TYPE_SSEMOV:
1172       switch (get_attr_mode (insn))
1173         {
1174         case MODE_TI:
1175           return "movdqa\t{%1, %0|%0, %1}";
1176         case MODE_V4SF:
1177           return "movaps\t{%1, %0|%0, %1}";
1178         case MODE_SI:
1179           return "movd\t{%1, %0|%0, %1}";
1180         case MODE_SF:
1181           return "movss\t{%1, %0|%0, %1}";
1182         default:
1183           gcc_unreachable ();
1184         }
1185
1186     case TYPE_MMXADD:
1187       return "pxor\t%0, %0";
1188
1189     case TYPE_MMXMOV:
1190       if (get_attr_mode (insn) == MODE_DI)
1191         return "movq\t{%1, %0|%0, %1}";
1192       return "movd\t{%1, %0|%0, %1}";
1193
1194     case TYPE_LEA:
1195       return "lea{l}\t{%1, %0|%0, %1}";
1196
1197     default:
1198       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1199       return "mov{l}\t{%1, %0|%0, %1}";
1200     }
1201 }
1202   [(set (attr "type")
1203      (cond [(eq_attr "alternative" "2")
1204               (const_string "mmxadd")
1205             (eq_attr "alternative" "3,4,5")
1206               (const_string "mmxmov")
1207             (eq_attr "alternative" "6")
1208               (const_string "sselog1")
1209             (eq_attr "alternative" "7,8,9,10,11")
1210               (const_string "ssemov")
1211             (match_operand:DI 1 "pic_32bit_operand" "")
1212               (const_string "lea")
1213            ]
1214            (const_string "imov")))
1215    (set (attr "mode")
1216      (cond [(eq_attr "alternative" "2,3")
1217               (const_string "DI")
1218             (eq_attr "alternative" "6,7")
1219               (if_then_else
1220                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1221                 (const_string "V4SF")
1222                 (const_string "TI"))
1223             (and (eq_attr "alternative" "8,9,10,11")
1224                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1225               (const_string "SF")
1226            ]
1227            (const_string "SI")))])
1228
1229 ;; Stores and loads of ax to arbitrary constant address.
1230 ;; We fake an second form of instruction to force reload to load address
1231 ;; into register when rax is not available
1232 (define_insn "*movabssi_1_rex64"
1233   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1234         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1235   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1236   "@
1237    movabs{l}\t{%1, %P0|%P0, %1}
1238    mov{l}\t{%1, %a0|%a0, %1}"
1239   [(set_attr "type" "imov")
1240    (set_attr "modrm" "0,*")
1241    (set_attr "length_address" "8,0")
1242    (set_attr "length_immediate" "0,*")
1243    (set_attr "memory" "store")
1244    (set_attr "mode" "SI")])
1245
1246 (define_insn "*movabssi_2_rex64"
1247   [(set (match_operand:SI 0 "register_operand" "=a,r")
1248         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1249   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1250   "@
1251    movabs{l}\t{%P1, %0|%0, %P1}
1252    mov{l}\t{%a1, %0|%0, %a1}"
1253   [(set_attr "type" "imov")
1254    (set_attr "modrm" "0,*")
1255    (set_attr "length_address" "8,0")
1256    (set_attr "length_immediate" "0")
1257    (set_attr "memory" "load")
1258    (set_attr "mode" "SI")])
1259
1260 (define_insn "*swapsi"
1261   [(set (match_operand:SI 0 "register_operand" "+r")
1262         (match_operand:SI 1 "register_operand" "+r"))
1263    (set (match_dup 1)
1264         (match_dup 0))]
1265   ""
1266   "xchg{l}\t%1, %0"
1267   [(set_attr "type" "imov")
1268    (set_attr "mode" "SI")
1269    (set_attr "pent_pair" "np")
1270    (set_attr "athlon_decode" "vector")])
1271
1272 (define_expand "movhi"
1273   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1274         (match_operand:HI 1 "general_operand" ""))]
1275   ""
1276   "ix86_expand_move (HImode, operands); DONE;")
1277
1278 (define_insn "*pushhi2"
1279   [(set (match_operand:HI 0 "push_operand" "=X")
1280         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1281   "!TARGET_64BIT"
1282   "push{l}\t%k1"
1283   [(set_attr "type" "push")
1284    (set_attr "mode" "SI")])
1285
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288   [(set (match_operand:HI 0 "push_operand" "=X")
1289         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290   "TARGET_64BIT"
1291   "push{q}\t%q1"
1292   [(set_attr "type" "push")
1293    (set_attr "mode" "DI")])
1294
1295 (define_insn "*movhi_1"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299 {
1300   switch (get_attr_type (insn))
1301     {
1302     case TYPE_IMOVX:
1303       /* movzwl is faster than movw on p2 due to partial word stalls,
1304          though not as fast as an aligned movl.  */
1305       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306     default:
1307       if (get_attr_mode (insn) == MODE_SI)
1308         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309       else
1310         return "mov{w}\t{%1, %0|%0, %1}";
1311     }
1312 }
1313   [(set (attr "type")
1314      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "0")
1317                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                           (const_int 0))
1319                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                           (const_int 0))))
1321               (const_string "imov")
1322             (and (eq_attr "alternative" "1,2")
1323                  (match_operand:HI 1 "aligned_operand" ""))
1324               (const_string "imov")
1325             (and (ne (symbol_ref "TARGET_MOVX")
1326                      (const_int 0))
1327                  (eq_attr "alternative" "0,2"))
1328               (const_string "imovx")
1329            ]
1330            (const_string "imov")))
1331     (set (attr "mode")
1332       (cond [(eq_attr "type" "imovx")
1333                (const_string "SI")
1334              (and (eq_attr "alternative" "1,2")
1335                   (match_operand:HI 1 "aligned_operand" ""))
1336                (const_string "SI")
1337              (and (eq_attr "alternative" "0")
1338                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1339                            (const_int 0))
1340                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1341                            (const_int 0))))
1342                (const_string "SI")
1343             ]
1344             (const_string "HI")))])
1345
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1353   "@
1354    movabs{w}\t{%1, %P0|%P0, %1}
1355    mov{w}\t{%1, %a0|%a0, %1}"
1356   [(set_attr "type" "imov")
1357    (set_attr "modrm" "0,*")
1358    (set_attr "length_address" "8,0")
1359    (set_attr "length_immediate" "0,*")
1360    (set_attr "memory" "store")
1361    (set_attr "mode" "HI")])
1362
1363 (define_insn "*movabshi_2_rex64"
1364   [(set (match_operand:HI 0 "register_operand" "=a,r")
1365         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1367   "@
1368    movabs{w}\t{%P1, %0|%0, %P1}
1369    mov{w}\t{%a1, %0|%0, %a1}"
1370   [(set_attr "type" "imov")
1371    (set_attr "modrm" "0,*")
1372    (set_attr "length_address" "8,0")
1373    (set_attr "length_immediate" "0")
1374    (set_attr "memory" "load")
1375    (set_attr "mode" "HI")])
1376
1377 (define_insn "*swaphi_1"
1378   [(set (match_operand:HI 0 "register_operand" "+r")
1379         (match_operand:HI 1 "register_operand" "+r"))
1380    (set (match_dup 1)
1381         (match_dup 0))]
1382   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1383   "xchg{l}\t%k1, %k0"
1384   [(set_attr "type" "imov")
1385    (set_attr "mode" "SI")
1386    (set_attr "pent_pair" "np")
1387    (set_attr "athlon_decode" "vector")])
1388
1389 (define_insn "*swaphi_2"
1390   [(set (match_operand:HI 0 "register_operand" "+r")
1391         (match_operand:HI 1 "register_operand" "+r"))
1392    (set (match_dup 1)
1393         (match_dup 0))]
1394   "TARGET_PARTIAL_REG_STALL"
1395   "xchg{w}\t%1, %0"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")
1398    (set_attr "pent_pair" "np")
1399    (set_attr "athlon_decode" "vector")])
1400
1401 (define_expand "movstricthi"
1402   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403         (match_operand:HI 1 "general_operand" ""))]
1404   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405 {
1406   /* Don't generate memory->memory moves, go through a register */
1407   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408     operands[1] = force_reg (HImode, operands[1]);
1409 })
1410
1411 (define_insn "*movstricthi_1"
1412   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413         (match_operand:HI 1 "general_operand" "rn,m"))]
1414   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416   "mov{w}\t{%1, %0|%0, %1}"
1417   [(set_attr "type" "imov")
1418    (set_attr "mode" "HI")])
1419
1420 (define_insn "*movstricthi_xor"
1421   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422         (match_operand:HI 1 "const0_operand" "i"))
1423    (clobber (reg:CC FLAGS_REG))]
1424   "reload_completed
1425    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426   "xor{w}\t{%0, %0|%0, %0}"
1427   [(set_attr "type" "alu1")
1428    (set_attr "mode" "HI")
1429    (set_attr "length_immediate" "0")])
1430
1431 (define_expand "movqi"
1432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433         (match_operand:QI 1 "general_operand" ""))]
1434   ""
1435   "ix86_expand_move (QImode, operands); DONE;")
1436
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte".  But actually we use pushl, which has the effect
1439 ;; of rounding the amount pushed up to a word.
1440
1441 (define_insn "*pushqi2"
1442   [(set (match_operand:QI 0 "push_operand" "=X")
1443         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1444   "!TARGET_64BIT"
1445   "push{l}\t%k1"
1446   [(set_attr "type" "push")
1447    (set_attr "mode" "SI")])
1448
1449 ;; For 64BIT abi we always round up to 8 bytes.
1450 (define_insn "*pushqi2_rex64"
1451   [(set (match_operand:QI 0 "push_operand" "=X")
1452         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1453   "TARGET_64BIT"
1454   "push{q}\t%q1"
1455   [(set_attr "type" "push")
1456    (set_attr "mode" "DI")])
1457
1458 ;; Situation is quite tricky about when to choose full sized (SImode) move
1459 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1460 ;; partial register dependency machines (such as AMD Athlon), where QImode
1461 ;; moves issue extra dependency and for partial register stalls machines
1462 ;; that don't use QImode patterns (and QImode move cause stall on the next
1463 ;; instruction).
1464 ;;
1465 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1466 ;; register stall machines with, where we use QImode instructions, since
1467 ;; partial register stall can be caused there.  Then we use movzx.
1468 (define_insn "*movqi_1"
1469   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1470         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1471   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1472 {
1473   switch (get_attr_type (insn))
1474     {
1475     case TYPE_IMOVX:
1476       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1477       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1478     default:
1479       if (get_attr_mode (insn) == MODE_SI)
1480         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1481       else
1482         return "mov{b}\t{%1, %0|%0, %1}";
1483     }
1484 }
1485   [(set (attr "type")
1486      (cond [(and (eq_attr "alternative" "5")
1487                  (not (match_operand:QI 1 "aligned_operand" "")))
1488               (const_string "imovx")
1489             (ne (symbol_ref "optimize_size") (const_int 0))
1490               (const_string "imov")
1491             (and (eq_attr "alternative" "3")
1492                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1493                           (const_int 0))
1494                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1495                           (const_int 0))))
1496               (const_string "imov")
1497             (eq_attr "alternative" "3,5")
1498               (const_string "imovx")
1499             (and (ne (symbol_ref "TARGET_MOVX")
1500                      (const_int 0))
1501                  (eq_attr "alternative" "2"))
1502               (const_string "imovx")
1503            ]
1504            (const_string "imov")))
1505    (set (attr "mode")
1506       (cond [(eq_attr "alternative" "3,4,5")
1507                (const_string "SI")
1508              (eq_attr "alternative" "6")
1509                (const_string "QI")
1510              (eq_attr "type" "imovx")
1511                (const_string "SI")
1512              (and (eq_attr "type" "imov")
1513                   (and (eq_attr "alternative" "0,1")
1514                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1515                                 (const_int 0))
1516                             (and (eq (symbol_ref "optimize_size")
1517                                      (const_int 0))
1518                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519                                      (const_int 0))))))
1520                (const_string "SI")
1521              ;; Avoid partial register stalls when not using QImode arithmetic
1522              (and (eq_attr "type" "imov")
1523                   (and (eq_attr "alternative" "0,1")
1524                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1525                                 (const_int 0))
1526                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1527                                 (const_int 0)))))
1528                (const_string "SI")
1529            ]
1530            (const_string "QI")))])
1531
1532 (define_expand "reload_outqi"
1533   [(parallel [(match_operand:QI 0 "" "=m")
1534               (match_operand:QI 1 "register_operand" "r")
1535               (match_operand:QI 2 "register_operand" "=&q")])]
1536   ""
1537 {
1538   rtx op0, op1, op2;
1539   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1540
1541   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1542   if (! q_regs_operand (op1, QImode))
1543     {
1544       emit_insn (gen_movqi (op2, op1));
1545       op1 = op2;
1546     }
1547   emit_insn (gen_movqi (op0, op1));
1548   DONE;
1549 })
1550
1551 (define_insn "*swapqi_1"
1552   [(set (match_operand:QI 0 "register_operand" "+r")
1553         (match_operand:QI 1 "register_operand" "+r"))
1554    (set (match_dup 1)
1555         (match_dup 0))]
1556   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1557   "xchg{l}\t%k1, %k0"
1558   [(set_attr "type" "imov")
1559    (set_attr "mode" "SI")
1560    (set_attr "pent_pair" "np")
1561    (set_attr "athlon_decode" "vector")])
1562
1563 (define_insn "*swapqi_2"
1564   [(set (match_operand:QI 0 "register_operand" "+q")
1565         (match_operand:QI 1 "register_operand" "+q"))
1566    (set (match_dup 1)
1567         (match_dup 0))]
1568   "TARGET_PARTIAL_REG_STALL"
1569   "xchg{b}\t%1, %0"
1570   [(set_attr "type" "imov")
1571    (set_attr "mode" "QI")
1572    (set_attr "pent_pair" "np")
1573    (set_attr "athlon_decode" "vector")])
1574
1575 (define_expand "movstrictqi"
1576   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1577         (match_operand:QI 1 "general_operand" ""))]
1578   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1579 {
1580   /* Don't generate memory->memory moves, go through a register.  */
1581   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1582     operands[1] = force_reg (QImode, operands[1]);
1583 })
1584
1585 (define_insn "*movstrictqi_1"
1586   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1587         (match_operand:QI 1 "general_operand" "*qn,m"))]
1588   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1589    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1590   "mov{b}\t{%1, %0|%0, %1}"
1591   [(set_attr "type" "imov")
1592    (set_attr "mode" "QI")])
1593
1594 (define_insn "*movstrictqi_xor"
1595   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1596         (match_operand:QI 1 "const0_operand" "i"))
1597    (clobber (reg:CC FLAGS_REG))]
1598   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1599   "xor{b}\t{%0, %0|%0, %0}"
1600   [(set_attr "type" "alu1")
1601    (set_attr "mode" "QI")
1602    (set_attr "length_immediate" "0")])
1603
1604 (define_insn "*movsi_extv_1"
1605   [(set (match_operand:SI 0 "register_operand" "=R")
1606         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1607                          (const_int 8)
1608                          (const_int 8)))]
1609   ""
1610   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1611   [(set_attr "type" "imovx")
1612    (set_attr "mode" "SI")])
1613
1614 (define_insn "*movhi_extv_1"
1615   [(set (match_operand:HI 0 "register_operand" "=R")
1616         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1617                          (const_int 8)
1618                          (const_int 8)))]
1619   ""
1620   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1621   [(set_attr "type" "imovx")
1622    (set_attr "mode" "SI")])
1623
1624 (define_insn "*movqi_extv_1"
1625   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1626         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1627                          (const_int 8)
1628                          (const_int 8)))]
1629   "!TARGET_64BIT"
1630 {
1631   switch (get_attr_type (insn))
1632     {
1633     case TYPE_IMOVX:
1634       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1635     default:
1636       return "mov{b}\t{%h1, %0|%0, %h1}";
1637     }
1638 }
1639   [(set (attr "type")
1640      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1641                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1642                              (ne (symbol_ref "TARGET_MOVX")
1643                                  (const_int 0))))
1644         (const_string "imovx")
1645         (const_string "imov")))
1646    (set (attr "mode")
1647      (if_then_else (eq_attr "type" "imovx")
1648         (const_string "SI")
1649         (const_string "QI")))])
1650
1651 (define_insn "*movqi_extv_1_rex64"
1652   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1653         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1654                          (const_int 8)
1655                          (const_int 8)))]
1656   "TARGET_64BIT"
1657 {
1658   switch (get_attr_type (insn))
1659     {
1660     case TYPE_IMOVX:
1661       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1662     default:
1663       return "mov{b}\t{%h1, %0|%0, %h1}";
1664     }
1665 }
1666   [(set (attr "type")
1667      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1668                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1669                              (ne (symbol_ref "TARGET_MOVX")
1670                                  (const_int 0))))
1671         (const_string "imovx")
1672         (const_string "imov")))
1673    (set (attr "mode")
1674      (if_then_else (eq_attr "type" "imovx")
1675         (const_string "SI")
1676         (const_string "QI")))])
1677
1678 ;; Stores and loads of ax to arbitrary constant address.
1679 ;; We fake an second form of instruction to force reload to load address
1680 ;; into register when rax is not available
1681 (define_insn "*movabsqi_1_rex64"
1682   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1683         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1684   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1685   "@
1686    movabs{b}\t{%1, %P0|%P0, %1}
1687    mov{b}\t{%1, %a0|%a0, %1}"
1688   [(set_attr "type" "imov")
1689    (set_attr "modrm" "0,*")
1690    (set_attr "length_address" "8,0")
1691    (set_attr "length_immediate" "0,*")
1692    (set_attr "memory" "store")
1693    (set_attr "mode" "QI")])
1694
1695 (define_insn "*movabsqi_2_rex64"
1696   [(set (match_operand:QI 0 "register_operand" "=a,r")
1697         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1698   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1699   "@
1700    movabs{b}\t{%P1, %0|%0, %P1}
1701    mov{b}\t{%a1, %0|%0, %a1}"
1702   [(set_attr "type" "imov")
1703    (set_attr "modrm" "0,*")
1704    (set_attr "length_address" "8,0")
1705    (set_attr "length_immediate" "0")
1706    (set_attr "memory" "load")
1707    (set_attr "mode" "QI")])
1708
1709 (define_insn "*movdi_extzv_1"
1710   [(set (match_operand:DI 0 "register_operand" "=R")
1711         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1712                          (const_int 8)
1713                          (const_int 8)))]
1714   "TARGET_64BIT"
1715   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1716   [(set_attr "type" "imovx")
1717    (set_attr "mode" "DI")])
1718
1719 (define_insn "*movsi_extzv_1"
1720   [(set (match_operand:SI 0 "register_operand" "=R")
1721         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1722                          (const_int 8)
1723                          (const_int 8)))]
1724   ""
1725   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1726   [(set_attr "type" "imovx")
1727    (set_attr "mode" "SI")])
1728
1729 (define_insn "*movqi_extzv_2"
1730   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1731         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1732                                     (const_int 8)
1733                                     (const_int 8)) 0))]
1734   "!TARGET_64BIT"
1735 {
1736   switch (get_attr_type (insn))
1737     {
1738     case TYPE_IMOVX:
1739       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1740     default:
1741       return "mov{b}\t{%h1, %0|%0, %h1}";
1742     }
1743 }
1744   [(set (attr "type")
1745      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1746                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1747                              (ne (symbol_ref "TARGET_MOVX")
1748                                  (const_int 0))))
1749         (const_string "imovx")
1750         (const_string "imov")))
1751    (set (attr "mode")
1752      (if_then_else (eq_attr "type" "imovx")
1753         (const_string "SI")
1754         (const_string "QI")))])
1755
1756 (define_insn "*movqi_extzv_2_rex64"
1757   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1758         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1759                                     (const_int 8)
1760                                     (const_int 8)) 0))]
1761   "TARGET_64BIT"
1762 {
1763   switch (get_attr_type (insn))
1764     {
1765     case TYPE_IMOVX:
1766       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1767     default:
1768       return "mov{b}\t{%h1, %0|%0, %h1}";
1769     }
1770 }
1771   [(set (attr "type")
1772      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1773                         (ne (symbol_ref "TARGET_MOVX")
1774                             (const_int 0)))
1775         (const_string "imovx")
1776         (const_string "imov")))
1777    (set (attr "mode")
1778      (if_then_else (eq_attr "type" "imovx")
1779         (const_string "SI")
1780         (const_string "QI")))])
1781
1782 (define_insn "movsi_insv_1"
1783   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1784                          (const_int 8)
1785                          (const_int 8))
1786         (match_operand:SI 1 "general_operand" "Qmn"))]
1787   "!TARGET_64BIT"
1788   "mov{b}\t{%b1, %h0|%h0, %b1}"
1789   [(set_attr "type" "imov")
1790    (set_attr "mode" "QI")])
1791
1792 (define_insn "movdi_insv_1_rex64"
1793   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1794                          (const_int 8)
1795                          (const_int 8))
1796         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1797   "TARGET_64BIT"
1798   "mov{b}\t{%b1, %h0|%h0, %b1}"
1799   [(set_attr "type" "imov")
1800    (set_attr "mode" "QI")])
1801
1802 (define_insn "*movqi_insv_2"
1803   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1804                          (const_int 8)
1805                          (const_int 8))
1806         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1807                      (const_int 8)))]
1808   ""
1809   "mov{b}\t{%h1, %h0|%h0, %h1}"
1810   [(set_attr "type" "imov")
1811    (set_attr "mode" "QI")])
1812
1813 (define_expand "movdi"
1814   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1815         (match_operand:DI 1 "general_operand" ""))]
1816   ""
1817   "ix86_expand_move (DImode, operands); DONE;")
1818
1819 (define_insn "*pushdi"
1820   [(set (match_operand:DI 0 "push_operand" "=<")
1821         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1822   "!TARGET_64BIT"
1823   "#")
1824
1825 (define_insn "*pushdi2_rex64"
1826   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1827         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1828   "TARGET_64BIT"
1829   "@
1830    push{q}\t%1
1831    #"
1832   [(set_attr "type" "push,multi")
1833    (set_attr "mode" "DI")])
1834
1835 ;; Convert impossible pushes of immediate to existing instructions.
1836 ;; First try to get scratch register and go through it.  In case this
1837 ;; fails, push sign extended lower part first and then overwrite
1838 ;; upper part by 32bit move.
1839 (define_peephole2
1840   [(match_scratch:DI 2 "r")
1841    (set (match_operand:DI 0 "push_operand" "")
1842         (match_operand:DI 1 "immediate_operand" ""))]
1843   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1844    && !x86_64_immediate_operand (operands[1], DImode)"
1845   [(set (match_dup 2) (match_dup 1))
1846    (set (match_dup 0) (match_dup 2))]
1847   "")
1848
1849 ;; We need to define this as both peepholer and splitter for case
1850 ;; peephole2 pass is not run.
1851 ;; "&& 1" is needed to keep it from matching the previous pattern.
1852 (define_peephole2
1853   [(set (match_operand:DI 0 "push_operand" "")
1854         (match_operand:DI 1 "immediate_operand" ""))]
1855   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1856    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1857   [(set (match_dup 0) (match_dup 1))
1858    (set (match_dup 2) (match_dup 3))]
1859   "split_di (operands + 1, 1, operands + 2, operands + 3);
1860    operands[1] = gen_lowpart (DImode, operands[2]);
1861    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1862                                                     GEN_INT (4)));
1863   ")
1864
1865 (define_split
1866   [(set (match_operand:DI 0 "push_operand" "")
1867         (match_operand:DI 1 "immediate_operand" ""))]
1868   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1869                     ? flow2_completed : reload_completed)
1870    && !symbolic_operand (operands[1], DImode)
1871    && !x86_64_immediate_operand (operands[1], DImode)"
1872   [(set (match_dup 0) (match_dup 1))
1873    (set (match_dup 2) (match_dup 3))]
1874   "split_di (operands + 1, 1, operands + 2, operands + 3);
1875    operands[1] = gen_lowpart (DImode, operands[2]);
1876    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1877                                                     GEN_INT (4)));
1878   ")
1879
1880 (define_insn "*pushdi2_prologue_rex64"
1881   [(set (match_operand:DI 0 "push_operand" "=<")
1882         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1883    (clobber (mem:BLK (scratch)))]
1884   "TARGET_64BIT"
1885   "push{q}\t%1"
1886   [(set_attr "type" "push")
1887    (set_attr "mode" "DI")])
1888
1889 (define_insn "*popdi1_epilogue_rex64"
1890   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1891         (mem:DI (reg:DI SP_REG)))
1892    (set (reg:DI SP_REG)
1893         (plus:DI (reg:DI SP_REG) (const_int 8)))
1894    (clobber (mem:BLK (scratch)))]
1895   "TARGET_64BIT"
1896   "pop{q}\t%0"
1897   [(set_attr "type" "pop")
1898    (set_attr "mode" "DI")])
1899
1900 (define_insn "popdi1"
1901   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1902         (mem:DI (reg:DI SP_REG)))
1903    (set (reg:DI SP_REG)
1904         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1905   "TARGET_64BIT"
1906   "pop{q}\t%0"
1907   [(set_attr "type" "pop")
1908    (set_attr "mode" "DI")])
1909
1910 (define_insn "*movdi_xor_rex64"
1911   [(set (match_operand:DI 0 "register_operand" "=r")
1912         (match_operand:DI 1 "const0_operand" "i"))
1913    (clobber (reg:CC FLAGS_REG))]
1914   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1915    && reload_completed"
1916   "xor{l}\t{%k0, %k0|%k0, %k0}"
1917   [(set_attr "type" "alu1")
1918    (set_attr "mode" "SI")
1919    (set_attr "length_immediate" "0")])
1920
1921 (define_insn "*movdi_or_rex64"
1922   [(set (match_operand:DI 0 "register_operand" "=r")
1923         (match_operand:DI 1 "const_int_operand" "i"))
1924    (clobber (reg:CC FLAGS_REG))]
1925   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1926    && reload_completed
1927    && operands[1] == constm1_rtx"
1928 {
1929   operands[1] = constm1_rtx;
1930   return "or{q}\t{%1, %0|%0, %1}";
1931 }
1932   [(set_attr "type" "alu1")
1933    (set_attr "mode" "DI")
1934    (set_attr "length_immediate" "1")])
1935
1936 (define_insn "*movdi_2"
1937   [(set (match_operand:DI 0 "nonimmediate_operand"
1938                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1939         (match_operand:DI 1 "general_operand"
1940                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1941   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942   "@
1943    #
1944    #
1945    pxor\t%0, %0
1946    movq\t{%1, %0|%0, %1}
1947    movq\t{%1, %0|%0, %1}
1948    pxor\t%0, %0
1949    movq\t{%1, %0|%0, %1}
1950    movdqa\t{%1, %0|%0, %1}
1951    movq\t{%1, %0|%0, %1}
1952    xorps\t%0, %0
1953    movlps\t{%1, %0|%0, %1}
1954    movaps\t{%1, %0|%0, %1}
1955    movlps\t{%1, %0|%0, %1}"
1956   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1957    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1958
1959 (define_split
1960   [(set (match_operand:DI 0 "push_operand" "")
1961         (match_operand:DI 1 "general_operand" ""))]
1962   "!TARGET_64BIT && reload_completed
1963    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1964   [(const_int 0)]
1965   "ix86_split_long_move (operands); DONE;")
1966
1967 ;; %%% This multiword shite has got to go.
1968 (define_split
1969   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1970         (match_operand:DI 1 "general_operand" ""))]
1971   "!TARGET_64BIT && reload_completed
1972    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1973    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1974   [(const_int 0)]
1975   "ix86_split_long_move (operands); DONE;")
1976
1977 (define_insn "*movdi_1_rex64"
1978   [(set (match_operand:DI 0 "nonimmediate_operand"
1979                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1980         (match_operand:DI 1 "general_operand"
1981                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1982   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983 {
1984   switch (get_attr_type (insn))
1985     {
1986     case TYPE_SSECVT:
1987       if (which_alternative == 13)
1988         return "movq2dq\t{%1, %0|%0, %1}";
1989       else
1990         return "movdq2q\t{%1, %0|%0, %1}";
1991     case TYPE_SSEMOV:
1992       if (get_attr_mode (insn) == MODE_TI)
1993           return "movdqa\t{%1, %0|%0, %1}";
1994       /* FALLTHRU */
1995     case TYPE_MMXMOV:
1996       /* Moves from and into integer register is done using movd opcode with
1997          REX prefix.  */
1998       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1999           return "movd\t{%1, %0|%0, %1}";
2000       return "movq\t{%1, %0|%0, %1}";
2001     case TYPE_SSELOG1:
2002     case TYPE_MMXADD:
2003       return "pxor\t%0, %0";
2004     case TYPE_MULTI:
2005       return "#";
2006     case TYPE_LEA:
2007       return "lea{q}\t{%a1, %0|%0, %a1}";
2008     default:
2009       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2010       if (get_attr_mode (insn) == MODE_SI)
2011         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012       else if (which_alternative == 2)
2013         return "movabs{q}\t{%1, %0|%0, %1}";
2014       else
2015         return "mov{q}\t{%1, %0|%0, %1}";
2016     }
2017 }
2018   [(set (attr "type")
2019      (cond [(eq_attr "alternative" "5")
2020               (const_string "mmxadd")
2021             (eq_attr "alternative" "6,7,8")
2022               (const_string "mmxmov")
2023             (eq_attr "alternative" "9")
2024               (const_string "sselog1")
2025             (eq_attr "alternative" "10,11,12")
2026               (const_string "ssemov")
2027             (eq_attr "alternative" "13,14")
2028               (const_string "ssecvt")
2029             (eq_attr "alternative" "4")
2030               (const_string "multi")
2031             (match_operand:DI 1 "pic_32bit_operand" "")
2032               (const_string "lea")
2033            ]
2034            (const_string "imov")))
2035    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2036    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2037    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2038
2039 ;; Stores and loads of ax to arbitrary constant address.
2040 ;; We fake an second form of instruction to force reload to load address
2041 ;; into register when rax is not available
2042 (define_insn "*movabsdi_1_rex64"
2043   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2044         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2045   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2046   "@
2047    movabs{q}\t{%1, %P0|%P0, %1}
2048    mov{q}\t{%1, %a0|%a0, %1}"
2049   [(set_attr "type" "imov")
2050    (set_attr "modrm" "0,*")
2051    (set_attr "length_address" "8,0")
2052    (set_attr "length_immediate" "0,*")
2053    (set_attr "memory" "store")
2054    (set_attr "mode" "DI")])
2055
2056 (define_insn "*movabsdi_2_rex64"
2057   [(set (match_operand:DI 0 "register_operand" "=a,r")
2058         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2059   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2060   "@
2061    movabs{q}\t{%P1, %0|%0, %P1}
2062    mov{q}\t{%a1, %0|%0, %a1}"
2063   [(set_attr "type" "imov")
2064    (set_attr "modrm" "0,*")
2065    (set_attr "length_address" "8,0")
2066    (set_attr "length_immediate" "0")
2067    (set_attr "memory" "load")
2068    (set_attr "mode" "DI")])
2069
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it.  In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074   [(match_scratch:DI 2 "r")
2075    (set (match_operand:DI 0 "memory_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078    && !x86_64_immediate_operand (operands[1], DImode)"
2079   [(set (match_dup 2) (match_dup 1))
2080    (set (match_dup 0) (match_dup 2))]
2081   "")
2082
2083 ;; We need to define this as both peepholer and splitter for case
2084 ;; peephole2 pass is not run.
2085 ;; "&& 1" is needed to keep it from matching the previous pattern.
2086 (define_peephole2
2087   [(set (match_operand:DI 0 "memory_operand" "")
2088         (match_operand:DI 1 "immediate_operand" ""))]
2089   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2091   [(set (match_dup 2) (match_dup 3))
2092    (set (match_dup 4) (match_dup 5))]
2093   "split_di (operands, 2, operands + 2, operands + 4);")
2094
2095 (define_split
2096   [(set (match_operand:DI 0 "memory_operand" "")
2097         (match_operand:DI 1 "immediate_operand" ""))]
2098   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2099                     ? flow2_completed : reload_completed)
2100    && !symbolic_operand (operands[1], DImode)
2101    && !x86_64_immediate_operand (operands[1], DImode)"
2102   [(set (match_dup 2) (match_dup 3))
2103    (set (match_dup 4) (match_dup 5))]
2104   "split_di (operands, 2, operands + 2, operands + 4);")
2105
2106 (define_insn "*swapdi_rex64"
2107   [(set (match_operand:DI 0 "register_operand" "+r")
2108         (match_operand:DI 1 "register_operand" "+r"))
2109    (set (match_dup 1)
2110         (match_dup 0))]
2111   "TARGET_64BIT"
2112   "xchg{q}\t%1, %0"
2113   [(set_attr "type" "imov")
2114    (set_attr "mode" "DI")
2115    (set_attr "pent_pair" "np")
2116    (set_attr "athlon_decode" "vector")])
2117
2118 (define_expand "movti"
2119   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2120         (match_operand:TI 1 "nonimmediate_operand" ""))]
2121   "TARGET_SSE || TARGET_64BIT"
2122 {
2123   if (TARGET_64BIT)
2124     ix86_expand_move (TImode, operands);
2125   else
2126     ix86_expand_vector_move (TImode, operands);
2127   DONE;
2128 })
2129
2130 (define_insn "*movti_internal"
2131   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2132         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2133   "TARGET_SSE && !TARGET_64BIT
2134    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2135 {
2136   switch (which_alternative)
2137     {
2138     case 0:
2139       if (get_attr_mode (insn) == MODE_V4SF)
2140         return "xorps\t%0, %0";
2141       else
2142         return "pxor\t%0, %0";
2143     case 1:
2144     case 2:
2145       if (get_attr_mode (insn) == MODE_V4SF)
2146         return "movaps\t{%1, %0|%0, %1}";
2147       else
2148         return "movdqa\t{%1, %0|%0, %1}";
2149     default:
2150       gcc_unreachable ();
2151     }
2152 }
2153   [(set_attr "type" "sselog1,ssemov,ssemov")
2154    (set (attr "mode")
2155         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2156                     (ne (symbol_ref "optimize_size") (const_int 0)))
2157                  (const_string "V4SF")
2158                (and (eq_attr "alternative" "2")
2159                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2160                         (const_int 0)))
2161                  (const_string "V4SF")]
2162               (const_string "TI")))])
2163
2164 (define_insn "*movti_rex64"
2165   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2166         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2167   "TARGET_64BIT
2168    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2169 {
2170   switch (which_alternative)
2171     {
2172     case 0:
2173     case 1:
2174       return "#";
2175     case 2:
2176       if (get_attr_mode (insn) == MODE_V4SF)
2177         return "xorps\t%0, %0";
2178       else
2179         return "pxor\t%0, %0";
2180     case 3:
2181     case 4:
2182       if (get_attr_mode (insn) == MODE_V4SF)
2183         return "movaps\t{%1, %0|%0, %1}";
2184       else
2185         return "movdqa\t{%1, %0|%0, %1}";
2186     default:
2187       gcc_unreachable ();
2188     }
2189 }
2190   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2191    (set (attr "mode")
2192         (cond [(eq_attr "alternative" "2,3")
2193                  (if_then_else
2194                    (ne (symbol_ref "optimize_size")
2195                        (const_int 0))
2196                    (const_string "V4SF")
2197                    (const_string "TI"))
2198                (eq_attr "alternative" "4")
2199                  (if_then_else
2200                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2201                             (const_int 0))
2202                         (ne (symbol_ref "optimize_size")
2203                             (const_int 0)))
2204                    (const_string "V4SF")
2205                    (const_string "TI"))]
2206                (const_string "DI")))])
2207
2208 (define_split
2209   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2210         (match_operand:TI 1 "general_operand" ""))]
2211   "reload_completed && !SSE_REG_P (operands[0])
2212    && !SSE_REG_P (operands[1])"
2213   [(const_int 0)]
2214   "ix86_split_long_move (operands); DONE;")
2215
2216 (define_expand "movsf"
2217   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2218         (match_operand:SF 1 "general_operand" ""))]
2219   ""
2220   "ix86_expand_move (SFmode, operands); DONE;")
2221
2222 (define_insn "*pushsf"
2223   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2224         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2225   "!TARGET_64BIT"
2226 {
2227   /* Anything else should be already split before reg-stack.  */
2228   gcc_assert (which_alternative == 1);
2229   return "push{l}\t%1";
2230 }
2231   [(set_attr "type" "multi,push,multi")
2232    (set_attr "unit" "i387,*,*")
2233    (set_attr "mode" "SF,SI,SF")])
2234
2235 (define_insn "*pushsf_rex64"
2236   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2237         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2238   "TARGET_64BIT"
2239 {
2240   /* Anything else should be already split before reg-stack.  */
2241   gcc_assert (which_alternative == 1);
2242   return "push{q}\t%q1";
2243 }
2244   [(set_attr "type" "multi,push,multi")
2245    (set_attr "unit" "i387,*,*")
2246    (set_attr "mode" "SF,DI,SF")])
2247
2248 (define_split
2249   [(set (match_operand:SF 0 "push_operand" "")
2250         (match_operand:SF 1 "memory_operand" ""))]
2251   "reload_completed
2252    && GET_CODE (operands[1]) == MEM
2253    && constant_pool_reference_p (operands[1])"
2254   [(set (match_dup 0)
2255         (match_dup 1))]
2256   "operands[1] = avoid_constant_pool_reference (operands[1]);")
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,sselog1,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,sselog1,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,sselog1,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    && constant_pool_reference_p (operands[1])"
2867   [(set (match_dup 0) (match_dup 1))]
2868 {
2869   rtx c = avoid_constant_pool_reference (operands[1]);
2870   rtx r = operands[0];
2871
2872   if (GET_CODE (r) == SUBREG)
2873     r = SUBREG_REG (r);
2874
2875   if (SSE_REG_P (r))
2876     {
2877       if (!standard_sse_constant_p (c))
2878         FAIL;
2879     }
2880   else if (FP_REG_P (r))
2881     {
2882       if (!standard_80387_constant_p (c))
2883         FAIL;
2884     }
2885   else if (MMX_REG_P (r))
2886     FAIL;
2887
2888   operands[1] = c;
2889 })
2890
2891 (define_insn "swapxf"
2892   [(set (match_operand:XF 0 "register_operand" "+f")
2893         (match_operand:XF 1 "register_operand" "+f"))
2894    (set (match_dup 1)
2895         (match_dup 0))]
2896   "TARGET_80387"
2897 {
2898   if (STACK_TOP_P (operands[0]))
2899     return "fxch\t%1";
2900   else
2901     return "fxch\t%0";
2902 }
2903   [(set_attr "type" "fxch")
2904    (set_attr "mode" "XF")])
2905
2906 (define_expand "movtf"
2907   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2908         (match_operand:TF 1 "nonimmediate_operand" ""))]
2909   "TARGET_64BIT"
2910 {
2911   ix86_expand_move (TFmode, operands);
2912   DONE;
2913 })
2914
2915 (define_insn "*movtf_internal"
2916   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2917         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2918   "TARGET_64BIT
2919    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2920 {
2921   switch (which_alternative)
2922     {
2923     case 0:
2924     case 1:
2925       return "#";
2926     case 2:
2927       if (get_attr_mode (insn) == MODE_V4SF)
2928         return "xorps\t%0, %0";
2929       else
2930         return "pxor\t%0, %0";
2931     case 3:
2932     case 4:
2933       if (get_attr_mode (insn) == MODE_V4SF)
2934         return "movaps\t{%1, %0|%0, %1}";
2935       else
2936         return "movdqa\t{%1, %0|%0, %1}";
2937     default:
2938       gcc_unreachable ();
2939     }
2940 }
2941   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2942    (set (attr "mode")
2943         (cond [(eq_attr "alternative" "2,3")
2944                  (if_then_else
2945                    (ne (symbol_ref "optimize_size")
2946                        (const_int 0))
2947                    (const_string "V4SF")
2948                    (const_string "TI"))
2949                (eq_attr "alternative" "4")
2950                  (if_then_else
2951                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2952                             (const_int 0))
2953                         (ne (symbol_ref "optimize_size")
2954                             (const_int 0)))
2955                    (const_string "V4SF")
2956                    (const_string "TI"))]
2957                (const_string "DI")))])
2958
2959 (define_split
2960   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2961         (match_operand:TF 1 "general_operand" ""))]
2962   "reload_completed && !SSE_REG_P (operands[0])
2963    && !SSE_REG_P (operands[1])"
2964   [(const_int 0)]
2965   "ix86_split_long_move (operands); DONE;")
2966 \f
2967 ;; Zero extension instructions
2968
2969 (define_expand "zero_extendhisi2"
2970   [(set (match_operand:SI 0 "register_operand" "")
2971      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2972   ""
2973 {
2974   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2975     {
2976       operands[1] = force_reg (HImode, operands[1]);
2977       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2978       DONE;
2979     }
2980 })
2981
2982 (define_insn "zero_extendhisi2_and"
2983   [(set (match_operand:SI 0 "register_operand" "=r")
2984      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2985    (clobber (reg:CC FLAGS_REG))]
2986   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2987   "#"
2988   [(set_attr "type" "alu1")
2989    (set_attr "mode" "SI")])
2990
2991 (define_split
2992   [(set (match_operand:SI 0 "register_operand" "")
2993         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2994    (clobber (reg:CC FLAGS_REG))]
2995   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2996   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2997               (clobber (reg:CC FLAGS_REG))])]
2998   "")
2999
3000 (define_insn "*zero_extendhisi2_movzwl"
3001   [(set (match_operand:SI 0 "register_operand" "=r")
3002      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3003   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3004   "movz{wl|x}\t{%1, %0|%0, %1}"
3005   [(set_attr "type" "imovx")
3006    (set_attr "mode" "SI")])
3007
3008 (define_expand "zero_extendqihi2"
3009   [(parallel
3010     [(set (match_operand:HI 0 "register_operand" "")
3011        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3012      (clobber (reg:CC FLAGS_REG))])]
3013   ""
3014   "")
3015
3016 (define_insn "*zero_extendqihi2_and"
3017   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3018      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3019    (clobber (reg:CC FLAGS_REG))]
3020   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3021   "#"
3022   [(set_attr "type" "alu1")
3023    (set_attr "mode" "HI")])
3024
3025 (define_insn "*zero_extendqihi2_movzbw_and"
3026   [(set (match_operand:HI 0 "register_operand" "=r,r")
3027      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3028    (clobber (reg:CC FLAGS_REG))]
3029   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3030   "#"
3031   [(set_attr "type" "imovx,alu1")
3032    (set_attr "mode" "HI")])
3033
3034 ; zero extend to SImode here to avoid partial register stalls
3035 (define_insn "*zero_extendqihi2_movzbl"
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{bl|x}\t{%1, %k0|%k0, %k1}"
3040   [(set_attr "type" "imovx")
3041    (set_attr "mode" "SI")])
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"))