OSDN Git Service

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