OSDN Git Service

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