OSDN Git Service

* config/i386/i386.md (define_peephole2): Revert last change.
[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 ;; "&& 1" is needed to keep it from matching the previous pattern.
1870 (define_peephole2
1871   [(set (match_operand:DI 0 "push_operand" "")
1872         (match_operand:DI 1 "immediate_operand" ""))]
1873   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1874    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1875   [(set (match_dup 0) (match_dup 1))
1876    (set (match_dup 2) (match_dup 3))]
1877   "split_di (operands + 1, 1, operands + 2, operands + 3);
1878    operands[1] = gen_lowpart (DImode, operands[2]);
1879    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1880                                                     GEN_INT (4)));
1881   ")
1882
1883 (define_split
1884   [(set (match_operand:DI 0 "push_operand" "")
1885         (match_operand:DI 1 "immediate_operand" ""))]
1886   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1887    && !symbolic_operand (operands[1], DImode)
1888    && !x86_64_immediate_operand (operands[1], DImode)"
1889   [(set (match_dup 0) (match_dup 1))
1890    (set (match_dup 2) (match_dup 3))]
1891   "split_di (operands + 1, 1, operands + 2, operands + 3);
1892    operands[1] = gen_lowpart (DImode, operands[2]);
1893    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1894                                                     GEN_INT (4)));
1895   ")
1896
1897 (define_insn "*pushdi2_prologue_rex64"
1898   [(set (match_operand:DI 0 "push_operand" "=<")
1899         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1900    (clobber (mem:BLK (scratch)))]
1901   "TARGET_64BIT"
1902   "push{q}\t%1"
1903   [(set_attr "type" "push")
1904    (set_attr "mode" "DI")])
1905
1906 (define_insn "*popdi1_epilogue_rex64"
1907   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1908         (mem:DI (reg:DI SP_REG)))
1909    (set (reg:DI SP_REG)
1910         (plus:DI (reg:DI SP_REG) (const_int 8)))
1911    (clobber (mem:BLK (scratch)))]
1912   "TARGET_64BIT"
1913   "pop{q}\t%0"
1914   [(set_attr "type" "pop")
1915    (set_attr "mode" "DI")])
1916
1917 (define_insn "popdi1"
1918   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1919         (mem:DI (reg:DI SP_REG)))
1920    (set (reg:DI SP_REG)
1921         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1922   "TARGET_64BIT"
1923   "pop{q}\t%0"
1924   [(set_attr "type" "pop")
1925    (set_attr "mode" "DI")])
1926
1927 (define_insn "*movdi_xor_rex64"
1928   [(set (match_operand:DI 0 "register_operand" "=r")
1929         (match_operand:DI 1 "const0_operand" "i"))
1930    (clobber (reg:CC FLAGS_REG))]
1931   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1932    && reload_completed"
1933   "xor{l}\t{%k0, %k0|%k0, %k0}"
1934   [(set_attr "type" "alu1")
1935    (set_attr "mode" "SI")
1936    (set_attr "length_immediate" "0")])
1937
1938 (define_insn "*movdi_or_rex64"
1939   [(set (match_operand:DI 0 "register_operand" "=r")
1940         (match_operand:DI 1 "const_int_operand" "i"))
1941    (clobber (reg:CC FLAGS_REG))]
1942   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1943    && reload_completed
1944    && operands[1] == constm1_rtx"
1945 {
1946   operands[1] = constm1_rtx;
1947   return "or{q}\t{%1, %0|%0, %1}";
1948 }
1949   [(set_attr "type" "alu1")
1950    (set_attr "mode" "DI")
1951    (set_attr "length_immediate" "1")])
1952
1953 (define_insn "*movdi_2"
1954   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1955         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1956   "!TARGET_64BIT
1957    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1958   "@
1959    #
1960    #
1961    movq\t{%1, %0|%0, %1}
1962    movq\t{%1, %0|%0, %1}
1963    movq\t{%1, %0|%0, %1}
1964    movdqa\t{%1, %0|%0, %1}
1965    movq\t{%1, %0|%0, %1}"
1966   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1967    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1968
1969 (define_split
1970   [(set (match_operand:DI 0 "push_operand" "")
1971         (match_operand:DI 1 "general_operand" ""))]
1972   "!TARGET_64BIT && reload_completed
1973    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1974   [(const_int 0)]
1975   "ix86_split_long_move (operands); DONE;")
1976
1977 ;; %%% This multiword shite has got to go.
1978 (define_split
1979   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1980         (match_operand:DI 1 "general_operand" ""))]
1981   "!TARGET_64BIT && reload_completed
1982    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1983    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1984   [(const_int 0)]
1985   "ix86_split_long_move (operands); DONE;")
1986
1987 (define_insn "*movdi_1_rex64"
1988   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1989         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1990   "TARGET_64BIT
1991    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1992    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1993 {
1994   switch (get_attr_type (insn))
1995     {
1996     case TYPE_SSECVT:
1997       if (which_alternative == 11)
1998         return "movq2dq\t{%1, %0|%0, %1}";
1999       else
2000         return "movdq2q\t{%1, %0|%0, %1}";
2001     case TYPE_SSEMOV:
2002       if (get_attr_mode (insn) == MODE_TI)
2003           return "movdqa\t{%1, %0|%0, %1}";
2004       /* FALLTHRU */
2005     case TYPE_MMXMOV:
2006       /* Moves from and into integer register is done using movd opcode with
2007          REX prefix.  */
2008       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2009           return "movd\t{%1, %0|%0, %1}";
2010       return "movq\t{%1, %0|%0, %1}";
2011     case TYPE_MULTI:
2012       return "#";
2013     case TYPE_LEA:
2014       return "lea{q}\t{%a1, %0|%0, %a1}";
2015     default:
2016       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2017         abort ();
2018       if (get_attr_mode (insn) == MODE_SI)
2019         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2020       else if (which_alternative == 2)
2021         return "movabs{q}\t{%1, %0|%0, %1}";
2022       else
2023         return "mov{q}\t{%1, %0|%0, %1}";
2024     }
2025 }
2026   [(set (attr "type")
2027      (cond [(eq_attr "alternative" "5,6,7")
2028               (const_string "mmxmov")
2029             (eq_attr "alternative" "8,9,10")
2030               (const_string "ssemov")
2031             (eq_attr "alternative" "11,12")
2032               (const_string "ssecvt")
2033             (eq_attr "alternative" "4")
2034               (const_string "multi")
2035             (and (ne (symbol_ref "flag_pic") (const_int 0))
2036                  (match_operand:DI 1 "symbolic_operand" ""))
2037               (const_string "lea")
2038            ]
2039            (const_string "imov")))
2040    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
2041    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2042    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
2043
2044 (define_insn "*movdi_1_rex64_nointerunit"
2045   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2046         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2047   "TARGET_64BIT
2048    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2049    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2050 {
2051   switch (get_attr_type (insn))
2052     {
2053     case TYPE_SSEMOV:
2054       if (get_attr_mode (insn) == MODE_TI)
2055           return "movdqa\t{%1, %0|%0, %1}";
2056       /* FALLTHRU */
2057     case TYPE_MMXMOV:
2058       return "movq\t{%1, %0|%0, %1}";
2059     case TYPE_MULTI:
2060       return "#";
2061     case TYPE_LEA:
2062       return "lea{q}\t{%a1, %0|%0, %a1}";
2063     default:
2064       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2065         abort ();
2066       if (get_attr_mode (insn) == MODE_SI)
2067         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2068       else if (which_alternative == 2)
2069         return "movabs{q}\t{%1, %0|%0, %1}";
2070       else
2071         return "mov{q}\t{%1, %0|%0, %1}";
2072     }
2073 }
2074   [(set (attr "type")
2075      (cond [(eq_attr "alternative" "5,6,7")
2076               (const_string "mmxmov")
2077             (eq_attr "alternative" "8,9,10")
2078               (const_string "ssemov")
2079             (eq_attr "alternative" "4")
2080               (const_string "multi")
2081             (and (ne (symbol_ref "flag_pic") (const_int 0))
2082                  (match_operand:DI 1 "symbolic_operand" ""))
2083               (const_string "lea")
2084            ]
2085            (const_string "imov")))
2086    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2087    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2088    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2089
2090 ;; Stores and loads of ax to arbitrary constant address.
2091 ;; We fake an second form of instruction to force reload to load address
2092 ;; into register when rax is not available
2093 (define_insn "*movabsdi_1_rex64"
2094   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2095         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2096   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2097   "@
2098    movabs{q}\t{%1, %P0|%P0, %1}
2099    mov{q}\t{%1, %a0|%a0, %1}"
2100   [(set_attr "type" "imov")
2101    (set_attr "modrm" "0,*")
2102    (set_attr "length_address" "8,0")
2103    (set_attr "length_immediate" "0,*")
2104    (set_attr "memory" "store")
2105    (set_attr "mode" "DI")])
2106
2107 (define_insn "*movabsdi_2_rex64"
2108   [(set (match_operand:DI 0 "register_operand" "=a,r")
2109         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2110   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2111   "@
2112    movabs{q}\t{%P1, %0|%0, %P1}
2113    mov{q}\t{%a1, %0|%0, %a1}"
2114   [(set_attr "type" "imov")
2115    (set_attr "modrm" "0,*")
2116    (set_attr "length_address" "8,0")
2117    (set_attr "length_immediate" "0")
2118    (set_attr "memory" "load")
2119    (set_attr "mode" "DI")])
2120
2121 ;; Convert impossible stores of immediate to existing instructions.
2122 ;; First try to get scratch register and go through it.  In case this
2123 ;; fails, move by 32bit parts.
2124 (define_peephole2
2125   [(match_scratch:DI 2 "r")
2126    (set (match_operand:DI 0 "memory_operand" "")
2127         (match_operand:DI 1 "immediate_operand" ""))]
2128   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2129    && !x86_64_immediate_operand (operands[1], DImode)"
2130   [(set (match_dup 2) (match_dup 1))
2131    (set (match_dup 0) (match_dup 2))]
2132   "")
2133
2134 ;; We need to define this as both peepholer and splitter for case
2135 ;; peephole2 pass is not run.
2136 ;; "&& 1" is needed to keep it from matching the previous pattern.
2137 (define_peephole2
2138   [(set (match_operand:DI 0 "memory_operand" "")
2139         (match_operand:DI 1 "immediate_operand" ""))]
2140   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2141    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2142   [(set (match_dup 2) (match_dup 3))
2143    (set (match_dup 4) (match_dup 5))]
2144   "split_di (operands, 2, operands + 2, operands + 4);")
2145
2146 (define_split
2147   [(set (match_operand:DI 0 "memory_operand" "")
2148         (match_operand:DI 1 "immediate_operand" ""))]
2149   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2150    && !symbolic_operand (operands[1], DImode)
2151    && !x86_64_immediate_operand (operands[1], DImode)"
2152   [(set (match_dup 2) (match_dup 3))
2153    (set (match_dup 4) (match_dup 5))]
2154   "split_di (operands, 2, operands + 2, operands + 4);")
2155
2156 (define_insn "*swapdi_rex64"
2157   [(set (match_operand:DI 0 "register_operand" "+r")
2158         (match_operand:DI 1 "register_operand" "+r"))
2159    (set (match_dup 1)
2160         (match_dup 0))]
2161   "TARGET_64BIT"
2162   "xchg{q}\t%1, %0"
2163   [(set_attr "type" "imov")
2164    (set_attr "pent_pair" "np")
2165    (set_attr "athlon_decode" "vector")
2166    (set_attr "mode" "DI")
2167    (set_attr "modrm" "0")])
2168
2169   
2170 (define_expand "movsf"
2171   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2172         (match_operand:SF 1 "general_operand" ""))]
2173   ""
2174   "ix86_expand_move (SFmode, operands); DONE;")
2175
2176 (define_insn "*pushsf"
2177   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2178         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2179   "!TARGET_64BIT"
2180 {
2181   switch (which_alternative)
2182     {
2183     case 1:
2184       return "push{l}\t%1";
2185
2186     default:
2187       /* This insn should be already split before reg-stack.  */
2188       abort ();
2189     }
2190 }
2191   [(set_attr "type" "multi,push,multi")
2192    (set_attr "mode" "SF,SI,SF")])
2193
2194 (define_insn "*pushsf_rex64"
2195   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2196         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2197   "TARGET_64BIT"
2198 {
2199   switch (which_alternative)
2200     {
2201     case 1:
2202       return "push{q}\t%q1";
2203
2204     default:
2205       /* This insn should be already split before reg-stack.  */
2206       abort ();
2207     }
2208 }
2209   [(set_attr "type" "multi,push,multi")
2210    (set_attr "mode" "SF,DI,SF")])
2211
2212 (define_split
2213   [(set (match_operand:SF 0 "push_operand" "")
2214         (match_operand:SF 1 "memory_operand" ""))]
2215   "reload_completed
2216    && GET_CODE (operands[1]) == MEM
2217    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2218    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2219   [(set (match_dup 0)
2220         (match_dup 1))]
2221   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2222
2223
2224 ;; %%% Kill this when call knows how to work this out.
2225 (define_split
2226   [(set (match_operand:SF 0 "push_operand" "")
2227         (match_operand:SF 1 "any_fp_register_operand" ""))]
2228   "!TARGET_64BIT"
2229   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2230    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2231
2232 (define_split
2233   [(set (match_operand:SF 0 "push_operand" "")
2234         (match_operand:SF 1 "any_fp_register_operand" ""))]
2235   "TARGET_64BIT"
2236   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2237    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2238
2239 (define_insn "*movsf_1"
2240   [(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")
2241         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2242   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2243    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2244    && (reload_in_progress || reload_completed
2245        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2246        || GET_CODE (operands[1]) != CONST_DOUBLE
2247        || memory_operand (operands[0], SFmode))" 
2248 {
2249   switch (which_alternative)
2250     {
2251     case 0:
2252       return output_387_reg_move (insn, operands);
2253
2254     case 1:
2255       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2256         return "fstp%z0\t%y0";
2257       else
2258         return "fst%z0\t%y0";
2259
2260     case 2:
2261       return standard_80387_constant_opcode (operands[1]);
2262
2263     case 3:
2264     case 4:
2265       return "mov{l}\t{%1, %0|%0, %1}";
2266     case 5:
2267       if (get_attr_mode (insn) == MODE_TI)
2268         return "pxor\t%0, %0";
2269       else
2270         return "xorps\t%0, %0";
2271     case 6:
2272       if (get_attr_mode (insn) == MODE_V4SF)
2273         return "movaps\t{%1, %0|%0, %1}";
2274       else
2275         return "movss\t{%1, %0|%0, %1}";
2276     case 7:
2277     case 8:
2278       return "movss\t{%1, %0|%0, %1}";
2279
2280     case 9:
2281     case 10:
2282       return "movd\t{%1, %0|%0, %1}";
2283
2284     case 11:
2285       return "movq\t{%1, %0|%0, %1}";
2286
2287     default:
2288       abort();
2289     }
2290 }
2291   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2292    (set (attr "mode")
2293         (cond [(eq_attr "alternative" "3,4,9,10")
2294                  (const_string "SI")
2295                (eq_attr "alternative" "5")
2296                  (if_then_else
2297                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2298                                  (const_int 0))
2299                              (ne (symbol_ref "TARGET_SSE2")
2300                                  (const_int 0)))
2301                         (eq (symbol_ref "optimize_size")
2302                             (const_int 0)))
2303                    (const_string "TI")
2304                    (const_string "V4SF"))
2305                /* For architectures resolving dependencies on
2306                   whole SSE registers use APS move to break dependency
2307                   chains, otherwise use short move to avoid extra work. 
2308
2309                   Do the same for architectures resolving dependencies on
2310                   the parts.  While in DF mode it is better to always handle
2311                   just register parts, the SF mode is different due to lack
2312                   of instructions to load just part of the register.  It is
2313                   better to maintain the whole registers in single format
2314                   to avoid problems on using packed logical operations.  */
2315                (eq_attr "alternative" "6")
2316                  (if_then_else
2317                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2318                             (const_int 0))
2319                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2320                             (const_int 0)))
2321                    (const_string "V4SF")
2322                    (const_string "SF"))
2323                (eq_attr "alternative" "11")
2324                  (const_string "DI")]
2325                (const_string "SF")))])
2326
2327 (define_insn "*movsf_1_nointerunit"
2328   [(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")
2329         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2330   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2331    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2332    && (reload_in_progress || reload_completed
2333        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2334        || GET_CODE (operands[1]) != CONST_DOUBLE
2335        || memory_operand (operands[0], SFmode))" 
2336 {
2337   switch (which_alternative)
2338     {
2339     case 0:
2340       return output_387_reg_move (insn, operands);
2341
2342     case 1:
2343       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2344         return "fstp%z0\t%y0";
2345       else
2346         return "fst%z0\t%y0";
2347
2348     case 2:
2349       return standard_80387_constant_opcode (operands[1]);
2350
2351     case 3:
2352     case 4:
2353       return "mov{l}\t{%1, %0|%0, %1}";
2354     case 5:
2355       if (get_attr_mode (insn) == MODE_TI)
2356         return "pxor\t%0, %0";
2357       else
2358         return "xorps\t%0, %0";
2359     case 6:
2360       if (get_attr_mode (insn) == MODE_V4SF)
2361         return "movaps\t{%1, %0|%0, %1}";
2362       else
2363         return "movss\t{%1, %0|%0, %1}";
2364     case 7:
2365     case 8:
2366       return "movss\t{%1, %0|%0, %1}";
2367
2368     case 9:
2369     case 10:
2370       return "movd\t{%1, %0|%0, %1}";
2371
2372     case 11:
2373       return "movq\t{%1, %0|%0, %1}";
2374
2375     default:
2376       abort();
2377     }
2378 }
2379   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2380    (set (attr "mode")
2381         (cond [(eq_attr "alternative" "3,4,9,10")
2382                  (const_string "SI")
2383                (eq_attr "alternative" "5")
2384                  (if_then_else
2385                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2386                                  (const_int 0))
2387                              (ne (symbol_ref "TARGET_SSE2")
2388                                  (const_int 0)))
2389                         (eq (symbol_ref "optimize_size")
2390                             (const_int 0)))
2391                    (const_string "TI")
2392                    (const_string "V4SF"))
2393                /* For architectures resolving dependencies on
2394                   whole SSE registers use APS move to break dependency
2395                   chains, otherwise use short move to avoid extra work. 
2396
2397                   Do the same for architectures resolving dependencies on
2398                   the parts.  While in DF mode it is better to always handle
2399                   just register parts, the SF mode is different due to lack
2400                   of instructions to load just part of the register.  It is
2401                   better to maintain the whole registers in single format
2402                   to avoid problems on using packed logical operations.  */
2403                (eq_attr "alternative" "6")
2404                  (if_then_else
2405                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2406                             (const_int 0))
2407                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2408                             (const_int 0)))
2409                    (const_string "V4SF")
2410                    (const_string "SF"))
2411                (eq_attr "alternative" "11")
2412                  (const_string "DI")]
2413                (const_string "SF")))])
2414
2415 (define_insn "*swapsf"
2416   [(set (match_operand:SF 0 "register_operand" "+f")
2417         (match_operand:SF 1 "register_operand" "+f"))
2418    (set (match_dup 1)
2419         (match_dup 0))]
2420   "reload_completed || !TARGET_SSE"
2421 {
2422   if (STACK_TOP_P (operands[0]))
2423     return "fxch\t%1";
2424   else
2425     return "fxch\t%0";
2426 }
2427   [(set_attr "type" "fxch")
2428    (set_attr "mode" "SF")])
2429
2430 (define_expand "movdf"
2431   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2432         (match_operand:DF 1 "general_operand" ""))]
2433   ""
2434   "ix86_expand_move (DFmode, operands); DONE;")
2435
2436 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2437 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2438 ;; On the average, pushdf using integers can be still shorter.  Allow this
2439 ;; pattern for optimize_size too.
2440
2441 (define_insn "*pushdf_nointeger"
2442   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2443         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2444   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2445 {
2446   /* This insn should be already split before reg-stack.  */
2447   abort ();
2448 }
2449   [(set_attr "type" "multi")
2450    (set_attr "mode" "DF,SI,SI,DF")])
2451
2452 (define_insn "*pushdf_integer"
2453   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2454         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2455   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2456 {
2457   /* This insn should be already split before reg-stack.  */
2458   abort ();
2459 }
2460   [(set_attr "type" "multi")
2461    (set_attr "mode" "DF,SI,DF")])
2462
2463 ;; %%% Kill this when call knows how to work this out.
2464 (define_split
2465   [(set (match_operand:DF 0 "push_operand" "")
2466         (match_operand:DF 1 "any_fp_register_operand" ""))]
2467   "!TARGET_64BIT && reload_completed"
2468   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2469    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2470   "")
2471
2472 (define_split
2473   [(set (match_operand:DF 0 "push_operand" "")
2474         (match_operand:DF 1 "any_fp_register_operand" ""))]
2475   "TARGET_64BIT && reload_completed"
2476   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2477    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2478   "")
2479
2480 (define_split
2481   [(set (match_operand:DF 0 "push_operand" "")
2482         (match_operand:DF 1 "general_operand" ""))]
2483   "reload_completed"
2484   [(const_int 0)]
2485   "ix86_split_long_move (operands); DONE;")
2486
2487 ;; Moving is usually shorter when only FP registers are used. This separate
2488 ;; movdf pattern avoids the use of integer registers for FP operations
2489 ;; when optimizing for size.
2490
2491 (define_insn "*movdf_nointeger"
2492   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2493         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2494   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2495    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2496    && (reload_in_progress || reload_completed
2497        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2498        || GET_CODE (operands[1]) != CONST_DOUBLE
2499        || memory_operand (operands[0], DFmode))" 
2500 {
2501   switch (which_alternative)
2502     {
2503     case 0:
2504       return output_387_reg_move (insn, operands);
2505
2506     case 1:
2507       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2508         return "fstp%z0\t%y0";
2509       else
2510         return "fst%z0\t%y0";
2511
2512     case 2:
2513       return standard_80387_constant_opcode (operands[1]);
2514
2515     case 3:
2516     case 4:
2517       return "#";
2518     case 5:
2519       switch (get_attr_mode (insn))
2520         {
2521         case MODE_V4SF:
2522           return "xorps\t%0, %0";
2523         case MODE_V2DF:
2524           return "xorpd\t%0, %0";
2525         case MODE_TI:
2526           return "pxor\t%0, %0";
2527         default:
2528           abort ();
2529         }
2530     case 6:
2531       switch (get_attr_mode (insn))
2532         {
2533         case MODE_V4SF:
2534           return "movaps\t{%1, %0|%0, %1}";
2535         case MODE_V2DF:
2536           return "movapd\t{%1, %0|%0, %1}";
2537         case MODE_DF:
2538           return "movsd\t{%1, %0|%0, %1}";
2539         default:
2540           abort ();
2541         }
2542     case 7:
2543       if (get_attr_mode (insn) == MODE_V2DF)
2544         return "movlpd\t{%1, %0|%0, %1}";
2545       else
2546         return "movsd\t{%1, %0|%0, %1}";
2547     case 8:
2548       return "movsd\t{%1, %0|%0, %1}";
2549
2550     default:
2551       abort();
2552     }
2553 }
2554   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2555    (set (attr "mode")
2556         (cond [(eq_attr "alternative" "3,4")
2557                  (const_string "SI")
2558                /* xorps is one byte shorter.  */
2559                (eq_attr "alternative" "5")
2560                  (cond [(ne (symbol_ref "optimize_size")
2561                             (const_int 0))
2562                           (const_string "V4SF")
2563                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2564                             (const_int 0))
2565                           (const_string "TI")]
2566                        (const_string "V2DF"))
2567                /* For architectures resolving dependencies on
2568                   whole SSE registers use APD move to break dependency
2569                   chains, otherwise use short move to avoid extra work.
2570
2571                   movaps encodes one byte shorter.  */
2572                (eq_attr "alternative" "6")
2573                  (cond
2574                   [(ne (symbol_ref "optimize_size")
2575                        (const_int 0))
2576                      (const_string "V4SF")
2577                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2578                        (const_int 0))
2579                      (const_string "V2DF")]
2580                    (const_string "DF"))
2581                /* For architectures resolving dependencies on register
2582                   parts we may avoid extra work to zero out upper part
2583                   of register.  */
2584                (eq_attr "alternative" "7")
2585                  (if_then_else
2586                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2587                        (const_int 0))
2588                    (const_string "V2DF")
2589                    (const_string "DF"))]
2590                (const_string "DF")))])
2591
2592 (define_insn "*movdf_integer"
2593   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2594         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2595   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2596    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2597    && (reload_in_progress || reload_completed
2598        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2599        || GET_CODE (operands[1]) != CONST_DOUBLE
2600        || memory_operand (operands[0], DFmode))" 
2601 {
2602   switch (which_alternative)
2603     {
2604     case 0:
2605       return output_387_reg_move (insn, operands);
2606
2607     case 1:
2608       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2609         return "fstp%z0\t%y0";
2610       else
2611         return "fst%z0\t%y0";
2612
2613     case 2:
2614       return standard_80387_constant_opcode (operands[1]);
2615
2616     case 3:
2617     case 4:
2618       return "#";
2619
2620     case 5:
2621       switch (get_attr_mode (insn))
2622         {
2623         case MODE_V4SF:
2624           return "xorps\t%0, %0";
2625         case MODE_V2DF:
2626           return "xorpd\t%0, %0";
2627         case MODE_TI:
2628           return "pxor\t%0, %0";
2629         default:
2630           abort ();
2631         }
2632     case 6:
2633       switch (get_attr_mode (insn))
2634         {
2635         case MODE_V4SF:
2636           return "movaps\t{%1, %0|%0, %1}";
2637         case MODE_V2DF:
2638           return "movapd\t{%1, %0|%0, %1}";
2639         case MODE_DF:
2640           return "movsd\t{%1, %0|%0, %1}";
2641         default:
2642           abort ();
2643         }
2644     case 7:
2645       if (get_attr_mode (insn) == MODE_V2DF)
2646         return "movlpd\t{%1, %0|%0, %1}";
2647       else
2648         return "movsd\t{%1, %0|%0, %1}";
2649     case 8:
2650       return "movsd\t{%1, %0|%0, %1}";
2651
2652     default:
2653       abort();
2654     }
2655 }
2656   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2657    (set (attr "mode")
2658         (cond [(eq_attr "alternative" "3,4")
2659                  (const_string "SI")
2660                /* xorps is one byte shorter.  */
2661                (eq_attr "alternative" "5")
2662                  (cond [(ne (symbol_ref "optimize_size")
2663                             (const_int 0))
2664                           (const_string "V4SF")
2665                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2666                             (const_int 0))
2667                           (const_string "TI")]
2668                        (const_string "V2DF"))
2669                /* For architectures resolving dependencies on
2670                   whole SSE registers use APD move to break dependency
2671                   chains, otherwise use short move to avoid extra work.  
2672
2673                   movaps encodes one byte shorter.  */
2674                (eq_attr "alternative" "6")
2675                  (cond
2676                   [(ne (symbol_ref "optimize_size")
2677                        (const_int 0))
2678                      (const_string "V4SF")
2679                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2680                        (const_int 0))
2681                      (const_string "V2DF")]
2682                    (const_string "DF"))
2683                /* For architectures resolving dependencies on register
2684                   parts we may avoid extra work to zero out upper part
2685                   of register.  */
2686                (eq_attr "alternative" "7")
2687                  (if_then_else
2688                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2689                        (const_int 0))
2690                    (const_string "V2DF")
2691                    (const_string "DF"))]
2692                (const_string "DF")))])
2693
2694 (define_split
2695   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2696         (match_operand:DF 1 "general_operand" ""))]
2697   "reload_completed
2698    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2699    && ! (ANY_FP_REG_P (operands[0]) || 
2700          (GET_CODE (operands[0]) == SUBREG
2701           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2702    && ! (ANY_FP_REG_P (operands[1]) || 
2703          (GET_CODE (operands[1]) == SUBREG
2704           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2705   [(const_int 0)]
2706   "ix86_split_long_move (operands); DONE;")
2707
2708 (define_insn "*swapdf"
2709   [(set (match_operand:DF 0 "register_operand" "+f")
2710         (match_operand:DF 1 "register_operand" "+f"))
2711    (set (match_dup 1)
2712         (match_dup 0))]
2713   "reload_completed || !TARGET_SSE2"
2714 {
2715   if (STACK_TOP_P (operands[0]))
2716     return "fxch\t%1";
2717   else
2718     return "fxch\t%0";
2719 }
2720   [(set_attr "type" "fxch")
2721    (set_attr "mode" "DF")])
2722
2723 (define_expand "movxf"
2724   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2725         (match_operand:XF 1 "general_operand" ""))]
2726   ""
2727   "ix86_expand_move (XFmode, operands); DONE;")
2728
2729 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2730 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2731 ;; Pushing using integer instructions is longer except for constants
2732 ;; and direct memory references.
2733 ;; (assuming that any given constant is pushed only once, but this ought to be
2734 ;;  handled elsewhere).
2735
2736 (define_insn "*pushxf_nointeger"
2737   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2738         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2739   "optimize_size"
2740 {
2741   /* This insn should be already split before reg-stack.  */
2742   abort ();
2743 }
2744   [(set_attr "type" "multi")
2745    (set_attr "mode" "XF,SI,SI")])
2746
2747 (define_insn "*pushxf_integer"
2748   [(set (match_operand:XF 0 "push_operand" "=<,<")
2749         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2750   "!optimize_size"
2751 {
2752   /* This insn should be already split before reg-stack.  */
2753   abort ();
2754 }
2755   [(set_attr "type" "multi")
2756    (set_attr "mode" "XF,SI")])
2757
2758 (define_split
2759   [(set (match_operand 0 "push_operand" "")
2760         (match_operand 1 "general_operand" ""))]
2761   "reload_completed
2762    && (GET_MODE (operands[0]) == XFmode
2763        || GET_MODE (operands[0]) == DFmode)
2764    && !ANY_FP_REG_P (operands[1])"
2765   [(const_int 0)]
2766   "ix86_split_long_move (operands); DONE;")
2767
2768 (define_split
2769   [(set (match_operand:XF 0 "push_operand" "")
2770         (match_operand:XF 1 "any_fp_register_operand" ""))]
2771   "!TARGET_64BIT"
2772   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2773    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2774   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2775
2776 (define_split
2777   [(set (match_operand:XF 0 "push_operand" "")
2778         (match_operand:XF 1 "any_fp_register_operand" ""))]
2779   "TARGET_64BIT"
2780   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2781    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2782   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2783
2784 ;; Do not use integer registers when optimizing for size
2785 (define_insn "*movxf_nointeger"
2786   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2787         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2788   "optimize_size
2789    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2790    && (reload_in_progress || reload_completed
2791        || GET_CODE (operands[1]) != CONST_DOUBLE
2792        || memory_operand (operands[0], XFmode))" 
2793 {
2794   switch (which_alternative)
2795     {
2796     case 0:
2797       return output_387_reg_move (insn, operands);
2798
2799     case 1:
2800       /* There is no non-popping store to memory for XFmode.  So if
2801          we need one, follow the store with a load.  */
2802       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2803         return "fstp%z0\t%y0\;fld%z0\t%y0";
2804       else
2805         return "fstp%z0\t%y0";
2806
2807     case 2:
2808       return standard_80387_constant_opcode (operands[1]);
2809
2810     case 3: case 4:
2811       return "#";
2812     }
2813   abort();
2814 }
2815   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2816    (set_attr "mode" "XF,XF,XF,SI,SI")])
2817
2818 (define_insn "*movxf_integer"
2819   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2820         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2821   "!optimize_size
2822    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2823    && (reload_in_progress || reload_completed
2824        || GET_CODE (operands[1]) != CONST_DOUBLE
2825        || memory_operand (operands[0], XFmode))" 
2826 {
2827   switch (which_alternative)
2828     {
2829     case 0:
2830       return output_387_reg_move (insn, operands);
2831
2832     case 1:
2833       /* There is no non-popping store to memory for XFmode.  So if
2834          we need one, follow the store with a load.  */
2835       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2836         return "fstp%z0\t%y0\;fld%z0\t%y0";
2837       else
2838         return "fstp%z0\t%y0";
2839
2840     case 2:
2841       return standard_80387_constant_opcode (operands[1]);
2842
2843     case 3: case 4:
2844       return "#";
2845     }
2846   abort();
2847 }
2848   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2849    (set_attr "mode" "XF,XF,XF,SI,SI")])
2850
2851 (define_split
2852   [(set (match_operand 0 "nonimmediate_operand" "")
2853         (match_operand 1 "general_operand" ""))]
2854   "reload_completed
2855    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2856    && GET_MODE (operands[0]) == XFmode
2857    && ! (ANY_FP_REG_P (operands[0]) || 
2858          (GET_CODE (operands[0]) == SUBREG
2859           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2860    && ! (ANY_FP_REG_P (operands[1]) || 
2861          (GET_CODE (operands[1]) == SUBREG
2862           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2863   [(const_int 0)]
2864   "ix86_split_long_move (operands); DONE;")
2865
2866 (define_split
2867   [(set (match_operand 0 "register_operand" "")
2868         (match_operand 1 "memory_operand" ""))]
2869   "reload_completed
2870    && GET_CODE (operands[1]) == MEM
2871    && (GET_MODE (operands[0]) == XFmode
2872        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2873    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2874    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2875   [(set (match_dup 0) (match_dup 1))]
2876 {
2877   rtx c = get_pool_constant (XEXP (operands[1], 0));
2878   rtx r = operands[0];
2879
2880   if (GET_CODE (r) == SUBREG)
2881     r = SUBREG_REG (r);
2882
2883   if (SSE_REG_P (r))
2884     {
2885       if (!standard_sse_constant_p (c))
2886         FAIL;
2887     }
2888   else if (FP_REG_P (r))
2889     {
2890       if (!standard_80387_constant_p (c))
2891         FAIL;
2892     }
2893   else if (MMX_REG_P (r))
2894     FAIL;
2895
2896   operands[1] = c;
2897 })
2898
2899 (define_insn "swapxf"
2900   [(set (match_operand:XF 0 "register_operand" "+f")
2901         (match_operand:XF 1 "register_operand" "+f"))
2902    (set (match_dup 1)
2903         (match_dup 0))]
2904   ""
2905 {
2906   if (STACK_TOP_P (operands[0]))
2907     return "fxch\t%1";
2908   else
2909     return "fxch\t%0";
2910 }
2911   [(set_attr "type" "fxch")
2912    (set_attr "mode" "XF")])
2913 \f
2914 ;; Zero extension instructions
2915
2916 (define_expand "zero_extendhisi2"
2917   [(set (match_operand:SI 0 "register_operand" "")
2918      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2919   ""
2920 {
2921   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2922     {
2923       operands[1] = force_reg (HImode, operands[1]);
2924       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2925       DONE;
2926     }
2927 })
2928
2929 (define_insn "zero_extendhisi2_and"
2930   [(set (match_operand:SI 0 "register_operand" "=r")
2931      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2932    (clobber (reg:CC FLAGS_REG))]
2933   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2934   "#"
2935   [(set_attr "type" "alu1")
2936    (set_attr "mode" "SI")])
2937
2938 (define_split
2939   [(set (match_operand:SI 0 "register_operand" "")
2940         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2941    (clobber (reg:CC FLAGS_REG))]
2942   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2943   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2944               (clobber (reg:CC FLAGS_REG))])]
2945   "")
2946
2947 (define_insn "*zero_extendhisi2_movzwl"
2948   [(set (match_operand:SI 0 "register_operand" "=r")
2949      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2950   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2951   "movz{wl|x}\t{%1, %0|%0, %1}"
2952   [(set_attr "type" "imovx")
2953    (set_attr "mode" "SI")])
2954
2955 (define_expand "zero_extendqihi2"
2956   [(parallel
2957     [(set (match_operand:HI 0 "register_operand" "")
2958        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2959      (clobber (reg:CC FLAGS_REG))])]
2960   ""
2961   "")
2962
2963 (define_insn "*zero_extendqihi2_and"
2964   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2965      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2966    (clobber (reg:CC FLAGS_REG))]
2967   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2968   "#"
2969   [(set_attr "type" "alu1")
2970    (set_attr "mode" "HI")])
2971
2972 (define_insn "*zero_extendqihi2_movzbw_and"
2973   [(set (match_operand:HI 0 "register_operand" "=r,r")
2974      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2975    (clobber (reg:CC FLAGS_REG))]
2976   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2977   "#"
2978   [(set_attr "type" "imovx,alu1")
2979    (set_attr "mode" "HI")])
2980
2981 (define_insn "*zero_extendqihi2_movzbw"
2982   [(set (match_operand:HI 0 "register_operand" "=r")
2983      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2984   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2985   "movz{bw|x}\t{%1, %0|%0, %1}"
2986   [(set_attr "type" "imovx")
2987    (set_attr "mode" "HI")])
2988
2989 ;; For the movzbw case strip only the clobber
2990 (define_split
2991   [(set (match_operand:HI 0 "register_operand" "")
2992         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2993    (clobber (reg:CC FLAGS_REG))]
2994   "reload_completed 
2995    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2996    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2997   [(set (match_operand:HI 0 "register_operand" "")
2998         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2999
3000 ;; When source and destination does not overlap, clear destination
3001 ;; first and then do the movb
3002 (define_split
3003   [(set (match_operand:HI 0 "register_operand" "")
3004         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3005    (clobber (reg:CC FLAGS_REG))]
3006   "reload_completed
3007    && ANY_QI_REG_P (operands[0])
3008    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3009    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3010   [(set (match_dup 0) (const_int 0))
3011    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3012   "operands[2] = gen_lowpart (QImode, operands[0]);")
3013
3014 ;; Rest is handled by single and.
3015 (define_split
3016   [(set (match_operand:HI 0 "register_operand" "")
3017         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3018    (clobber (reg:CC FLAGS_REG))]
3019   "reload_completed
3020    && true_regnum (operands[0]) == true_regnum (operands[1])"
3021   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3022               (clobber (reg:CC FLAGS_REG))])]
3023   "")
3024
3025 (define_expand "zero_extendqisi2"
3026   [(parallel
3027     [(set (match_operand:SI 0 "register_operand" "")
3028        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3029      (clobber (reg:CC FLAGS_REG))])]
3030   ""
3031   "")
3032
3033 (define_insn "*zero_extendqisi2_and"
3034   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3035      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3036    (clobber (reg:CC FLAGS_REG))]
3037   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3038   "#"
3039   [(set_attr "type" "alu1")
3040    (set_attr "mode" "SI")])
3041
3042 (define_insn "*zero_extendqisi2_movzbw_and"
3043   [(set (match_operand:SI 0 "register_operand" "=r,r")
3044      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3045    (clobber (reg:CC FLAGS_REG))]
3046   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3047   "#"
3048   [(set_attr "type" "imovx,alu1")
3049    (set_attr "mode" "SI")])
3050
3051 (define_insn "*zero_extendqisi2_movzbw"
3052   [(set (match_operand:SI 0 "register_operand" "=r")
3053      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3054   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3055   "movz{bl|x}\t{%1, %0|%0, %1}"
3056   [(set_attr "type" "imovx")
3057    (set_attr "mode" "SI")])
3058
3059 ;; For the movzbl case strip only the clobber
3060 (define_split
3061   [(set (match_operand:SI 0 "register_operand" "")
3062         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3063    (clobber (reg:CC FLAGS_REG))]
3064   "reload_completed 
3065    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3066    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3067   [(set (match_dup 0)
3068         (zero_extend:SI (match_dup 1)))])
3069
3070 ;; When source and destination does not overlap, clear destination
3071 ;; first and then do the movb
3072 (define_split
3073   [(set (match_operand:SI 0 "register_operand" "")
3074         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3075    (clobber (reg:CC FLAGS_REG))]
3076   "reload_completed
3077    && ANY_QI_REG_P (operands[0])
3078    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3079    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3080    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3081   [(set (match_dup 0) (const_int 0))
3082    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3083   "operands[2] = gen_lowpart (QImode, operands[0]);")
3084
3085 ;; Rest is handled by single and.
3086 (define_split
3087   [(set (match_operand:SI 0 "register_operand" "")
3088         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3089    (clobber (reg:CC FLAGS_REG))]
3090   "reload_completed
3091    && true_regnum (operands[0]) == true_regnum (operands[1])"
3092   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3093               (clobber (reg:CC FLAGS_REG))])]
3094   "")
3095
3096 ;; %%% Kill me once multi-word ops are sane.
3097 (define_expand "zero_extendsidi2"
3098   [(set (match_operand:DI 0 "register_operand" "=r")
3099      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3100   ""
3101   "if (!TARGET_64BIT)
3102      {
3103        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3104        DONE;
3105      }
3106   ")
3107
3108 (define_insn "zero_extendsidi2_32"
3109   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3110         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3111    (clobber (reg:CC FLAGS_REG))]
3112   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3113   "@
3114    #
3115    #
3116    #
3117    movd\t{%1, %0|%0, %1}
3118    movd\t{%1, %0|%0, %1}"
3119   [(set_attr "mode" "SI,SI,SI,DI,TI")
3120    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3121
3122 (define_insn "*zero_extendsidi2_32_1"
3123   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3124         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3125    (clobber (reg:CC FLAGS_REG))]
3126   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3127   "@
3128    #
3129    #
3130    #
3131    movd\t{%1, %0|%0, %1}
3132    movd\t{%1, %0|%0, %1}"
3133   [(set_attr "mode" "SI,SI,SI,DI,TI")
3134    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3135
3136 (define_insn "zero_extendsidi2_rex64"
3137   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3138      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3139   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3140   "@
3141    mov\t{%k1, %k0|%k0, %k1}
3142    #
3143    movd\t{%1, %0|%0, %1}
3144    movd\t{%1, %0|%0, %1}"
3145   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3146    (set_attr "mode" "SI,DI,DI,TI")])
3147
3148 (define_insn "*zero_extendsidi2_rex64_1"
3149   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3150      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3151   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3152   "@
3153    mov\t{%k1, %k0|%k0, %k1}
3154    #
3155    movd\t{%1, %0|%0, %1}
3156    movd\t{%1, %0|%0, %1}"
3157   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3158    (set_attr "mode" "SI,DI,SI,SI")])
3159
3160 (define_split
3161   [(set (match_operand:DI 0 "memory_operand" "")
3162      (zero_extend:DI (match_dup 0)))]
3163   "TARGET_64BIT"
3164   [(set (match_dup 4) (const_int 0))]
3165   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3166
3167 (define_split 
3168   [(set (match_operand:DI 0 "register_operand" "")
3169         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3170    (clobber (reg:CC FLAGS_REG))]
3171   "!TARGET_64BIT && reload_completed
3172    && true_regnum (operands[0]) == true_regnum (operands[1])"
3173   [(set (match_dup 4) (const_int 0))]
3174   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3175
3176 (define_split 
3177   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3178         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3179    (clobber (reg:CC FLAGS_REG))]
3180   "!TARGET_64BIT && reload_completed
3181    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3182   [(set (match_dup 3) (match_dup 1))
3183    (set (match_dup 4) (const_int 0))]
3184   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3185
3186 (define_insn "zero_extendhidi2"
3187   [(set (match_operand:DI 0 "register_operand" "=r,r")
3188      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3189   "TARGET_64BIT"
3190   "@
3191    movz{wl|x}\t{%1, %k0|%k0, %1}
3192    movz{wq|x}\t{%1, %0|%0, %1}"
3193   [(set_attr "type" "imovx")
3194    (set_attr "mode" "SI,DI")])
3195
3196 (define_insn "zero_extendqidi2"
3197   [(set (match_operand:DI 0 "register_operand" "=r,r")
3198      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3199   "TARGET_64BIT"
3200   "@
3201    movz{bl|x}\t{%1, %k0|%k0, %1}
3202    movz{bq|x}\t{%1, %0|%0, %1}"
3203   [(set_attr "type" "imovx")
3204    (set_attr "mode" "SI,DI")])
3205 \f
3206 ;; Sign extension instructions
3207
3208 (define_expand "extendsidi2"
3209   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3210                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3211               (clobber (reg:CC FLAGS_REG))
3212               (clobber (match_scratch:SI 2 ""))])]
3213   ""
3214 {
3215   if (TARGET_64BIT)
3216     {
3217       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3218       DONE;
3219     }
3220 })
3221
3222 (define_insn "*extendsidi2_1"
3223   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3224         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3225    (clobber (reg:CC FLAGS_REG))
3226    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3227   "!TARGET_64BIT"
3228   "#")
3229
3230 (define_insn "extendsidi2_rex64"
3231   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3232         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3233   "TARGET_64BIT"
3234   "@
3235    {cltq|cdqe}
3236    movs{lq|x}\t{%1,%0|%0, %1}"
3237   [(set_attr "type" "imovx")
3238    (set_attr "mode" "DI")
3239    (set_attr "prefix_0f" "0")
3240    (set_attr "modrm" "0,1")])
3241
3242 (define_insn "extendhidi2"
3243   [(set (match_operand:DI 0 "register_operand" "=r")
3244         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3245   "TARGET_64BIT"
3246   "movs{wq|x}\t{%1,%0|%0, %1}"
3247   [(set_attr "type" "imovx")
3248    (set_attr "mode" "DI")])
3249
3250 (define_insn "extendqidi2"
3251   [(set (match_operand:DI 0 "register_operand" "=r")
3252         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3253   "TARGET_64BIT"
3254   "movs{bq|x}\t{%1,%0|%0, %1}"
3255    [(set_attr "type" "imovx")
3256     (set_attr "mode" "DI")])
3257
3258 ;; Extend to memory case when source register does die.
3259 (define_split 
3260   [(set (match_operand:DI 0 "memory_operand" "")
3261         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3262    (clobber (reg:CC FLAGS_REG))
3263    (clobber (match_operand:SI 2 "register_operand" ""))]
3264   "(reload_completed
3265     && dead_or_set_p (insn, operands[1])
3266     && !reg_mentioned_p (operands[1], operands[0]))"
3267   [(set (match_dup 3) (match_dup 1))
3268    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3269               (clobber (reg:CC FLAGS_REG))])
3270    (set (match_dup 4) (match_dup 1))]
3271   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3272
3273 ;; Extend to memory case when source register does not die.
3274 (define_split 
3275   [(set (match_operand:DI 0 "memory_operand" "")
3276         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3277    (clobber (reg:CC FLAGS_REG))
3278    (clobber (match_operand:SI 2 "register_operand" ""))]
3279   "reload_completed"
3280   [(const_int 0)]
3281 {
3282   split_di (&operands[0], 1, &operands[3], &operands[4]);
3283
3284   emit_move_insn (operands[3], operands[1]);
3285
3286   /* Generate a cltd if possible and doing so it profitable.  */
3287   if (true_regnum (operands[1]) == 0
3288       && true_regnum (operands[2]) == 1
3289       && (optimize_size || TARGET_USE_CLTD))
3290     {
3291       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3292     }
3293   else
3294     {
3295       emit_move_insn (operands[2], operands[1]);
3296       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3297     }
3298   emit_move_insn (operands[4], operands[2]);
3299   DONE;
3300 })
3301
3302 ;; Extend to register case.  Optimize case where source and destination
3303 ;; registers match and cases where we can use cltd.
3304 (define_split 
3305   [(set (match_operand:DI 0 "register_operand" "")
3306         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3307    (clobber (reg:CC FLAGS_REG))
3308    (clobber (match_scratch:SI 2 ""))]
3309   "reload_completed"
3310   [(const_int 0)]
3311 {
3312   split_di (&operands[0], 1, &operands[3], &operands[4]);
3313
3314   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3315     emit_move_insn (operands[3], operands[1]);
3316
3317   /* Generate a cltd if possible and doing so it profitable.  */
3318   if (true_regnum (operands[3]) == 0
3319       && (optimize_size || TARGET_USE_CLTD))
3320     {
3321       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3322       DONE;
3323     }
3324
3325   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3326     emit_move_insn (operands[4], operands[1]);
3327
3328   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3329   DONE;
3330 })
3331
3332 (define_insn "extendhisi2"
3333   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3334         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3335   ""
3336 {
3337   switch (get_attr_prefix_0f (insn))
3338     {
3339     case 0:
3340       return "{cwtl|cwde}";
3341     default:
3342       return "movs{wl|x}\t{%1,%0|%0, %1}";
3343     }
3344 }
3345   [(set_attr "type" "imovx")
3346    (set_attr "mode" "SI")
3347    (set (attr "prefix_0f")
3348      ;; movsx is short decodable while cwtl is vector decoded.
3349      (if_then_else (and (eq_attr "cpu" "!k6")
3350                         (eq_attr "alternative" "0"))
3351         (const_string "0")
3352         (const_string "1")))
3353    (set (attr "modrm")
3354      (if_then_else (eq_attr "prefix_0f" "0")
3355         (const_string "0")
3356         (const_string "1")))])
3357
3358 (define_insn "*extendhisi2_zext"
3359   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3360         (zero_extend:DI
3361           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3362   "TARGET_64BIT"
3363 {
3364   switch (get_attr_prefix_0f (insn))
3365     {
3366     case 0:
3367       return "{cwtl|cwde}";
3368     default:
3369       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3370     }
3371 }
3372   [(set_attr "type" "imovx")
3373    (set_attr "mode" "SI")
3374    (set (attr "prefix_0f")
3375      ;; movsx is short decodable while cwtl is vector decoded.
3376      (if_then_else (and (eq_attr "cpu" "!k6")
3377                         (eq_attr "alternative" "0"))
3378         (const_string "0")
3379         (const_string "1")))
3380    (set (attr "modrm")
3381      (if_then_else (eq_attr "prefix_0f" "0")
3382         (const_string "0")
3383         (const_string "1")))])
3384
3385 (define_insn "extendqihi2"
3386   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3387         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3388   ""