OSDN Git Service

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