OSDN Git Service

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