OSDN Git Service

afcecdea930d20ee123dcf738b17b753d5b1f165
[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" "ssemov,ssemov,ssemov")
2152    (set (attr "mode")
2153         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2154                  (const_string "V4SF")
2155
2156                (eq_attr "alternative" "0,1")
2157                  (if_then_else
2158                    (ne (symbol_ref "optimize_size")
2159                        (const_int 0))
2160                    (const_string "V4SF")
2161                    (const_string "TI"))
2162                (eq_attr "alternative" "2")
2163                  (if_then_else
2164                    (ne (symbol_ref "optimize_size")
2165                        (const_int 0))
2166                    (const_string "V4SF")
2167                    (const_string "TI"))]
2168                (const_string "TI")))])
2169
2170 (define_insn "*movti_rex64"
2171   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2172         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2173   "TARGET_64BIT
2174    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2175 {
2176   switch (which_alternative)
2177     {
2178     case 0:
2179     case 1:
2180       return "#";
2181     case 2:
2182       if (get_attr_mode (insn) == MODE_V4SF)
2183         return "xorps\t%0, %0";
2184       else
2185         return "pxor\t%0, %0";
2186     case 3:
2187     case 4:
2188       if (get_attr_mode (insn) == MODE_V4SF)
2189         return "movaps\t{%1, %0|%0, %1}";
2190       else
2191         return "movdqa\t{%1, %0|%0, %1}";
2192     default:
2193       gcc_unreachable ();
2194     }
2195 }
2196   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2197    (set (attr "mode")
2198         (cond [(eq_attr "alternative" "2,3")
2199                  (if_then_else
2200                    (ne (symbol_ref "optimize_size")
2201                        (const_int 0))
2202                    (const_string "V4SF")
2203                    (const_string "TI"))
2204                (eq_attr "alternative" "4")
2205                  (if_then_else
2206                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2207                             (const_int 0))
2208                         (ne (symbol_ref "optimize_size")
2209                             (const_int 0)))
2210                    (const_string "V4SF")
2211                    (const_string "TI"))]
2212                (const_string "DI")))])
2213
2214 (define_split
2215   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2216         (match_operand:TI 1 "general_operand" ""))]
2217   "reload_completed && !SSE_REG_P (operands[0])
2218    && !SSE_REG_P (operands[1])"
2219   [(const_int 0)]
2220   "ix86_split_long_move (operands); DONE;")
2221
2222 (define_expand "movsf"
2223   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2224         (match_operand:SF 1 "general_operand" ""))]
2225   ""
2226   "ix86_expand_move (SFmode, operands); DONE;")
2227
2228 (define_insn "*pushsf"
2229   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2230         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2231   "!TARGET_64BIT"
2232 {
2233   /* Anything else should be already split before reg-stack.  */
2234   gcc_assert (which_alternative == 1);
2235   return "push{l}\t%1";
2236 }
2237   [(set_attr "type" "multi,push,multi")
2238    (set_attr "unit" "i387,*,*")
2239    (set_attr "mode" "SF,SI,SF")])
2240
2241 (define_insn "*pushsf_rex64"
2242   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2243         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2244   "TARGET_64BIT"
2245 {
2246   /* Anything else should be already split before reg-stack.  */
2247   gcc_assert (which_alternative == 1);
2248   return "push{q}\t%q1";
2249 }
2250   [(set_attr "type" "multi,push,multi")
2251    (set_attr "unit" "i387,*,*")
2252    (set_attr "mode" "SF,DI,SF")])
2253
2254 (define_split
2255   [(set (match_operand:SF 0 "push_operand" "")
2256         (match_operand:SF 1 "memory_operand" ""))]
2257   "reload_completed
2258    && GET_CODE (operands[1]) == MEM
2259    && constant_pool_reference_p (operands[1])"
2260   [(set (match_dup 0)
2261         (match_dup 1))]
2262   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2263
2264
2265 ;; %%% Kill this when call knows how to work this out.
2266 (define_split
2267   [(set (match_operand:SF 0 "push_operand" "")
2268         (match_operand:SF 1 "any_fp_register_operand" ""))]
2269   "!TARGET_64BIT"
2270   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2271    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2272
2273 (define_split
2274   [(set (match_operand:SF 0 "push_operand" "")
2275         (match_operand:SF 1 "any_fp_register_operand" ""))]
2276   "TARGET_64BIT"
2277   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2278    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2279
2280 (define_insn "*movsf_1"
2281   [(set (match_operand:SF 0 "nonimmediate_operand"
2282           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2283         (match_operand:SF 1 "general_operand"
2284           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2285   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2286    && (reload_in_progress || reload_completed
2287        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288        || GET_CODE (operands[1]) != CONST_DOUBLE
2289        || memory_operand (operands[0], SFmode))" 
2290 {
2291   switch (which_alternative)
2292     {
2293     case 0:
2294       return output_387_reg_move (insn, operands);
2295
2296     case 1:
2297       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298         return "fstp%z0\t%y0";
2299       else
2300         return "fst%z0\t%y0";
2301
2302     case 2:
2303       return standard_80387_constant_opcode (operands[1]);
2304
2305     case 3:
2306     case 4:
2307       return "mov{l}\t{%1, %0|%0, %1}";
2308     case 5:
2309       if (get_attr_mode (insn) == MODE_TI)
2310         return "pxor\t%0, %0";
2311       else
2312         return "xorps\t%0, %0";
2313     case 6:
2314       if (get_attr_mode (insn) == MODE_V4SF)
2315         return "movaps\t{%1, %0|%0, %1}";
2316       else
2317         return "movss\t{%1, %0|%0, %1}";
2318     case 7:
2319     case 8:
2320       return "movss\t{%1, %0|%0, %1}";
2321
2322     case 9:
2323     case 10:
2324       return "movd\t{%1, %0|%0, %1}";
2325
2326     case 11:
2327       return "movq\t{%1, %0|%0, %1}";
2328
2329     default:
2330       gcc_unreachable ();
2331     }
2332 }
2333   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334    (set (attr "mode")
2335         (cond [(eq_attr "alternative" "3,4,9,10")
2336                  (const_string "SI")
2337                (eq_attr "alternative" "5")
2338                  (if_then_else
2339                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340                                  (const_int 0))
2341                              (ne (symbol_ref "TARGET_SSE2")
2342                                  (const_int 0)))
2343                         (eq (symbol_ref "optimize_size")
2344                             (const_int 0)))
2345                    (const_string "TI")
2346                    (const_string "V4SF"))
2347                /* For architectures resolving dependencies on
2348                   whole SSE registers use APS move to break dependency
2349                   chains, otherwise use short move to avoid extra work. 
2350
2351                   Do the same for architectures resolving dependencies on
2352                   the parts.  While in DF mode it is better to always handle
2353                   just register parts, the SF mode is different due to lack
2354                   of instructions to load just part of the register.  It is
2355                   better to maintain the whole registers in single format
2356                   to avoid problems on using packed logical operations.  */
2357                (eq_attr "alternative" "6")
2358                  (if_then_else
2359                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360                             (const_int 0))
2361                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2362                             (const_int 0)))
2363                    (const_string "V4SF")
2364                    (const_string "SF"))
2365                (eq_attr "alternative" "11")
2366                  (const_string "DI")]
2367                (const_string "SF")))])
2368
2369 (define_insn "*swapsf"
2370   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2371         (match_operand:SF 1 "fp_register_operand" "+f"))
2372    (set (match_dup 1)
2373         (match_dup 0))]
2374   "reload_completed || TARGET_80387"
2375 {
2376   if (STACK_TOP_P (operands[0]))
2377     return "fxch\t%1";
2378   else
2379     return "fxch\t%0";
2380 }
2381   [(set_attr "type" "fxch")
2382    (set_attr "mode" "SF")])
2383
2384 (define_expand "movdf"
2385   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386         (match_operand:DF 1 "general_operand" ""))]
2387   ""
2388   "ix86_expand_move (DFmode, operands); DONE;")
2389
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter.  Allow this
2393 ;; pattern for optimize_size too.
2394
2395 (define_insn "*pushdf_nointeger"
2396   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2398   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2399 {
2400   /* This insn should be already split before reg-stack.  */
2401   gcc_unreachable ();
2402 }
2403   [(set_attr "type" "multi")
2404    (set_attr "unit" "i387,*,*,*")
2405    (set_attr "mode" "DF,SI,SI,DF")])
2406
2407 (define_insn "*pushdf_integer"
2408   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2409         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2410   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2411 {
2412   /* This insn should be already split before reg-stack.  */
2413   gcc_unreachable ();
2414 }
2415   [(set_attr "type" "multi")
2416    (set_attr "unit" "i387,*,*")
2417    (set_attr "mode" "DF,SI,DF")])
2418
2419 ;; %%% Kill this when call knows how to work this out.
2420 (define_split
2421   [(set (match_operand:DF 0 "push_operand" "")
2422         (match_operand:DF 1 "any_fp_register_operand" ""))]
2423   "!TARGET_64BIT && reload_completed"
2424   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2425    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2426   "")
2427
2428 (define_split
2429   [(set (match_operand:DF 0 "push_operand" "")
2430         (match_operand:DF 1 "any_fp_register_operand" ""))]
2431   "TARGET_64BIT && reload_completed"
2432   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2433    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2434   "")
2435
2436 (define_split
2437   [(set (match_operand:DF 0 "push_operand" "")
2438         (match_operand:DF 1 "general_operand" ""))]
2439   "reload_completed"
2440   [(const_int 0)]
2441   "ix86_split_long_move (operands); DONE;")
2442
2443 ;; Moving is usually shorter when only FP registers are used. This separate
2444 ;; movdf pattern avoids the use of integer registers for FP operations
2445 ;; when optimizing for size.
2446
2447 (define_insn "*movdf_nointeger"
2448   [(set (match_operand:DF 0 "nonimmediate_operand"
2449                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2450         (match_operand:DF 1 "general_operand"
2451                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2452   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2453    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2454    && (reload_in_progress || reload_completed
2455        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2456        || GET_CODE (operands[1]) != CONST_DOUBLE
2457        || memory_operand (operands[0], DFmode))" 
2458 {
2459   switch (which_alternative)
2460     {
2461     case 0:
2462       return output_387_reg_move (insn, operands);
2463
2464     case 1:
2465       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2466         return "fstp%z0\t%y0";
2467       else
2468         return "fst%z0\t%y0";
2469
2470     case 2:
2471       return standard_80387_constant_opcode (operands[1]);
2472
2473     case 3:
2474     case 4:
2475       return "#";
2476     case 5:
2477       switch (get_attr_mode (insn))
2478         {
2479         case MODE_V4SF:
2480           return "xorps\t%0, %0";
2481         case MODE_V2DF:
2482           return "xorpd\t%0, %0";
2483         case MODE_TI:
2484           return "pxor\t%0, %0";
2485         default:
2486           gcc_unreachable ();
2487         }
2488     case 6:
2489     case 7:
2490     case 8:
2491       switch (get_attr_mode (insn))
2492         {
2493         case MODE_V4SF:
2494           return "movaps\t{%1, %0|%0, %1}";
2495         case MODE_V2DF:
2496           return "movapd\t{%1, %0|%0, %1}";
2497         case MODE_TI:
2498           return "movdqa\t{%1, %0|%0, %1}";
2499         case MODE_DI:
2500           return "movq\t{%1, %0|%0, %1}";
2501         case MODE_DF:
2502           return "movsd\t{%1, %0|%0, %1}";
2503         case MODE_V1DF:
2504           return "movlpd\t{%1, %0|%0, %1}";
2505         case MODE_V2SF:
2506           return "movlps\t{%1, %0|%0, %1}";
2507         default:
2508           gcc_unreachable ();
2509         }
2510
2511     default:
2512       gcc_unreachable ();
2513     }
2514 }
2515   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2516    (set (attr "mode")
2517         (cond [(eq_attr "alternative" "0,1,2")
2518                  (const_string "DF")
2519                (eq_attr "alternative" "3,4")
2520                  (const_string "SI")
2521
2522                /* For SSE1, we have many fewer alternatives.  */
2523                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2524                  (cond [(eq_attr "alternative" "5,6")
2525                           (const_string "V4SF")
2526                        ]
2527                    (const_string "V2SF"))
2528
2529                /* xorps is one byte shorter.  */
2530                (eq_attr "alternative" "5")
2531                  (cond [(ne (symbol_ref "optimize_size")
2532                             (const_int 0))
2533                           (const_string "V4SF")
2534                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2535                             (const_int 0))
2536                           (const_string "TI")
2537                        ]
2538                        (const_string "V2DF"))
2539
2540                /* For architectures resolving dependencies on
2541                   whole SSE registers use APD move to break dependency
2542                   chains, otherwise use short move to avoid extra work.
2543
2544                   movaps encodes one byte shorter.  */
2545                (eq_attr "alternative" "6")
2546                  (cond
2547                    [(ne (symbol_ref "optimize_size")
2548                         (const_int 0))
2549                       (const_string "V4SF")
2550                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2551                         (const_int 0))
2552                       (const_string "V2DF")
2553                    ]
2554                    (const_string "DF"))
2555                /* For architectures resolving dependencies on register
2556                   parts we may avoid extra work to zero out upper part
2557                   of register.  */
2558                (eq_attr "alternative" "7")
2559                  (if_then_else
2560                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2561                        (const_int 0))
2562                    (const_string "V1DF")
2563                    (const_string "DF"))
2564               ]
2565               (const_string "DF")))])
2566
2567 (define_insn "*movdf_integer"
2568   [(set (match_operand:DF 0 "nonimmediate_operand"
2569                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2570         (match_operand:DF 1 "general_operand"
2571                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2572   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2573    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2574    && (reload_in_progress || reload_completed
2575        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2576        || GET_CODE (operands[1]) != CONST_DOUBLE
2577        || memory_operand (operands[0], DFmode))" 
2578 {
2579   switch (which_alternative)
2580     {
2581     case 0:
2582       return output_387_reg_move (insn, operands);
2583
2584     case 1:
2585       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2586         return "fstp%z0\t%y0";
2587       else
2588         return "fst%z0\t%y0";
2589
2590     case 2:
2591       return standard_80387_constant_opcode (operands[1]);
2592
2593     case 3:
2594     case 4:
2595       return "#";
2596
2597     case 5:
2598       switch (get_attr_mode (insn))
2599         {
2600         case MODE_V4SF:
2601           return "xorps\t%0, %0";
2602         case MODE_V2DF:
2603           return "xorpd\t%0, %0";
2604         case MODE_TI:
2605           return "pxor\t%0, %0";
2606         default:
2607           gcc_unreachable ();
2608         }
2609     case 6:
2610     case 7:
2611     case 8:
2612       switch (get_attr_mode (insn))
2613         {
2614         case MODE_V4SF:
2615           return "movaps\t{%1, %0|%0, %1}";
2616         case MODE_V2DF:
2617           return "movapd\t{%1, %0|%0, %1}";
2618         case MODE_TI:
2619           return "movdqa\t{%1, %0|%0, %1}";
2620         case MODE_DI:
2621           return "movq\t{%1, %0|%0, %1}";
2622         case MODE_DF:
2623           return "movsd\t{%1, %0|%0, %1}";
2624         case MODE_V1DF:
2625           return "movlpd\t{%1, %0|%0, %1}";
2626         case MODE_V2SF:
2627           return "movlps\t{%1, %0|%0, %1}";
2628         default:
2629           gcc_unreachable ();
2630         }
2631
2632     default:
2633       gcc_unreachable();
2634     }
2635 }
2636   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2637    (set (attr "mode")
2638         (cond [(eq_attr "alternative" "0,1,2")
2639                  (const_string "DF")
2640                (eq_attr "alternative" "3,4")
2641                  (const_string "SI")
2642
2643                /* For SSE1, we have many fewer alternatives.  */
2644                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2645                  (cond [(eq_attr "alternative" "5,6")
2646                           (const_string "V4SF")
2647                        ]
2648                    (const_string "V2SF"))
2649
2650                /* xorps is one byte shorter.  */
2651                (eq_attr "alternative" "5")
2652                  (cond [(ne (symbol_ref "optimize_size")
2653                             (const_int 0))
2654                           (const_string "V4SF")
2655                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2656                             (const_int 0))
2657                           (const_string "TI")
2658                        ]
2659                        (const_string "V2DF"))
2660
2661                /* For architectures resolving dependencies on
2662                   whole SSE registers use APD move to break dependency
2663                   chains, otherwise use short move to avoid extra work.
2664
2665                   movaps encodes one byte shorter.  */
2666                (eq_attr "alternative" "6")
2667                  (cond
2668                    [(ne (symbol_ref "optimize_size")
2669                         (const_int 0))
2670                       (const_string "V4SF")
2671                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2672                         (const_int 0))
2673                       (const_string "V2DF")
2674                    ]
2675                    (const_string "DF"))
2676                /* For architectures resolving dependencies on register
2677                   parts we may avoid extra work to zero out upper part
2678                   of register.  */
2679                (eq_attr "alternative" "7")
2680                  (if_then_else
2681                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2682                        (const_int 0))
2683                    (const_string "V1DF")
2684                    (const_string "DF"))
2685               ]
2686               (const_string "DF")))])
2687
2688 (define_split
2689   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2690         (match_operand:DF 1 "general_operand" ""))]
2691   "reload_completed
2692    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2693    && ! (ANY_FP_REG_P (operands[0]) || 
2694          (GET_CODE (operands[0]) == SUBREG
2695           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2696    && ! (ANY_FP_REG_P (operands[1]) || 
2697          (GET_CODE (operands[1]) == SUBREG
2698           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2699   [(const_int 0)]
2700   "ix86_split_long_move (operands); DONE;")
2701
2702 (define_insn "*swapdf"
2703   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2704         (match_operand:DF 1 "fp_register_operand" "+f"))
2705    (set (match_dup 1)
2706         (match_dup 0))]
2707   "reload_completed || TARGET_80387"
2708 {
2709   if (STACK_TOP_P (operands[0]))
2710     return "fxch\t%1";
2711   else
2712     return "fxch\t%0";
2713 }
2714   [(set_attr "type" "fxch")
2715    (set_attr "mode" "DF")])
2716
2717 (define_expand "movxf"
2718   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2719         (match_operand:XF 1 "general_operand" ""))]
2720   ""
2721   "ix86_expand_move (XFmode, operands); DONE;")
2722
2723 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2724 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2725 ;; Pushing using integer instructions is longer except for constants
2726 ;; and direct memory references.
2727 ;; (assuming that any given constant is pushed only once, but this ought to be
2728 ;;  handled elsewhere).
2729
2730 (define_insn "*pushxf_nointeger"
2731   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2732         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2733   "optimize_size"
2734 {
2735   /* This insn should be already split before reg-stack.  */
2736   gcc_unreachable ();
2737 }
2738   [(set_attr "type" "multi")
2739    (set_attr "unit" "i387,*,*")
2740    (set_attr "mode" "XF,SI,SI")])
2741
2742 (define_insn "*pushxf_integer"
2743   [(set (match_operand:XF 0 "push_operand" "=<,<")
2744         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2745   "!optimize_size"
2746 {
2747   /* This insn should be already split before reg-stack.  */
2748   gcc_unreachable ();
2749 }
2750   [(set_attr "type" "multi")
2751    (set_attr "unit" "i387,*")
2752    (set_attr "mode" "XF,SI")])
2753
2754 (define_split
2755   [(set (match_operand 0 "push_operand" "")
2756         (match_operand 1 "general_operand" ""))]
2757   "reload_completed
2758    && (GET_MODE (operands[0]) == XFmode
2759        || GET_MODE (operands[0]) == DFmode)
2760    && !ANY_FP_REG_P (operands[1])"
2761   [(const_int 0)]
2762   "ix86_split_long_move (operands); DONE;")
2763
2764 (define_split
2765   [(set (match_operand:XF 0 "push_operand" "")
2766         (match_operand:XF 1 "any_fp_register_operand" ""))]
2767   "!TARGET_64BIT"
2768   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2769    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2770   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2771
2772 (define_split
2773   [(set (match_operand:XF 0 "push_operand" "")
2774         (match_operand:XF 1 "any_fp_register_operand" ""))]
2775   "TARGET_64BIT"
2776   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2777    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2778   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2779
2780 ;; Do not use integer registers when optimizing for size
2781 (define_insn "*movxf_nointeger"
2782   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2783         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2784   "optimize_size
2785    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2786    && (reload_in_progress || reload_completed
2787        || GET_CODE (operands[1]) != CONST_DOUBLE
2788        || memory_operand (operands[0], XFmode))" 
2789 {
2790   switch (which_alternative)
2791     {
2792     case 0:
2793       return output_387_reg_move (insn, operands);
2794
2795     case 1:
2796       /* There is no non-popping store to memory for XFmode.  So if
2797          we need one, follow the store with a load.  */
2798       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2799         return "fstp%z0\t%y0\;fld%z0\t%y0";
2800       else
2801         return "fstp%z0\t%y0";
2802
2803     case 2:
2804       return standard_80387_constant_opcode (operands[1]);
2805
2806     case 3: case 4:
2807       return "#";
2808     default:
2809       gcc_unreachable ();
2810     }
2811 }
2812   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2813    (set_attr "mode" "XF,XF,XF,SI,SI")])
2814
2815 (define_insn "*movxf_integer"
2816   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2817         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2818   "!optimize_size
2819    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2820    && (reload_in_progress || reload_completed
2821        || GET_CODE (operands[1]) != CONST_DOUBLE
2822        || memory_operand (operands[0], XFmode))" 
2823 {
2824   switch (which_alternative)
2825     {
2826     case 0:
2827       return output_387_reg_move (insn, operands);
2828
2829     case 1:
2830       /* There is no non-popping store to memory for XFmode.  So if
2831          we need one, follow the store with a load.  */
2832       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2833         return "fstp%z0\t%y0\;fld%z0\t%y0";
2834       else
2835         return "fstp%z0\t%y0";
2836
2837     case 2:
2838       return standard_80387_constant_opcode (operands[1]);
2839
2840     case 3: case 4:
2841       return "#";
2842
2843     default:
2844       gcc_unreachable ();
2845     }
2846 }
2847   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2848    (set_attr "mode" "XF,XF,XF,SI,SI")])
2849
2850 (define_split
2851   [(set (match_operand 0 "nonimmediate_operand" "")
2852         (match_operand 1 "general_operand" ""))]
2853   "reload_completed
2854    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2855    && GET_MODE (operands[0]) == XFmode
2856    && ! (ANY_FP_REG_P (operands[0]) || 
2857          (GET_CODE (operands[0]) == SUBREG
2858           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2859    && ! (ANY_FP_REG_P (operands[1]) || 
2860          (GET_CODE (operands[1]) == SUBREG
2861           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2862   [(const_int 0)]
2863   "ix86_split_long_move (operands); DONE;")
2864
2865 (define_split
2866   [(set (match_operand 0 "register_operand" "")
2867         (match_operand 1 "memory_operand" ""))]
2868   "reload_completed
2869    && GET_CODE (operands[1]) == MEM
2870    && (GET_MODE (operands[0]) == XFmode
2871        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2872    && constant_pool_reference_p (operands[1])"
2873   [(set (match_dup 0) (match_dup 1))]
2874 {
2875   rtx c = avoid_constant_pool_reference (operands[1]);
2876   rtx r = operands[0];
2877
2878   if (GET_CODE (r) == SUBREG)
2879     r = SUBREG_REG (r);
2880
2881   if (SSE_REG_P (r))
2882     {
2883       if (!standard_sse_constant_p (c))
2884         FAIL;
2885     }
2886   else if (FP_REG_P (r))
2887     {
2888       if (!standard_80387_constant_p (c))
2889         FAIL;
2890     }
2891   else if (MMX_REG_P (r))
2892     FAIL;
2893
2894   operands[1] = c;
2895 })
2896
2897 (define_insn "swapxf"
2898   [(set (match_operand:XF 0 "register_operand" "+f")
2899         (match_operand:XF 1 "register_operand" "+f"))
2900    (set (match_dup 1)
2901         (match_dup 0))]
2902   "TARGET_80387"
2903 {
2904   if (STACK_TOP_P (operands[0]))
2905     return "fxch\t%1";
2906   else
2907     return "fxch\t%0";
2908 }
2909   [(set_attr "type" "fxch")
2910    (set_attr "mode" "XF")])
2911
2912 (define_expand "movtf"
2913   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2914         (match_operand:TF 1 "nonimmediate_operand" ""))]
2915   "TARGET_64BIT"
2916 {
2917   ix86_expand_move (TFmode, operands);
2918   DONE;
2919 })
2920
2921 (define_insn "*movtf_internal"
2922   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2923         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2924   "TARGET_64BIT
2925    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2926 {
2927   switch (which_alternative)
2928     {
2929     case 0:
2930     case 1:
2931       return "#";
2932     case 2:
2933       if (get_attr_mode (insn) == MODE_V4SF)
2934         return "xorps\t%0, %0";
2935       else
2936         return "pxor\t%0, %0";
2937     case 3:
2938     case 4:
2939       if (get_attr_mode (insn) == MODE_V4SF)
2940         return "movaps\t{%1, %0|%0, %1}";
2941       else
2942         return "movdqa\t{%1, %0|%0, %1}";
2943     default:
2944       gcc_unreachable ();
2945     }
2946 }
2947   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2948    (set (attr "mode")
2949         (cond [(eq_attr "alternative" "2,3")
2950                  (if_then_else
2951                    (ne (symbol_ref "optimize_size")
2952                        (const_int 0))
2953                    (const_string "V4SF")
2954                    (const_string "TI"))
2955                (eq_attr "alternative" "4")
2956                  (if_then_else
2957                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2958                             (const_int 0))
2959                         (ne (symbol_ref "optimize_size")
2960                             (const_int 0)))
2961                    (const_string "V4SF")
2962                    (const_string "TI"))]
2963                (const_string "DI")))])
2964
2965 (define_split
2966   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2967         (match_operand:TF 1 "general_operand" ""))]
2968   "reload_completed && !SSE_REG_P (operands[0])
2969    && !SSE_REG_P (operands[1])"
2970   [(const_int 0)]
2971   "ix86_split_long_move (operands); DONE;")
2972 \f
2973 ;; Zero extension instructions
2974
2975 (define_expand "zero_extendhisi2"
2976   [(set (match_operand:SI 0 "register_operand" "")
2977      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2978   ""
2979 {
2980   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2981     {
2982       operands[1] = force_reg (HImode, operands[1]);
2983       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2984       DONE;
2985     }
2986 })
2987
2988 (define_insn "zero_extendhisi2_and"
2989   [(set (match_operand:SI 0 "register_operand" "=r")
2990      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2991    (clobber (reg:CC FLAGS_REG))]
2992   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2993   "#"
2994   [(set_attr "type" "alu1")
2995    (set_attr "mode" "SI")])
2996
2997 (define_split
2998   [(set (match_operand:SI 0 "register_operand" "")
2999         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3000    (clobber (reg:CC FLAGS_REG))]
3001   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3002   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3003               (clobber (reg:CC FLAGS_REG))])]
3004   "")
3005
3006 (define_insn "*zero_extendhisi2_movzwl"
3007   [(set (match_operand:SI 0 "register_operand" "=r")
3008      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3009   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3010   "movz{wl|x}\t{%1, %0|%0, %1}"
3011   [(set_attr "type" "imovx")
3012    (set_attr "mode" "SI")])
3013
3014 (define_expand "zero_extendqihi2"
3015   [(parallel
3016     [(set (match_operand:HI 0 "register_operand" "")
3017        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3018      (clobber (reg:CC FLAGS_REG))])]
3019   ""
3020   "")
3021
3022 (define_insn "*zero_extendqihi2_and"
3023   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3024      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3025    (clobber (reg:CC FLAGS_REG))]
3026   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3027   "#"
3028   [(set_attr "type" "alu1")
3029    (set_attr "mode" "HI")])
3030
3031 (define_insn "*zero_extendqihi2_movzbw_and"
3032   [(set (match_operand:HI 0 "register_operand" "=r,r")
3033      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3034    (clobber (reg:CC FLAGS_REG))]
3035   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3036   "#"
3037   [(set_attr "type" "imovx,alu1")
3038    (set_attr "mode" "HI")])
3039
3040 ; zero extend to SImode here to avoid partial register stalls
3041 (define_insn "*zero_extendqihi2_movzbl"
3042   [(set (match_operand:HI 0 "register_operand" "=r")
3043      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3044   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3045   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3046   [(set_attr "type" "imovx")
3047    (set_attr "mode" "SI")])
3048
3049 ;; For the movzbw case strip only the clobber
3050 (define_split
3051   [(set (match_operand:HI 0 "register_operand" "")
3052         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3053    (clobber (reg:CC FLAGS_REG))]
3054   "reload_completed 
3055    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3056    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3057   [(set (match_operand:HI 0 "register_operand" "")
3058         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3059
3060 ;; When source and destination does not overlap, clear destination
3061 ;; first and then do the movb
3062 (define_split
3063   [(set (match_operand:HI 0 "register_operand" "")
3064         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3065    (clobber (reg:CC FLAGS_REG))]
3066   "reload_completed
3067    && ANY_QI_REG_P (operands[0])
3068    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3069    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3070   [(set (match_dup 0) (const_int 0))
3071    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3072   "operands[2] = gen_lowpart (QImode, operands[0]);")
3073
3074 ;; Rest is handled by single and.
3075 (define_split
3076   [(set (match_operand:HI 0 "register_operand" "")
3077         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3078    (clobber (reg:CC FLAGS_REG))]
3079   "reload_completed
3080    && true_regnum (operands[0]) == true_regnum (operands[1])"
3081   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3082               (clobber (reg:CC FLAGS_REG))])]
3083   "")
3084
3085 (define_expand "zero_extendqisi2"
3086   [(parallel
3087     [(set (match_operand:SI 0 "register_operand" "")
3088        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3089      (clobber (reg:CC FLAGS_REG))])]
3090   ""
3091   "")
3092
3093 (define_insn "*zero_extendqisi2_and"
3094   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3095      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3096    (clobber (reg:CC FLAGS_REG))]
3097   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3098   "#"
3099   [(set_attr "type" "alu1")
3100    (set_attr "mode" "SI")])
3101
3102 (define_insn "*zero_extendqisi2_movzbw_and"
3103   [(set (match_operand:SI 0 "register_operand" "=r,r")
3104      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3105    (clobber (reg:CC FLAGS_REG))]
3106   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3107   "#"
3108   [(set_attr "type" "imovx,alu1")
3109    (set_attr "mode" "SI")])
3110
3111 (define_insn "*zero_extendqisi2_movzbw"
3112   [(set (match_operand:SI 0 "register_operand" "=r")
3113      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3114   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3115   "movz{bl|x}\t{%1, %0|%0, %1}"
3116   [(set_attr "type" "imovx")
3117    (set_attr "mode" "SI")])
3118
3119 ;; For the movzbl case strip only the clobber
3120 (define_split
3121   [(set (match_operand:SI 0 "register_operand" "")
3122         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3123    (clobber (reg:CC FLAGS_REG))]
3124   "reload_completed 
3125    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3126    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3127   [(set (match_dup 0)
3128         (zero_extend:SI (match_dup 1)))])
3129
3130 ;; When source and destination does not overlap, clear destination
3131 ;; first and then do the movb
3132 (define_split
3133   [(set (match_operand:SI 0 "register_operand" "")
3134         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3135    (clobber (reg:CC FLAGS_REG))]
3136   "reload_completed
3137    && ANY_QI_REG_P (operands[0])
3138    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3139    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3140    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3141   [(set (match_dup 0) (const_int 0))
3142    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3143   "operands[2] = gen_lowpart (QImode, operands[0]);")
3144
3145 ;; Rest is handled by single and.
3146 (define_split
3147   [(set (match_operand:SI 0 "register_operand" "")
3148         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3149    (clobber (reg:CC FLAGS_REG))]
3150   "reload_completed
3151    && true_regnum (operands[0]) == true_regnum (operands[1])"
3152   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3153               (clobber (reg:CC FLAGS_REG))])]
3154   "")
3155
3156 ;; %%% Kill me once multi-word ops are sane.
3157 (define_expand "zero_extendsidi2"
3158   [(set (match_operand:DI 0 "register_operand" "=r")
3159      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3160   ""
3161   "if (!TARGET_64BIT)
3162      {
3163        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3164        DONE;
3165      }
3166   ")
3167
3168 (define_insn "zero_extendsidi2_32"
3169   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3170         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3171    (clobber (reg:CC FLAGS_REG))]
3172   "!TARGET_64BIT"
3173   "@
3174    #
3175    #
3176    #
3177    movd\t{%1, %0|%0, %1}
3178    movd\t{%1, %0|%0, %1}"
3179   [(set_attr "mode" "SI,SI,SI,DI,TI")
3180    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3181
3182 (define_insn "zero_extendsidi2_rex64"
3183   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3184      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3185   "TARGET_64BIT"
3186   "@
3187    mov\t{%k1, %k0|%k0, %k1}
3188    #
3189    movd\t{%1, %0|%0, %1}
3190    movd\t{%1, %0|%0, %1}"
3191   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3192    (set_attr "mode" "SI,DI,SI,SI")])
3193
3194 (define_split
3195   [(set (match_operand:DI 0 "memory_operand" "")
3196      (zero_extend:DI (match_dup 0)))]
3197   "TARGET_64BIT"
3198   [(set (match_dup 4) (const_int 0))]
3199   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3200
3201 (define_split 
3202   [(set (match_operand:DI 0 "register_operand" "")
3203         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3204    (clobber (reg:CC FLAGS_REG))]
3205   "!TARGET_64BIT && reload_completed
3206    && true_regnum (operands[0]) == true_regnum (operands[1])"
3207   [(set (match_dup 4) (const_int 0))]
3208   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3209
3210 (define_split 
3211   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3212         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3213    (clobber (reg:CC FLAGS_REG))]
3214   "!TARGET_64BIT && reload_completed
3215    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3216   [(set (match_dup 3) (match_dup 1))
3217    (set (match_dup 4) (const_int 0))]
3218   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3219
3220 (define_insn "zero_extendhidi2"
3221   [(set (match_operand:DI 0 "register_operand" "=r")
3222      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3223   "TARGET_64BIT"
3224   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3225   [(set_attr "type" "imovx")
3226    (set_attr "mode" "DI")])
3227
3228 (define_insn "zero_extendqidi2"
3229   [(set (match_operand:DI 0 "register_operand" "=r")
3230      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3231   "TARGET_64BIT"
3232   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3233   [(set_attr "type" "imovx")
3234    (set_attr "mode" "DI")])
3235 \f
3236 ;; Sign extension instructions
3237
3238 (define_expand "extendsidi2"
3239   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3240                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3241               (clobber (reg:CC FLAGS_REG))
3242               (clobber (match_scratch:SI 2 ""))])]
3243   ""
3244 {
3245   if (TARGET_64BIT)
3246     {
3247       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3248       DONE;
3249     }
3250 })
3251
3252 (define_insn "*extendsidi2_1"
3253   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3254         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3255    (clobber (reg:CC FLAGS_REG))
3256    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3257   "!TARGET_64BIT"
3258   "#")
3259
3260 (define_insn "extendsidi2_rex64"
3261   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3262         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3263   "TARGET_64BIT"
3264   "@
3265    {cltq|cdqe}
3266    movs{lq|x}\t{%1,%0|%0, %1}"
3267   [(set_attr "type" "imovx")
3268    (set_attr "mode" "DI")
3269    (set_attr "prefix_0f" "0")
3270    (set_attr "modrm" "0,1")])
3271
3272 (define_insn "extendhidi2"
3273   [(set (match_operand:DI 0 "register_operand" "=r")
3274         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3275   "TARGET_64BIT"
3276   "movs{wq|x}\t{%1,%0|%0, %1}"
3277   [(set_attr "type" "imovx")
3278    (set_attr "mode" "DI")])
3279
3280 (define_insn "extendqidi2"
3281   [(set (match_operand:DI 0 "register_operand" "=r")
3282         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3283   "TARGET_64BIT"
3284   "movs{bq|x}\t{%1,%0|%0, %1}"
3285    [(set_attr "type" "imovx")
3286     (set_attr "mode" "DI")])
3287
3288 ;; Extend to memory case when source register does die.
3289 (define_split 
3290   [(set (match_operand:DI 0 "memory_operand" "")
3291         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3292    (clobber (reg:CC FLAGS_REG))
3293    (clobber (match_operand:SI 2 "register_operand" ""))]
3294   "(reload_completed
3295     && dead_or_set_p (insn, operands[1])
3296     && !reg_mentioned_p (operands[1], operands[0]))"
3297   [(set (match_dup 3) (match_dup 1))
3298    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3299               (clobber (reg:CC FLAGS_REG))])
3300    (set (match_dup 4) (match_dup 1))]
3301   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3302
3303 ;; Extend to memory case when source register does not die.
3304 (define_split 
3305   [(set (match_operand:DI 0 "memory_operand" "")
3306         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3307    (clobber (reg:CC FLAGS_REG))
3308    (clobber (match_operand:SI 2 "register_operand" ""))]
3309   "reload_completed"
3310   [(const_int 0)]
3311 {
3312   split_di (&operands[0], 1, &operands[3], &operands[4]);
3313
3314   emit_move_insn (operands[3], operands[1]);
3315
3316   /* Generate a cltd if possible and doing so it profitable.  */
3317   if (true_regnum (operands[1]) == 0
3318       && true_regnum (operands[2]) == 1
3319       && (optimize_size || TARGET_USE_CLTD))
3320     {
3321       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3322     }
3323   else
3324     {
3325       emit_move_insn (operands[2], operands[1]);
3326       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3327     }
3328   emit_move_insn (operands[4], operands[2]);
3329   DONE;
3330 })
3331
3332 ;; Extend to register case.  Optimize case where source and destination
3333 ;; registers match and cases where we can use cltd.
3334 (define_split 
3335   [(set (match_operand:DI 0 "register_operand" "")
3336         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3337    (clobber (reg:CC FLAGS_REG))
3338    (clobber (match_scratch:SI 2 ""))]
3339   "reload_completed"
3340   [(const_int 0)]
3341 {
3342   split_di (&operands[0], 1, &operands[3], &operands[4]);
3343
3344   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3345     emit_move_insn (operands[3], operands[1]);
3346
3347   /* Generate a cltd if possible and doing so it profitable.  */
3348   if (true_regnum (operands[3]) == 0
3349       && (optimize_size || TARGET_USE_CLTD))
3350     {
3351       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3352       DONE;
3353     }
3354
3355   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3356     emit_move_insn (operands[4], operands[1]);
3357
3358   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3359   DONE;
3360 })
3361
3362 (define_insn "extendhisi2"
3363   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3364         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3365   ""
3366 {
3367   switch (get_attr_prefix_0f (insn))
3368     {
3369     case 0:
3370       return "{cwtl|cwde}";
3371     default:
3372       return "movs{wl|x}\t{%1,%0|%0, %1}";
3373     }
3374 }
3375   [(set_attr "type" "imovx")
3376    (set_attr "mode" "SI")
3377    (set (attr "prefix_0f")
3378      ;; movsx is short decodable while cwtl is vector decoded.
3379      (if_then_else (and (eq_attr "cpu" "!k6")
3380                         (eq_attr "alternative" "0"))
3381         (const_string "0")
3382         (const_string "1")))
3383    (set (attr "modrm")
3384      (if_then_else (eq_attr "prefix_0f" "0")
3385         (const_string "0")
3386         (const_string "1")))])
3387
3388 (define_insn "*extendhisi2_zext"
3389   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3390         (zero_extend:DI
3391           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3392   "TARGET_64BIT"
3393 {
3394   switch (get_attr_prefix_0f (insn))
3395     {
3396     case 0:
3397       return "{cwtl|cwde}";
3398     default:
3399       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3400     }
3401 }
3402   [(set_attr "type" "imovx")
3403    (set_attr "mode" "SI")
3404    (set (attr "prefix_0f")
3405      ;; movsx is short decodable while cwtl is vector decoded.
3406      (if_then_else (and (eq_attr "cpu" "!k6")
3407                         (eq_attr "alternative" "0"))
3408         (const_string "0")
3409         (const_string "1")))
3410    (set (attr "modrm")
3411      (if_then_else (eq_attr "prefix_0f" "0")
3412         (const_string "0")
3413         (const_string "1")))])
3414
3415 (define_insn "extendqihi2"
3416   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3417         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3418   ""
3419 {
3420   switch (get_attr_prefix_0f (insn))
3421     {
3422     case 0:
3423       return "{cbtw|cbw}";
3424     default:
3425       return "movs{bw|x}\t{%1,%0|%0, %1}";
3426     }
3427 }
3428   [(set_attr "type" "imovx")
3429    (set_attr "mode" "HI")
3430    (set (attr "prefix_0f")
3431      ;; movsx is short decodable while cwtl is vector decoded.
3432      (if_then_else (and (eq_attr "cpu" "!k6")
3433                         (eq_attr "alternative" "0"))
3434         (const_string "0")
3435         (const_string "1")))
3436    (set (attr "modrm")
3437      (if_then_else (eq_attr "prefix_0f" "0")
3438         (const_string "0")
3439         (const_string "1")))])
3440
3441 (define_insn "extendqisi2"
3442   [(set (match_operand:SI 0 "register_operand" "=r")
3443         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3444   ""
3445   "movs{bl|x}\t{%1,%0|%0, %1}"
3446    [(set_attr "type" "imovx")
3447     (set_attr "mode" "SI")])
3448
3449 (define_insn "*extendqisi2_zext"
3450   [(set (match_operand:DI 0 "register_operand" "=r")
3451         (zero_extend:DI
3452           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3453   "TARGET_64BIT"
3454   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3455    [(set_attr "type" "imovx")
3456     (set_attr "mode" "SI")])
3457 \f
3458 ;; Conversions between float and double.
3459
3460 ;; These are all no-ops in the model used for the 80387.  So just
3461 ;; emit moves.
3462
3463 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3464 (define_insn "*dummy_extendsfdf2"
3465   [(set (match_operand:DF 0 "push_operand" "=<")
3466         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3467   "0"
3468   "#")
3469
3470 (define_split
3471   [(set (match_operand:DF 0 "push_operand" "")
3472         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3473   "!TARGET_64BIT"
3474   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3475    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3476
3477 (define_split
3478   [(set (match_operand:DF 0 "push_operand" "")
3479         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3480   "TARGET_64BIT"
3481   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3482    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3483
3484 (define_insn "*dummy_extendsfxf2"
3485   [(set (match_operand:XF 0 "push_operand" "=<")
3486         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3487   "0"
3488   "#")
3489
3490 (define_split
3491   [(set (match_operand:XF 0 "push_operand" "")
3492         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3493   ""
3494   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3495    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3496   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3497
3498 (define_split
3499   [(set (match_operand:XF 0 "push_operand" "")
3500         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3501   "TARGET_64BIT"
3502   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3503    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3504   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3505
3506 (define_split
3507   [(set (match_operand:XF 0 "push_operand" "")
3508         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3509   ""
3510   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3511    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3512   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3513
3514 (define_split
3515   [(set (match_operand:XF 0 "push_operand" "")
3516         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3517   "TARGET_64BIT"
3518   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3519    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3520   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3521
3522 (define_expand "extendsfdf2"
3523   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3524         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3525   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3526 {
3527   /* ??? Needed for compress_float_constant since all fp constants
3528      are LEGITIMATE_CONSTANT_P.  */
3529   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3530     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3531   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3532     operands[1] = force_reg (SFmode, operands[1]);
3533 })
3534
3535 (define_insn "*extendsfdf2_mixed"
3536   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3537         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3538   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3539    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3540 {
3541   switch (which_alternative)
3542     {
3543     case 0:
3544       return output_387_reg_move (insn, operands);
3545
3546     case 1:
3547       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3548         return "fstp%z0\t%y0";
3549       else
3550         return "fst%z0\t%y0";
3551
3552     case 2:
3553       return "cvtss2sd\t{%1, %0|%0, %1}";
3554
3555     default:
3556       gcc_unreachable ();
3557     }
3558 }
3559   [(set_attr "type" "fmov,fmov,ssecvt")
3560    (set_attr "mode" "SF,XF,DF")])
3561
3562 (define_insn "*extendsfdf2_sse"
3563   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3564         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3565   "TARGET_SSE2 && TARGET_SSE_MATH
3566    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3567   "cvtss2sd\t{%1, %0|%0, %1}"
3568   [(set_attr "type" "ssecvt")
3569    (set_attr "mode" "DF")])
3570
3571 (define_insn "*extendsfdf2_i387"
3572   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3573         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3574   "TARGET_80387
3575    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3576 {
3577   switch (which_alternative)
3578     {
3579     case 0:
3580       return output_387_reg_move (insn, operands);
3581
3582     case 1:
3583       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3584         return "fstp%z0\t%y0";
3585       else
3586         return "fst%z0\t%y0";
3587
3588     default:
3589       gcc_unreachable ();
3590     }
3591 }
3592   [(set_attr "type" "fmov")
3593    (set_attr "mode" "SF,XF")])
3594
3595 (define_expand "extendsfxf2"
3596   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3597         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3598   "TARGET_80387"
3599 {
3600   /* ??? Needed for compress_float_constant since all fp constants
3601      are LEGITIMATE_CONSTANT_P.  */
3602   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3603     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3604   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3605     operands[1] = force_reg (SFmode, operands[1]);
3606 })
3607
3608 (define_insn "*extendsfxf2_i387"
3609   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3610         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3611   "TARGET_80387
3612    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3613 {
3614   switch (which_alternative)
3615     {
3616     case 0:
3617       return output_387_reg_move (insn, operands);
3618
3619     case 1:
3620       /* There is no non-popping store to memory for XFmode.  So if
3621          we need one, follow the store with a load.  */
3622       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3623         return "fstp%z0\t%y0";
3624       else
3625         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3626
3627     default:
3628       gcc_unreachable ();
3629     }
3630 }
3631   [(set_attr "type" "fmov")
3632    (set_attr "mode" "SF,XF")])
3633
3634 (define_expand "extenddfxf2"
3635   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3636         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3637   "TARGET_80387"
3638 {
3639   /* ??? Needed for compress_float_constant since all fp constants
3640      are LEGITIMATE_CONSTANT_P.  */
3641   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3642     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3643   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3644     operands[1] = force_reg (DFmode, operands[1]);
3645 })
3646
3647 (define_insn "*extenddfxf2_i387"
3648   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3649         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3650   "TARGET_80387
3651    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3652 {
3653   switch (which_alternative)
3654     {
3655     case 0:
3656       return output_387_reg_move (insn, operands);
3657
3658     case 1:
3659       /* There is no non-popping store to memory for XFmode.  So if
3660          we need one, follow the store with a load.  */
3661       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3662         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3663       else
3664         return "fstp%z0\t%y0";
3665
3666     default:
3667       gcc_unreachable ();
3668     }
3669 }
3670   [(set_attr "type" "fmov")
3671    (set_attr "mode" "DF,XF")])
3672
3673 ;; %%% This seems bad bad news.
3674 ;; This cannot output into an f-reg because there is no way to be sure
3675 ;; of truncating in that case.  Otherwise this is just like a simple move
3676 ;; insn.  So we pretend we can output to a reg in order to get better
3677 ;; register preferencing, but we really use a stack slot.
3678
3679 ;; Conversion from DFmode to SFmode.
3680
3681 (define_expand "truncdfsf2"
3682   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3683         (float_truncate:SF
3684           (match_operand:DF 1 "nonimmediate_operand" "")))]
3685   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3686 {
3687   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3688     operands[1] = force_reg (DFmode, operands[1]);
3689
3690   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3691     ;
3692   else if (flag_unsafe_math_optimizations)
3693     ;
3694   else
3695     {
3696       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3697       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3698       DONE;
3699     }
3700 })
3701
3702 (define_expand "truncdfsf2_with_temp"
3703   [(parallel [(set (match_operand:SF 0 "" "")
3704                    (float_truncate:SF (match_operand:DF 1 "" "")))
3705               (clobber (match_operand:SF 2 "" ""))])]
3706   "")
3707
3708 (define_insn "*truncdfsf_fast_mixed"
3709   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3710         (float_truncate:SF
3711           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3712   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3713 {
3714   switch (which_alternative)
3715     {
3716     case 0:
3717       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3718         return "fstp%z0\t%y0";
3719       else
3720         return "fst%z0\t%y0";
3721     case 1:
3722       return output_387_reg_move (insn, operands);
3723     case 2:
3724       return "cvtsd2ss\t{%1, %0|%0, %1}";
3725     default:
3726       gcc_unreachable ();
3727     }
3728 }
3729   [(set_attr "type" "fmov,fmov,ssecvt")
3730    (set_attr "mode" "SF")])
3731
3732 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3733 ;; because nothing we do here is unsafe.
3734 (define_insn "*truncdfsf_fast_sse"
3735   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3736         (float_truncate:SF
3737           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3738   "TARGET_SSE2 && TARGET_SSE_MATH"
3739   "cvtsd2ss\t{%1, %0|%0, %1}"
3740   [(set_attr "type" "ssecvt")
3741    (set_attr "mode" "SF")])
3742
3743 (define_insn "*truncdfsf_fast_i387"
3744   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3745         (float_truncate:SF
3746           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3747   "TARGET_80387 && flag_unsafe_math_optimizations"
3748   "* return output_387_reg_move (insn, operands);"
3749   [(set_attr "type" "fmov")
3750    (set_attr "mode" "SF")])
3751
3752 (define_insn "*truncdfsf_mixed"
3753   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3754         (float_truncate:SF
3755           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3756    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3757   "TARGET_MIX_SSE_I387"
3758 {
3759   switch (which_alternative)
3760     {
3761     case 0:
3762       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3763         return "fstp%z0\t%y0";
3764       else
3765         return "fst%z0\t%y0";
3766     case 1:
3767       return "#";
3768     case 2:
3769       return "cvtsd2ss\t{%1, %0|%0, %1}";
3770     default:
3771       gcc_unreachable ();
3772     }
3773 }
3774   [(set_attr "type" "fmov,multi,ssecvt")
3775    (set_attr "unit" "*,i387,*")
3776    (set_attr "mode" "SF")])
3777
3778 (define_insn "*truncdfsf_i387"
3779   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3780         (float_truncate:SF
3781           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3782    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3783   "TARGET_80387"
3784 {
3785   switch (which_alternative)
3786     {
3787     case 0:
3788       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3789         return "fstp%z0\t%y0";
3790       else
3791         return "fst%z0\t%y0";
3792     case 1:
3793       return "#";
3794     default:
3795       gcc_unreachable ();
3796     }
3797 }
3798   [(set_attr "type" "fmov,multi")
3799    (set_attr "unit" "*,i387")
3800    (set_attr "mode" "SF")])
3801
3802 (define_insn "*truncdfsf2_i387_1"
3803   [(set (match_operand:SF 0 "memory_operand" "=m")
3804         (float_truncate:SF
3805           (match_operand:DF 1 "register_operand" "f")))]
3806   "TARGET_80387
3807    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3808    && !TARGET_MIX_SSE_I387"
3809 {
3810   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3811     return "fstp%z0\t%y0";
3812   else
3813     return "fst%z0\t%y0";
3814 }
3815   [(set_attr "type" "fmov")
3816    (set_attr "mode" "SF")])
3817
3818 (define_split
3819   [(set (match_operand:SF 0 "register_operand" "")
3820         (float_truncate:SF
3821          (match_operand:DF 1 "fp_register_operand" "")))
3822    (clobber (match_operand 2 "" ""))]
3823   "reload_completed"
3824   [(set (match_dup 2) (match_dup 1))
3825    (set (match_dup 0) (match_dup 2))]
3826 {
3827   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3828 })
3829
3830 ;; Conversion from XFmode to SFmode.
3831
3832 (define_expand "truncxfsf2"
3833   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3834                    (float_truncate:SF
3835                     (match_operand:XF 1 "register_operand" "")))
3836               (clobber (match_dup 2))])]
3837   "TARGET_80387"
3838 {
3839   if (flag_unsafe_math_optimizations)
3840     {
3841       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3842       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3843       if (reg != operands[0])
3844         emit_move_insn (operands[0], reg);
3845       DONE;
3846     }
3847   else
3848     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3849 })
3850
3851 (define_insn "*truncxfsf2_mixed"
3852   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3853         (float_truncate:SF
3854          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3855    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3856   "TARGET_MIX_SSE_I387"
3857 {
3858   gcc_assert (!which_alternative);
3859   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3860     return "fstp%z0\t%y0";
3861   else
3862     return "fst%z0\t%y0";
3863 }
3864   [(set_attr "type" "fmov,multi,multi,multi")
3865    (set_attr "unit" "*,i387,i387,i387")
3866    (set_attr "mode" "SF")])
3867
3868 (define_insn "truncxfsf2_i387_noop"
3869   [(set (match_operand:SF 0 "register_operand" "=f")
3870         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3871   "TARGET_80387 && flag_unsafe_math_optimizations"
3872 {
3873   return output_387_reg_move (insn, operands);
3874 }
3875   [(set_attr "type" "fmov")
3876    (set_attr "mode" "SF")])
3877
3878 (define_insn "*truncxfsf2_i387"
3879   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3880         (float_truncate:SF
3881          (match_operand:XF 1 "register_operand" "f,f,f")))
3882    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3883   "TARGET_80387"
3884 {
3885   gcc_assert (!which_alternative);
3886   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3887     return "fstp%z0\t%y0";
3888    else
3889      return "fst%z0\t%y0";
3890 }
3891   [(set_attr "type" "fmov,multi,multi")
3892    (set_attr "unit" "*,i387,i387")
3893    (set_attr "mode" "SF")])
3894
3895 (define_insn "*truncxfsf2_i387_1"
3896   [(set (match_operand:SF 0 "memory_operand" "=m")
3897         (float_truncate:SF
3898          (match_operand:XF 1 "register_operand" "f")))]
3899   "TARGET_80387"
3900 {
3901   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3902     return "fstp%z0\t%y0";
3903   else
3904     return "fst%z0\t%y0";
3905 }
3906   [(set_attr "type" "fmov")
3907    (set_attr "mode" "SF")])
3908
3909 (define_split
3910   [(set (match_operand:SF 0 "register_operand" "")
3911         (float_truncate:SF
3912          (match_operand:XF 1 "register_operand" "")))
3913    (clobber (match_operand:SF 2 "memory_operand" ""))]
3914   "TARGET_80387 && reload_completed"
3915   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3916    (set (match_dup 0) (match_dup 2))]
3917   "")
3918
3919 (define_split
3920   [(set (match_operand:SF 0 "memory_operand" "")
3921         (float_truncate:SF
3922          (match_operand:XF 1 "register_operand" "")))
3923    (clobber (match_operand:SF 2 "memory_operand" ""))]
3924   "TARGET_80387"
3925   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3926   "")
3927
3928 ;; Conversion from XFmode to DFmode.
3929
3930 (define_expand "truncxfdf2"
3931   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3932                    (float_truncate:DF
3933                     (match_operand:XF 1 "register_operand" "")))
3934               (clobber (match_dup 2))])]
3935   "TARGET_80387"
3936 {
3937   if (flag_unsafe_math_optimizations)
3938     {
3939       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3940       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3941       if (reg != operands[0])
3942         emit_move_insn (operands[0], reg);
3943       DONE;
3944     }
3945   else
3946     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3947 })
3948
3949 (define_insn "*truncxfdf2_mixed"
3950   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3951         (float_truncate:DF
3952          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3953    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3954   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3955 {
3956   gcc_assert (!which_alternative);
3957   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3958     return "fstp%z0\t%y0";
3959   else
3960     return "fst%z0\t%y0";
3961 }
3962   [(set_attr "type" "fmov,multi,multi,multi")
3963    (set_attr "unit" "*,i387,i387,i387")
3964    (set_attr "mode" "DF")])
3965
3966 (define_insn "truncxfdf2_i387_noop"
3967   [(set (match_operand:DF 0 "register_operand" "=f")
3968         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3969   "TARGET_80387 && flag_unsafe_math_optimizations"
3970 {
3971   return output_387_reg_move (insn, operands);
3972 }
3973   [(set_attr "type" "fmov")
3974    (set_attr "mode" "DF")])
3975